After some profiling I've found that my program spends most of its time in the simplification step. The program uses my simplification function many times (over different data). My calculation is not possible without simplifications (expressions quickly become too long).

Here is a representative sample of of my data. (pastebin, 6413 lines of plain text)

The expressions that I want to simplify contain one parameter r. They are linear combinations of the following functions:

{ ExpIntegralEi[2 r], ExpIntegralEi[-2 r],
ExpIntegralEi[4 r], ExpIntegralEi[-4 r],
f000000[r], f000001[r], 
Log[r], Log[4 r] }.

The coefficients of linear combination contain exact numbers, powers of r and

Exp[-2 r], Exp[2 r], Exp[4 r], Exp[-4 r]

How can I make the simplification step in my program faster?

Below I summarize the ideas that I have tried.

No.  Simplification function                 Timing          ByteCount

1   Collect[sample, r, Simplify]            0.512032        19 784
2   Collect[sample, _[r], Simplify]         0.348022        18 632
3   Collect[sample, _[_. r], Simplify]      0.228014        13 136
4   Collect[sample, _[_. r], 
            Collect[#, r, Simplify]& ]      0.17601         20 536
5   Collect[sample /. logrule,
            _[_. r], Simplify]              0.284018        11 624
6   Collect[sample , _[_. r], 
                 Simplify[#]]]&  ]          0.284018        11 624

The first column of the table gives the number of the approach (for convenient reference), the second gives the simplification function, the third column gives the value given by Timing[] (for every Timing[] a fresh kernel session was used), the fourth column gives the ByteCount[] of the result. All calculations were done for the sample available via the link above.

The definition of logrule is:

logrule = {Log[4] -> 2 Log[2], 
           Log[4 r] -> 2 Log[2] + Log[r], 
           Log[16] -> 4 Log[2]};

Simplificatiom methods 5 and 6 indeed give the same Timing and ByteCount, this is not a mistake.

From the table above it can be seen that method no. 4 is the fastest one, methods 5 and 6 give the best compression (I believe that 5 should be generally better). Nevertheless, considering both speed and compression efficiency I conclude that my best function is method no. 3.

How can this method be improved? Or maybe should I replace it with some other method?

  • 1
    $\begingroup$ It could be augmented perhaps by common subexpression elimination. Try ee = Experimental`OptimizeExpression[s2]; where s2 is the result of Collect[]. This might (or might not) give a further size decrease. $\endgroup$ – Daniel Lichtblau Nov 6 '12 at 15:35
  • $\begingroup$ @DanielLichtblau This sounds very promising. However, my goal is rather to make simplification faster (possibly not lowering the compression level). Unfortunately I don't know how to include Experimental`OptimizeExpression[] to my code. This would probably require substantial changes. $\endgroup$ – au700 Nov 6 '12 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.