I've been writing a function to sum a pairwise potential on two lists, i.e. two charged bodies, each containing N >> 1
and M >> 1
atoms respectively.
I need to be able to calculate the potential of atom-atom, residue-residue or body-body potential.
In order to do so, I've defined the atom-atom, residue-residue, and body-body potentials as
Caa[atom1_,atom2_]:= Coulomb[atom1,atom2];
Crr[res1_,res2_]:= Total[Outer[Caa,res1,res2,1],2]
Cbb[body1_,body2_]:= Total[Outer[Crr,body1,body2,1],2]
where
body1 = {res11,res12,res13,...}
body2 = {res21,res22,res32,...}
res11 = {atom111,atom112,atom113,...}
res12 = {atom121,atom122,atom123,...}
...
res21 = {atom211,atom212,atom213,...}
res22 = {atom221,atom222,atom223,...}
...
atom111 = {{x111,y111,z111},q111}
atom112 = {{x112,y112,z112},q112}
...
atom211 = {{x211,y211,z211},q211}
atom212 = {{x212,y212,z212},q212}
...
i.e, two lists (bodies) of residues, which in turn are lists of atoms, all properly indexed.
My question is, what is the most efficient way to define Crr
and Cbb
?
I've tried with loops, Sum
, Table
, and a the Total[Outer[...],2]
definition shown, but all seem to take almost the same (very long) time when doing a Timing
check.
Needless to say, Coulomb
is a radial function, i.e., it only depends on the distance between atom1
and atom2
, and atom = {{x,y,z},q}
, where q
is the charge.
--EDIT 1--
Coulomb[atom1_,atom2_]:= atom1[[2]] atom2[[2]]/Norm[atom1[[1]]-atom2[[1]]]
--EDIT 2--
In http://pastebin.com/Yf9TKSDx, you can find a small example of body1
and body2
.
Here, body1[[i]]
, will give you the ith residue of the first body, body1[[i,j]]
, the jth atom of the ith residue of body1
.
The atom-atom potential is calculated by doing
Caa[body1[[i,j]],body2[[k,l]]]
the residue-residue potential
Crr[body1[[i]],body2[[j]]]
and the body-body potential
Cbb[body1,body2]
hope this clarifies the problem.
Outer[]
version is quite fast (almost idiomatic); you should maybe look into makingCoulomb[]
more efficient. $\endgroup$ – J. M.'s ennui♦ Aug 3 '12 at 6:40Norm[v, p]
is the $p$-norm of the vectorv
. Maybe you wantedEuclideanDistance[]
? $\endgroup$ – J. M.'s ennui♦ Aug 3 '12 at 7:04f
that's close enough in time complexity to yourCoulomb
, and useres = RandomReal[...]
(use a seed). Give us something concrete to objectively measure improvement $\endgroup$ – rm -rf♦ Aug 3 '12 at 14:01Coulomb[]
was suggested to be important for performance. Why speculate on complexity ofCoulomb
if I can simply post it. I'm a physicist and I think in terms of physics, and it seems unfair to say no one cares. I don't care if you don't care. $\endgroup$ – Pragabhava Aug 3 '12 at 20:40Coulomb
's definition... I was asking you to strip all the body-body, residue-residue details which are only confusing. If you understand it, good for you! But keep in mind that you're seeking help from a Q&A site, where most people might not be physicists like you. I'm certainly not. In such cases, it is helpful if you kept the question solely on the list-manipulation part of it without other details. Moving on, am I right in assuming that yourCaa
,Crr
andCbb
work as you expect (i.e., give you the right answer) and all you want to do now is improve speed? $\endgroup$ – rm -rf♦ Aug 3 '12 at 20:50