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 <[email protected]> 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 <[email protected]>: >> 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 <[email protected]> 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 <[email protected]>: >>>> 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 <[email protected]> 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 <[email protected]>: >>>>>> 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, <[email protected]> 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 >>>>>>> [email protected] >>>>>>> >>>>>>> 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 >>>>>> [email protected] >>>>>> >>>>>> 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 _______________________________________________ relax (http://www.nmr-relax.com) This is the relax-devel mailing list [email protected] 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

