Replacement of Do loopsIs there a faster way to calculate Abs[z]^2 numerically?Rapidly binning 3D dataCounting Events in a moving date rangeFunction takes hugely different times to evaluate on sets of virtually (but also literally) identical dataFinding planetary conjunctions with Mathematica (project-level)Performance of calculation of mean squared displacementExtraction of specific image pixels as bytesPerformance of SelectCan this code be changed to run faster?Programming with Mathematica Syntax - Dunford decompositionReading total number of frames in an AVI

Way of refund if scammed?

One word for 'the thing that attracts me'?

Is being an extrovert a necessary condition to be a manager?

What does it mean when みたいな is at the end of a sentence?

(For training purposes) Are there any openings with rook pawns that are more effective than others (and if so, what are they)?

To exponential digit growth and beyond!

Existence of a model of ZFC in which the natural numbers are really the natural numbers

How can I reduce the size of matrix?

Three knights or knaves, three different hair colors

Nunc est bibendum: gerund or gerundive?

Does science define life as "beginning at conception"?

Caught with my phone during an exam

csname in newenviroment

Was murdering a slave illegal in American slavery, and if so, what punishments were given for it?

Why is this integration method not valid?

Does the fact that we can only measure the two-way speed of light undermine the axiom of invariance?

Computing elements of a 1000 x 60 matrix exhausts RAM

How to become an Editorial board member?

A nasty indefinite integral

Why is 'additive' EQ more difficult to use than 'subtractive'?

Why "strap-on" boosters, and how do other people say it?

Coloring lines in a graph the same color if they are the same length

How to make Flex Markers appear in Logic Pro X?

Can someone get a spouse off a deed that never lived together and was incarcerated?



Replacement of Do loops


Is there a faster way to calculate Abs[z]^2 numerically?Rapidly binning 3D dataCounting Events in a moving date rangeFunction takes hugely different times to evaluate on sets of virtually (but also literally) identical dataFinding planetary conjunctions with Mathematica (project-level)Performance of calculation of mean squared displacementExtraction of specific image pixels as bytesPerformance of SelectCan this code be changed to run faster?Programming with Mathematica Syntax - Dunford decompositionReading total number of frames in an AVI













8












$begingroup$


Here is an example code (to calculate the so called structure factor, please see the comment below the question) for a small data set of 2d coordinates. In reality I have a factor of up to 100 times more coordinates.



Code with AbsoluteTiming:



coordinates = Get@"https://pastebin.com/raw/wFxJ1m4U"; 

lX, lZ = 100, 100;

kX = 2 Pi/lX*(Range[lX] - lX/2) // N;
kZ = 2 Pi/lZ*(Range[lZ] - lZ/2) // N;

cx = Flatten[coordinates[[All, 1]]];
cz = Flatten[coordinates[[All, 2]]];

rX = Flatten@Outer[Differences[##] &, cx, cx];
rZ = Flatten@Outer[Differences[##] &, cz, cz];

nP = Length[coordinates];

s = Array[0 &, lZ, lX];

Do[
Do[
s[[j, i]] = 1/nP*Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]]
, i, 1, lX
]
, j, 1, lZ
]; // AbsoluteTiming

31.3555, Null


How can I speed up this code?




A huge problem occurs for many coordinates: for about 2400 coordinates the calculation takes about 3 days!



Here are 2403 coordinates: https://pastebin.com/raw/0t1MBAgX .
Please use for this test lX, lZ = 1600, 1200



Here is the code for this large data set: https://pastebin.com/raw/MH5Pb4h0



Can the double loop be compiled?










share|improve this question











$endgroup$







  • 2




    $begingroup$
    Can you add information about what this code is supposed to do to your question?
    $endgroup$
    – Carl Lange
    May 8 at 8:17










  • $begingroup$
    @Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
    $endgroup$
    – lio
    May 8 at 8:38






  • 1




    $begingroup$
    On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
    $endgroup$
    – Roman
    May 8 at 8:51






  • 1




    $begingroup$
    I agree with @Roman, on my computer your code took about 14s as well.
    $endgroup$
    – Turgon
    May 8 at 8:52






  • 2




    $begingroup$
    Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
    $endgroup$
    – Roman
    May 8 at 9:01















8












$begingroup$


Here is an example code (to calculate the so called structure factor, please see the comment below the question) for a small data set of 2d coordinates. In reality I have a factor of up to 100 times more coordinates.



Code with AbsoluteTiming:



coordinates = Get@"https://pastebin.com/raw/wFxJ1m4U"; 

lX, lZ = 100, 100;

kX = 2 Pi/lX*(Range[lX] - lX/2) // N;
kZ = 2 Pi/lZ*(Range[lZ] - lZ/2) // N;

cx = Flatten[coordinates[[All, 1]]];
cz = Flatten[coordinates[[All, 2]]];

rX = Flatten@Outer[Differences[##] &, cx, cx];
rZ = Flatten@Outer[Differences[##] &, cz, cz];

nP = Length[coordinates];

s = Array[0 &, lZ, lX];

Do[
Do[
s[[j, i]] = 1/nP*Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]]
, i, 1, lX
]
, j, 1, lZ
]; // AbsoluteTiming

31.3555, Null


How can I speed up this code?




A huge problem occurs for many coordinates: for about 2400 coordinates the calculation takes about 3 days!



Here are 2403 coordinates: https://pastebin.com/raw/0t1MBAgX .
Please use for this test lX, lZ = 1600, 1200



Here is the code for this large data set: https://pastebin.com/raw/MH5Pb4h0



Can the double loop be compiled?










share|improve this question











$endgroup$







  • 2




    $begingroup$
    Can you add information about what this code is supposed to do to your question?
    $endgroup$
    – Carl Lange
    May 8 at 8:17










  • $begingroup$
    @Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
    $endgroup$
    – lio
    May 8 at 8:38






  • 1




    $begingroup$
    On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
    $endgroup$
    – Roman
    May 8 at 8:51






  • 1




    $begingroup$
    I agree with @Roman, on my computer your code took about 14s as well.
    $endgroup$
    – Turgon
    May 8 at 8:52






  • 2




    $begingroup$
    Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
    $endgroup$
    – Roman
    May 8 at 9:01













8












8








8


2



$begingroup$


Here is an example code (to calculate the so called structure factor, please see the comment below the question) for a small data set of 2d coordinates. In reality I have a factor of up to 100 times more coordinates.



Code with AbsoluteTiming:



coordinates = Get@"https://pastebin.com/raw/wFxJ1m4U"; 

lX, lZ = 100, 100;

kX = 2 Pi/lX*(Range[lX] - lX/2) // N;
kZ = 2 Pi/lZ*(Range[lZ] - lZ/2) // N;

cx = Flatten[coordinates[[All, 1]]];
cz = Flatten[coordinates[[All, 2]]];

rX = Flatten@Outer[Differences[##] &, cx, cx];
rZ = Flatten@Outer[Differences[##] &, cz, cz];

nP = Length[coordinates];

s = Array[0 &, lZ, lX];

Do[
Do[
s[[j, i]] = 1/nP*Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]]
, i, 1, lX
]
, j, 1, lZ
]; // AbsoluteTiming

31.3555, Null


How can I speed up this code?




A huge problem occurs for many coordinates: for about 2400 coordinates the calculation takes about 3 days!



Here are 2403 coordinates: https://pastebin.com/raw/0t1MBAgX .
Please use for this test lX, lZ = 1600, 1200



Here is the code for this large data set: https://pastebin.com/raw/MH5Pb4h0



Can the double loop be compiled?










share|improve this question











$endgroup$




Here is an example code (to calculate the so called structure factor, please see the comment below the question) for a small data set of 2d coordinates. In reality I have a factor of up to 100 times more coordinates.



Code with AbsoluteTiming:



coordinates = Get@"https://pastebin.com/raw/wFxJ1m4U"; 

lX, lZ = 100, 100;

kX = 2 Pi/lX*(Range[lX] - lX/2) // N;
kZ = 2 Pi/lZ*(Range[lZ] - lZ/2) // N;

cx = Flatten[coordinates[[All, 1]]];
cz = Flatten[coordinates[[All, 2]]];

rX = Flatten@Outer[Differences[##] &, cx, cx];
rZ = Flatten@Outer[Differences[##] &, cz, cz];

nP = Length[coordinates];

s = Array[0 &, lZ, lX];

Do[
Do[
s[[j, i]] = 1/nP*Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]]
, i, 1, lX
]
, j, 1, lZ
]; // AbsoluteTiming

31.3555, Null


How can I speed up this code?




A huge problem occurs for many coordinates: for about 2400 coordinates the calculation takes about 3 days!



Here are 2403 coordinates: https://pastebin.com/raw/0t1MBAgX .
Please use for this test lX, lZ = 1600, 1200



Here is the code for this large data set: https://pastebin.com/raw/MH5Pb4h0



Can the double loop be compiled?







performance-tuning






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 14 at 17:10







lio

















asked May 8 at 8:10









liolio

1,131318




1,131318







  • 2




    $begingroup$
    Can you add information about what this code is supposed to do to your question?
    $endgroup$
    – Carl Lange
    May 8 at 8:17










  • $begingroup$
    @Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
    $endgroup$
    – lio
    May 8 at 8:38






  • 1




    $begingroup$
    On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
    $endgroup$
    – Roman
    May 8 at 8:51






  • 1




    $begingroup$
    I agree with @Roman, on my computer your code took about 14s as well.
    $endgroup$
    – Turgon
    May 8 at 8:52






  • 2




    $begingroup$
    Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
    $endgroup$
    – Roman
    May 8 at 9:01












  • 2




    $begingroup$
    Can you add information about what this code is supposed to do to your question?
    $endgroup$
    – Carl Lange
    May 8 at 8:17










  • $begingroup$
    @Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
    $endgroup$
    – lio
    May 8 at 8:38






  • 1




    $begingroup$
    On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
    $endgroup$
    – Roman
    May 8 at 8:51






  • 1




    $begingroup$
    I agree with @Roman, on my computer your code took about 14s as well.
    $endgroup$
    – Turgon
    May 8 at 8:52






  • 2




    $begingroup$
    Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
    $endgroup$
    – Roman
    May 8 at 9:01







2




2




$begingroup$
Can you add information about what this code is supposed to do to your question?
$endgroup$
– Carl Lange
May 8 at 8:17




$begingroup$
Can you add information about what this code is supposed to do to your question?
$endgroup$
– Carl Lange
May 8 at 8:17












$begingroup$
@Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
$endgroup$
– lio
May 8 at 8:38




$begingroup$
@Carl Lange: It calculates the structures factor of a crystaline structure (S(k) algorithm from a paper by Henrich et al., arXiv:1001.3342v1, equation 2.6, pdf file: arxiv.org/pdf/1001.3342.pdf)
$endgroup$
– lio
May 8 at 8:38




1




1




$begingroup$
On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
$endgroup$
– Roman
May 8 at 8:51




$begingroup$
On my computer your first (non-parallel) code only takes 14.4 seconds. Replacing the last double loop with s = Outer[Total[Cos[#1 + #2]] &, KroneckerProduct[kZ, rZ], KroneckerProduct[kX, rX], 1]/nP cuts this down to 8.6 seconds. I have no idea where your excessive runtime of 3714.41 seconds comes from.
$endgroup$
– Roman
May 8 at 8:51




1




1




$begingroup$
I agree with @Roman, on my computer your code took about 14s as well.
$endgroup$
– Turgon
May 8 at 8:52




$begingroup$
I agree with @Roman, on my computer your code took about 14s as well.
$endgroup$
– Turgon
May 8 at 8:52




2




2




$begingroup$
Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
$endgroup$
– Roman
May 8 at 9:01




$begingroup$
Have you run your own code in a fresh kernel? What is your Mathematica version? Have you tried replacing the cosine sum by a Fourier or FourierDCT call?
$endgroup$
– Roman
May 8 at 9:01










1 Answer
1






active

oldest

votes


















17












$begingroup$

Table works a little bit better than Do:



s = Table[Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]], j, 1, lZ, i, 1, lX]/nP;


Much more speed can be gained by first rewriting the cosines as imaginary exponentials, and then rewriting exponentials of sums as products of exponentials. As a result, rX and rZ aren't needed, and the calculation takes 0.03 seconds, or just over one second with the large data set:



s = Abs[Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]^2/nP; //
AbsoluteTiming // First
(* 1.22367 *)


A little more speed can be gained with this trick of using an internal function to calculate Abs[...]^2:



s = Internal`AbsSquare[
Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]/nP; //
AbsoluteTiming // First
(* 1.09222 *)


A bit more speed could be gained by replacing the Kronecker products by a NestList, as the values in kX and kZ are uniformly spaced and thus the many exponentials can be replaced by repeated multiplications of a single exponential. This is numerically less stable though, and in any case at this point 50% of the time are spent in the Dot product which is unavoidable, so the best remaining speedup you could hope for is another factor of two.



Lesson of the day: don't think about compiling before you've tried rewriting the algorithm.



mathematical derivation



Starting from Eq. (2.6) of https://arxiv.org/pdf/1001.3342.pdf



$$
S_vecq=frac1Nsum_i j cos[vecqcdot(vecr_i-vecr_j)]
= frac1NResum_i j e^texti vecqcdot(vecr_i-vecr_j)
= frac1NResum_i j e^texti vecqcdotvecr_ie^-textivecqcdotvecr_j\
= frac1NReleft[sum_i e^texti vecqcdotvecr_iright]left[sum_j e^-texti vecqcdotvecr_jright]
= frac1Nleft|sum_i e^texti vecqcdotvecr_iright|^2
= frac1Nleft|sum_i e^texti q_xr_i,xe^texti q_zr_i,zright|^2
$$



From there it's a matter of calculating all the possible combinations of $e^texti q_xr_i,x$ and $e^texti q_zr_i,z$ with all desired $vecq$-values (in kX and kZ), and then summing over them. These operations are most efficiently done with vector operations like KroneckerProduct, listable Exp, Dot-products, and finally a listable Abs or AbsSquare.






share|improve this answer











$endgroup$












  • $begingroup$
    Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
    $endgroup$
    – lio
    May 8 at 12:10











  • $begingroup$
    Again, please make sure you use a fresh kernel to run calculations.
    $endgroup$
    – Roman
    May 8 at 12:14










  • $begingroup$
    I did it but still get False(Mathematica 12.0)
    $endgroup$
    – lio
    May 8 at 12:17







  • 2




    $begingroup$
    @b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
    $endgroup$
    – Roman
    May 10 at 12:31







  • 1




    $begingroup$
    @cphys or simply s-s2 // Abs // Max
    $endgroup$
    – Roman
    May 15 at 20:46











Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "387"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f197924%2freplacement-of-do-loops%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









17












$begingroup$

Table works a little bit better than Do:



s = Table[Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]], j, 1, lZ, i, 1, lX]/nP;


Much more speed can be gained by first rewriting the cosines as imaginary exponentials, and then rewriting exponentials of sums as products of exponentials. As a result, rX and rZ aren't needed, and the calculation takes 0.03 seconds, or just over one second with the large data set:



s = Abs[Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]^2/nP; //
AbsoluteTiming // First
(* 1.22367 *)


A little more speed can be gained with this trick of using an internal function to calculate Abs[...]^2:



s = Internal`AbsSquare[
Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]/nP; //
AbsoluteTiming // First
(* 1.09222 *)


A bit more speed could be gained by replacing the Kronecker products by a NestList, as the values in kX and kZ are uniformly spaced and thus the many exponentials can be replaced by repeated multiplications of a single exponential. This is numerically less stable though, and in any case at this point 50% of the time are spent in the Dot product which is unavoidable, so the best remaining speedup you could hope for is another factor of two.



Lesson of the day: don't think about compiling before you've tried rewriting the algorithm.



mathematical derivation



Starting from Eq. (2.6) of https://arxiv.org/pdf/1001.3342.pdf



$$
S_vecq=frac1Nsum_i j cos[vecqcdot(vecr_i-vecr_j)]
= frac1NResum_i j e^texti vecqcdot(vecr_i-vecr_j)
= frac1NResum_i j e^texti vecqcdotvecr_ie^-textivecqcdotvecr_j\
= frac1NReleft[sum_i e^texti vecqcdotvecr_iright]left[sum_j e^-texti vecqcdotvecr_jright]
= frac1Nleft|sum_i e^texti vecqcdotvecr_iright|^2
= frac1Nleft|sum_i e^texti q_xr_i,xe^texti q_zr_i,zright|^2
$$



From there it's a matter of calculating all the possible combinations of $e^texti q_xr_i,x$ and $e^texti q_zr_i,z$ with all desired $vecq$-values (in kX and kZ), and then summing over them. These operations are most efficiently done with vector operations like KroneckerProduct, listable Exp, Dot-products, and finally a listable Abs or AbsSquare.






share|improve this answer











$endgroup$












  • $begingroup$
    Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
    $endgroup$
    – lio
    May 8 at 12:10











  • $begingroup$
    Again, please make sure you use a fresh kernel to run calculations.
    $endgroup$
    – Roman
    May 8 at 12:14










  • $begingroup$
    I did it but still get False(Mathematica 12.0)
    $endgroup$
    – lio
    May 8 at 12:17







  • 2




    $begingroup$
    @b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
    $endgroup$
    – Roman
    May 10 at 12:31







  • 1




    $begingroup$
    @cphys or simply s-s2 // Abs // Max
    $endgroup$
    – Roman
    May 15 at 20:46















17












$begingroup$

Table works a little bit better than Do:



s = Table[Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]], j, 1, lZ, i, 1, lX]/nP;


Much more speed can be gained by first rewriting the cosines as imaginary exponentials, and then rewriting exponentials of sums as products of exponentials. As a result, rX and rZ aren't needed, and the calculation takes 0.03 seconds, or just over one second with the large data set:



s = Abs[Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]^2/nP; //
AbsoluteTiming // First
(* 1.22367 *)


A little more speed can be gained with this trick of using an internal function to calculate Abs[...]^2:



s = Internal`AbsSquare[
Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]/nP; //
AbsoluteTiming // First
(* 1.09222 *)


A bit more speed could be gained by replacing the Kronecker products by a NestList, as the values in kX and kZ are uniformly spaced and thus the many exponentials can be replaced by repeated multiplications of a single exponential. This is numerically less stable though, and in any case at this point 50% of the time are spent in the Dot product which is unavoidable, so the best remaining speedup you could hope for is another factor of two.



Lesson of the day: don't think about compiling before you've tried rewriting the algorithm.



mathematical derivation



Starting from Eq. (2.6) of https://arxiv.org/pdf/1001.3342.pdf



$$
S_vecq=frac1Nsum_i j cos[vecqcdot(vecr_i-vecr_j)]
= frac1NResum_i j e^texti vecqcdot(vecr_i-vecr_j)
= frac1NResum_i j e^texti vecqcdotvecr_ie^-textivecqcdotvecr_j\
= frac1NReleft[sum_i e^texti vecqcdotvecr_iright]left[sum_j e^-texti vecqcdotvecr_jright]
= frac1Nleft|sum_i e^texti vecqcdotvecr_iright|^2
= frac1Nleft|sum_i e^texti q_xr_i,xe^texti q_zr_i,zright|^2
$$



From there it's a matter of calculating all the possible combinations of $e^texti q_xr_i,x$ and $e^texti q_zr_i,z$ with all desired $vecq$-values (in kX and kZ), and then summing over them. These operations are most efficiently done with vector operations like KroneckerProduct, listable Exp, Dot-products, and finally a listable Abs or AbsSquare.






share|improve this answer











$endgroup$












  • $begingroup$
    Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
    $endgroup$
    – lio
    May 8 at 12:10











  • $begingroup$
    Again, please make sure you use a fresh kernel to run calculations.
    $endgroup$
    – Roman
    May 8 at 12:14










  • $begingroup$
    I did it but still get False(Mathematica 12.0)
    $endgroup$
    – lio
    May 8 at 12:17







  • 2




    $begingroup$
    @b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
    $endgroup$
    – Roman
    May 10 at 12:31







  • 1




    $begingroup$
    @cphys or simply s-s2 // Abs // Max
    $endgroup$
    – Roman
    May 15 at 20:46













17












17








17





$begingroup$

Table works a little bit better than Do:



s = Table[Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]], j, 1, lZ, i, 1, lX]/nP;


Much more speed can be gained by first rewriting the cosines as imaginary exponentials, and then rewriting exponentials of sums as products of exponentials. As a result, rX and rZ aren't needed, and the calculation takes 0.03 seconds, or just over one second with the large data set:



s = Abs[Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]^2/nP; //
AbsoluteTiming // First
(* 1.22367 *)


A little more speed can be gained with this trick of using an internal function to calculate Abs[...]^2:



s = Internal`AbsSquare[
Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]/nP; //
AbsoluteTiming // First
(* 1.09222 *)


A bit more speed could be gained by replacing the Kronecker products by a NestList, as the values in kX and kZ are uniformly spaced and thus the many exponentials can be replaced by repeated multiplications of a single exponential. This is numerically less stable though, and in any case at this point 50% of the time are spent in the Dot product which is unavoidable, so the best remaining speedup you could hope for is another factor of two.



Lesson of the day: don't think about compiling before you've tried rewriting the algorithm.



mathematical derivation



Starting from Eq. (2.6) of https://arxiv.org/pdf/1001.3342.pdf



$$
S_vecq=frac1Nsum_i j cos[vecqcdot(vecr_i-vecr_j)]
= frac1NResum_i j e^texti vecqcdot(vecr_i-vecr_j)
= frac1NResum_i j e^texti vecqcdotvecr_ie^-textivecqcdotvecr_j\
= frac1NReleft[sum_i e^texti vecqcdotvecr_iright]left[sum_j e^-texti vecqcdotvecr_jright]
= frac1Nleft|sum_i e^texti vecqcdotvecr_iright|^2
= frac1Nleft|sum_i e^texti q_xr_i,xe^texti q_zr_i,zright|^2
$$



From there it's a matter of calculating all the possible combinations of $e^texti q_xr_i,x$ and $e^texti q_zr_i,z$ with all desired $vecq$-values (in kX and kZ), and then summing over them. These operations are most efficiently done with vector operations like KroneckerProduct, listable Exp, Dot-products, and finally a listable Abs or AbsSquare.






share|improve this answer











$endgroup$



Table works a little bit better than Do:



s = Table[Total[Cos[kX[[i]]*rX + kZ[[j]]*rZ]], j, 1, lZ, i, 1, lX]/nP;


Much more speed can be gained by first rewriting the cosines as imaginary exponentials, and then rewriting exponentials of sums as products of exponentials. As a result, rX and rZ aren't needed, and the calculation takes 0.03 seconds, or just over one second with the large data set:



s = Abs[Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]^2/nP; //
AbsoluteTiming // First
(* 1.22367 *)


A little more speed can be gained with this trick of using an internal function to calculate Abs[...]^2:



s = Internal`AbsSquare[
Exp[I*KroneckerProduct[kZ, cz]].Exp[I*KroneckerProduct[cx, kX]]]/nP; //
AbsoluteTiming // First
(* 1.09222 *)


A bit more speed could be gained by replacing the Kronecker products by a NestList, as the values in kX and kZ are uniformly spaced and thus the many exponentials can be replaced by repeated multiplications of a single exponential. This is numerically less stable though, and in any case at this point 50% of the time are spent in the Dot product which is unavoidable, so the best remaining speedup you could hope for is another factor of two.



Lesson of the day: don't think about compiling before you've tried rewriting the algorithm.



mathematical derivation



Starting from Eq. (2.6) of https://arxiv.org/pdf/1001.3342.pdf



$$
S_vecq=frac1Nsum_i j cos[vecqcdot(vecr_i-vecr_j)]
= frac1NResum_i j e^texti vecqcdot(vecr_i-vecr_j)
= frac1NResum_i j e^texti vecqcdotvecr_ie^-textivecqcdotvecr_j\
= frac1NReleft[sum_i e^texti vecqcdotvecr_iright]left[sum_j e^-texti vecqcdotvecr_jright]
= frac1Nleft|sum_i e^texti vecqcdotvecr_iright|^2
= frac1Nleft|sum_i e^texti q_xr_i,xe^texti q_zr_i,zright|^2
$$



From there it's a matter of calculating all the possible combinations of $e^texti q_xr_i,x$ and $e^texti q_zr_i,z$ with all desired $vecq$-values (in kX and kZ), and then summing over them. These operations are most efficiently done with vector operations like KroneckerProduct, listable Exp, Dot-products, and finally a listable Abs or AbsSquare.







share|improve this answer














share|improve this answer



share|improve this answer








edited May 14 at 14:21

























answered May 8 at 9:18









RomanRoman

8,73511240




8,73511240











  • $begingroup$
    Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
    $endgroup$
    – lio
    May 8 at 12:10











  • $begingroup$
    Again, please make sure you use a fresh kernel to run calculations.
    $endgroup$
    – Roman
    May 8 at 12:14










  • $begingroup$
    I did it but still get False(Mathematica 12.0)
    $endgroup$
    – lio
    May 8 at 12:17







  • 2




    $begingroup$
    @b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
    $endgroup$
    – Roman
    May 10 at 12:31







  • 1




    $begingroup$
    @cphys or simply s-s2 // Abs // Max
    $endgroup$
    – Roman
    May 15 at 20:46
















  • $begingroup$
    Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
    $endgroup$
    – lio
    May 8 at 12:10











  • $begingroup$
    Again, please make sure you use a fresh kernel to run calculations.
    $endgroup$
    – Roman
    May 8 at 12:14










  • $begingroup$
    I did it but still get False(Mathematica 12.0)
    $endgroup$
    – lio
    May 8 at 12:17







  • 2




    $begingroup$
    @b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
    $endgroup$
    – Roman
    May 10 at 12:31







  • 1




    $begingroup$
    @cphys or simply s-s2 // Abs // Max
    $endgroup$
    – Roman
    May 15 at 20:46















$begingroup$
Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
$endgroup$
– lio
May 8 at 12:10





$begingroup$
Can you check if this result is equal to my s. I named your result as s2 and my as s. And if I check s==s2 it gives False. Please see also (s[[#]] == s2[[#]]) & /@ Range[lZ]. Nevertheless this difference is neglectable.
$endgroup$
– lio
May 8 at 12:10













$begingroup$
Again, please make sure you use a fresh kernel to run calculations.
$endgroup$
– Roman
May 8 at 12:14




$begingroup$
Again, please make sure you use a fresh kernel to run calculations.
$endgroup$
– Roman
May 8 at 12:14












$begingroup$
I did it but still get False(Mathematica 12.0)
$endgroup$
– lio
May 8 at 12:17





$begingroup$
I did it but still get False(Mathematica 12.0)
$endgroup$
– lio
May 8 at 12:17





2




2




$begingroup$
@b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
$endgroup$
– Roman
May 10 at 12:31





$begingroup$
@b3m2a1 see my updated solution: if you rewrite these cosines as exponentials, then you only need to KroneckerProduct with cx instead of rX, and the result easily fits into memory. In effect, rX contains cx twice, and this double-use is replaced by an Abs[...]^2 call.
$endgroup$
– Roman
May 10 at 12:31





1




1




$begingroup$
@cphys or simply s-s2 // Abs // Max
$endgroup$
– Roman
May 15 at 20:46




$begingroup$
@cphys or simply s-s2 // Abs // Max
$endgroup$
– Roman
May 15 at 20:46

















draft saved

draft discarded
















































Thanks for contributing an answer to Mathematica Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f197924%2freplacement-of-do-loops%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020