Hi Ed. Lets take this again, when you are near the end. I don't these tests applies to the end result? Best troels 2014-06-10 15:05 GMT+02:00 Edward d'Auvergne <edward@xxxxxxxxxxxxx>:
Removing the pA_arr and kex_arr structures will make this even faster: $ python -m timeit -n 100000 'import numpy as np; X = np.ones(100, np.float64); pA = 0.9; pA*X' 100000 loops, best of 3: 6.39 usec per loop $ python -m timeit -n 100000 'import numpy as np; X = np.ones(100, np.float64); pA = 0.9; pA_arr = np.array([pA]*100, np.float64); pA*X' 100000 loops, best of 3: 14.2 usec per loop $ python -m timeit -n 100000 'import numpy as np; X = np.ones(100, np.float64); pA = 0.9; pA_arr = np.array([pA]*100, np.float64); pA_arr*X' 100000 loops, best of 3: 13.9 usec per loop So the first one where pA_arr is not created is more than half the speed of the others. This will remove some of the overhead that makes the single spin calculations slower. I'm getting close to the end of the list of your changes now :) Regards, Edward On 10 June 2014 14:37, Troels Emtekær Linnet <tlinnet@xxxxxxxxxxxxx> wrote:Hi Edward. When you have digged your way through, you will see that I end up with: https://gna.org/task/?7807#comment56 Going from 32.247 seconds to 2 second for a 100 clustered calculation. ! BUM! 2014-06-10 14:33 GMT+02:00 Edward d'Auvergne <edward@xxxxxxxxxxxxx>:Hi, Maybe self.spins_a could be renamed as self.ones_array? And self.not_spins_a could be self.zeros_array? Or maybe self.ones_struct and self.zeros_struct? The spin part is only one dimension of 5, so the name is confusing. The name needs to have something to do with the ones and zeros, as well as the entire [ei][si][mi][oi][di] structure. Anyway, I can now see that pA_arr is most definitely not needed ;) Its removal will make the code much faster. Try and see what happens! Regards, Edward On 10 June 2014 14:25, Troels Emtekær Linnet <tlinnet@xxxxxxxxxxxxx> wrote:Hi Edward. spins_a is the multi dimensional numpy array Of dimension [ei][si][mi][oi][di]. It consists of 1.0 on all places, where there are dispersion points. pA is just the float. So, I think we agree? The pA values has to end up in a multi dimensional array. All multiplications in the target functions has to broadcast to the same size. Numpy multiplication is elements vise. In all dimensions. 2014-06-10 13:45 GMT+02:00 Edward d'Auvergne <edward@xxxxxxxxxxxxx>:Hi, I don't think you even need the pA array. What is the variable self.spins_a? Simply try using pA directly. Here is a demo: """ from numpy import array, float64, ones a = ones(3) pA = 0.9 pA_array = pA * a b = array([1, 2, 3], float64) print("\nFloat times array:") print(repr(pA * b)) print("\nArray times array:") print(repr(pA_array * b)) """ If you run this, you will obtain the same result for both operations. Is there a good reason, that I cannot see, why the second option is required in the target functions? Cheers, Edward On 10 June 2014 12:09, Troels Emtekær Linnet <tlinnet@xxxxxxxxxxxxx> wrote:You are Correct !!! The final version is: pA_arr = pA*self.spins_a The "trick" was to make a numpy multi dimensional spin array in the __init__ function of the class. That is filled with 1.0 where there are dispersion points. This array essential replace the spin looping! Best Troels 2014-06-10 11:56 GMT+02:00 Edward d'Auvergne <edward@xxxxxxxxxxxxx>:Hi Troels, From the dispersion equations, to me it looks like that you can keep pA as a single value. Why have you converted it to an array structure? You will have no problems as you can multiply any numpy array with a single float. This should be the same for all model parameters, excluding dw and R20. If you can use single values, that should be much quicker for the target functions. Regards, Edward On 8 June 2014 19:48, <tlinnet@xxxxxxxxxxxxx> wrote:Author: tlinnet Date: Sun Jun 8 19:48:31 2014 New Revision: 23735 URL: http://svn.gna.org/viewcvs/relax?rev=23735&view=rev Log: Important fix for the creation of the multi dimensional pA numpy array. It should be created as numpy.zeros([ei][si][mi][oi]) instead of numpy.ones([ei][si][mi][oi]). This allows for rapid testing of all dimensions with np.allclose(pA, numpy.ones(dw.shape)). pA can have missing filled out values, when the number of dispersion points are different per spectrometer frequency. Task #7807 (https://gna.org/task/index.php?7807): Speed-up of dispersion models for Clustered analysis. Modified: branches/disp_spin_speed/target_functions/relax_disp.py Modified: branches/disp_spin_speed/target_functions/relax_disp.py URL: http://svn.gna.org/viewcvs/relax/branches/disp_spin_speed/target_functions/relax_disp.py?rev=23735&r1=23734&r2=23735&view=diff ============================================================================== --- branches/disp_spin_speed/target_functions/relax_disp.py (original) +++ branches/disp_spin_speed/target_functions/relax_disp.py Sun Jun 8 19:48:31 2014 @@ -411,7 +411,7 @@ # The number of disp point can change per spectrometer, so we make the maximum size. self.R20A_a = np.ones(back_calc_shape + [self.max_num_disp_points]) self.R20B_a = np.ones(back_calc_shape + [self.max_num_disp_points]) - self.pA_a = np.ones(back_calc_shape + [self.max_num_disp_points]) + self.pA_a = np.zeros(back_calc_shape + [self.max_num_disp_points]) self.dw_frq_a = np.ones(back_calc_shape + [self.max_num_disp_points]) self.kex_a = np.ones(back_calc_shape + [self.max_num_disp_points]) self.cpmg_frqs_a = np.ones(back_calc_shape + [self.max_num_disp_points]) _______________________________________________ relax (http://www.nmr-relax.com) This is the relax-commits mailing list relax-commits@xxxxxxx To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-commits_______________________________________________ relax (http://www.nmr-relax.com) This is the relax-devel mailing list relax-devel@xxxxxxx To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-devel