Hi, See below:
The problem is, that if you make multiply with [300], to a numpy array, it will expand the last axis. Reshaping that into a usable form is the problem. I spent many many many hours, to get to this: # Reshape dw to per experiment and nr spins. Or for R20A per experiment, spin and frequency. [300] -> [1, 300] : [300] -> [1, 100, 3] # Expand axis [1, 300] -> [1, 300, 1, 1, 1] : [1, 100, 3]-> [1, 100, 3, 1, 1] # Then tile to dimensions [1, 300, 1, 1, 1] -> [1, 300, 3, 1, 22] : [1, 100, 3, 1, 22] This is a very logic build up of the shapes. The add or multiply would multiply to the last axis. The only thing I could do, was to create newaxis. And then tile up! --------- Example code to play with. import numpy as np s = [1, 100, 3, 1, 22] print "dw" dw = np.asarray(range(100)) print dw.shape dw1 = dw.reshape( (s[0], s[1]) ) print dw1.shape dw2 = dw1[:,:,None,None,None] print dw2.shape dw3 = np.tile(dw2, (1, 1, s[2], s[3], s[4])) print dw3.shape print "r20" r = np.asarray(range(300)) print r.shape r1 = r.reshape( (s[0], s[1], s[2]) ) print r1.shape r2 = r1[:,:,:,None,None] print r2.shape r3 = np.tile(r2, (1, 1, 1, s[3], s[4])) print r3.shape ------------------- With this, I think I am done!
With the code example I gave (http://thread.gmane.org/gmane.science.nmr.relax.devel/6135/focus=6154), all of this logic can be replaced. I hope the example is enough for both dw and R20 structure creation. Despite reintroducing a loop - note that the loop does not involve calls to the lib.dispersion functions so it does not have anywhere near the same cost as the loops you eliminated - this solution will speed things up by avoiding automatic Python data structure creation and deletion.
I really would like to wrap this up and continue with my own stuff. So, what needs to be done, before you can accept this? I will: Expand to other CPMG models, which are analytical Include R1rho.
That should be rather easy now with your infrastructure. I would recommend the dw and R20 speed ups first, as that will make the target functions far simpler and quicker to upgrade to the new design.
I cannot do for numerical, do to the looping.
To keep the API clean, the looping needs to be shifted to be inside the lib.dispersion functions. That should be easy enough.
Should I add unit tests for each?
You probably saw how useful the unit tests were when you were making the changes to the 'disp_spin_speed' branch. Feel free to add tests as you wish. I don't think we have universal coverage of all models yet, though I could be wrong with that. Additional points would be to clean up the code and comments (for example there are quite a few '##' that should be '#', and a few trivial whitespace issues). Then I can check it and give feedback for anything else that needs to be done. I can then merge the branch back to trunk and release it with a new version of relax. Cheers! Edward