Message Boards Message Boards

0
|
4898 Views
|
6 Replies
|
1 Total Likes
View groups...
Share
Share this post:

Reduce the time of calculations in my program (Table&Sum&function)?

Posted 7 years ago

Hello everybody. I want to evaluate my numerical data from my program, but it takes about 2 hours (for n=1 to 5 in sigma). I have one sum command (with piecewise function) in the Table command. I must reduce the time to calculate it, anyone have an idea?? Thanks a lot.

Attachments:
POSTED BY: saeid M
6 Replies
Anonymous User
Anonymous User
Posted 7 years ago

two general rules to make anything fast (computer science rules):

  • keep inner loops short, long inner loops (ie, what is inside For) make code very slow. divide and conquer

  • divide and conquer: divide the problem into loops with very little inside

  • count how many operations anything takes: if it is linear to time you are ok. if it becomes time squared: then you can do only a limited ammount of computing before your machine will take forever to complete it

keep in mind for Mathematica:

  • use machine precision for all numbers unless arbitrary precision is required

  • math (math code) can be quicker than "programmed code" - but does not offer an ability to "check and quit conditionally" when working on long arrays - this may or may not be an advantage. use math to your advantage, ie determining things ahead before doing large processes.

  • some say symbolics or solve are slow: but if they replace allot of legacy "program code" you come out way ahead

POSTED BY: Anonymous User
Posted 7 years ago

If I haven't made any mistakes then your code appears equivalent to this simplified version

b = 0.9999998593355306`;
?1 = 0; ?2 = 2 Pi; n? = 40; step? = (?2-?1)/n?;
kt[n_] = n*7.729837371051386*^14;
g[t_, n_, w_, ?_, ?_] = << "C:/Desktop/gt.m";
f1[n1_, w1_] := (pw=Table[
    If[w1 < kt[n1]/(1+b) || w1 > kt[n1]/(1-b),
        cn = dn = 0,
        (*else*)
        ?m = ?1 + (k-1) step?; ?1 = ArcCos[(1-kt[n1]/w1)/b];
        cn = 1.2302418268992892`*^14* NIntegrate[g[t, n1, w1, ?m, ?1], {t,0,8.12848318220823`*^-15}, WorkingPrecision->5]; 
        dn = Abs[cn.cn] - Abs[{Sin[?1] Cos[?m], Sin[?1] Sin[?m], Cos[?1]}.cn]^2; 
        If[dn<=1, 1.4399610959418586`*^-17/(2*Pi*0.000059156065864457335`)*Abs[dn]*8*w1/b, 0]
      ],
    {k, 1, n?+1}
    ];
    step?*(Total[pw]-1/2(pw[[1]]+pw[[n?+1]]))
);
data = Table[{w, Sum[f1[n,w], {n,1,1}]}, {w, 3.86491895735408`*^14, 2.747615443937921`*^22, 2.7476154052887314`*^20}] // AbsoluteTiming

All the computation time is spent evaluating the f1 function which produces the Total of the Table pw.

For each entry in your pw Table, if the parameters are out of range then cn, dn and the entry in your Table are zero, but cn and dn are not actually used in this case.

If the parameters are in range then cn is found from NIntegrate of your 2200 kilobyte interpolating function g, dn is found from cn and the entry in your Table is found from dn.

You do 41 iterations to construct that Table and each iteration is independent of all the other iterations. Thus if you replace that Table with ParallelTable and you ensure that all the parameters and your g interpolating function are available for each iteration of the ParallelTable and you have a license which allows multiple parallel cores and you have a processor with multiple cores and you have sufficient memory to support multiple parallel cores then you might be able to speed up your code.

Please check all this very carefully to make certain that I have not made any mistakes

POSTED BY: Bill Simpson
Posted 7 years ago

Dear Bill, Thank you very much for your comment. I tried to change the code in another way (that you mentioned) but unfortunately I did not get any good results. Does anyone have an idea about how to use parallelization commands in my code? Thanks

POSTED BY: saeid M
Posted 7 years ago

You have three expressions, which had been Piecewise and are now Which and which are used repeatedly

if function out of bounds then zero else if function in bounds then result

Changing those to

If function out of bounds then zero else result

does not change the calculation time because the time needed to evaluate 'function' is approximately zero compared to the time needed for the rest of your calculations.

You have a 600 kilobyte interpolating function that is not used in your example. Removing that only speeds up initialization slightly and makes no change in the timing of your repeated calculations. I assume that is needed and used in the real problem you are trying to solve.

You have a 2200 kilobyte interpolating function of very ill behaved data that is used inside an NIntegrate that is used inside a Sum that is used inside a Table in your example.

In that there are 7310 redundant instances of " + 0.*I" Removing those only speeds up your example code by half a second = 1%.

So to speed your code up substantially I think you need to focus on how you could speed up finding the integral of that interpolating function by 10 or 100 or 1000 times.

Looking at

ListPlot[data,Joined->True,PlotRange->All]

for some of the lists of data points that make up your interpolating function tends to make me think that this may be very challenging to do.

The only thought that I have, and I cannot tell if this would be feasible because there are too many parameters being passed into your interpolating function for me to untangle, would be for you to consider whether you might be able to spend the time up front to in effect calculate something somewhat like the indefinite integral from your data points. If this were feasible then you might be able to get the same result as the NIntegrate but by just subtracting two values from that constructed integral. I'm not suggesting you try to get a symbolic integral, but an interpolating function of that integral.

POSTED BY: Bill Simpson
Posted 7 years ago

Dear Gianluca, Many thanks for your reply. I changed the 3 Piecewise functions to Which functions (in new attachment) as you mentioned. but there is no change in the time of calculations!!

Attachments:
POSTED BY: saeid M

Just at a cursory look, your use of of the high-level Piecewise is inappropriate. Try using the lower-level Which or If.

POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract