2
$\begingroup$

Im interested in counting the number of operations required to evaluate a given formula. Let me give you an example.

Lets say I have entered the expression $\dfrac{\operatorname{Sqrt}[\operatorname{Sin}[a*x+b*x-c*y]]}{2*a+b}$

Now lets say you have values for those unknows $a,b,c$. Then you would to calculate $a*x+b*x-c*y$ first which requires 3 multiplications, 1 addition and 1 subtraction. Then you take the $\sin(...)$ and then the square root.

Now you might calculate $2*a+b$ which requires 1 multiplication and 1 addition. In the end you take the quotient. This gives a total number of:

$1\times\sin, 1\times\sqrt{\cdot} \ 1 \times$ quotient, $4 \times $ multiplication, $2 \times$ addition and 1 subtraction.

Well you might call one subtraction the result of 1 multiplication and 1 addition. But that doesnt matter to me.

Since I have most of my formulas stored in Mathematica it would be great to have such a function. That would save a lot of time counting by hand.

$\endgroup$
2
$\begingroup$

Maybe you can use the output of Experimental`OptimizeExpression? For your example:

Experimental`OptimizeExpression[
    Sqrt[Sin[a x + b x - c y]]/(2 a + b), 
    "OptimizationLevel"->2
]
Experimental`OptimizedExpression[
   Block[{Compile`$34, Compile`$35, Compile`$36, Compile`$37, Compile`$38, Compile`$39, Compile`$40, Compile`$41, Compile`$42}, 
      Compile`$34 = 2 a; 
      Compile`$35 = Compile`$34 + b; 
      Compile`$36 = 1/Compile`$35;
          Compile`$37 = a x; 
      Compile`$38 = b x; 
      Compile`$39 = -c y; 
          Compile`$40 = Compile`$37 + Compile`$38 + Compile`$39; 
      Compile`$41 = Sin[Compile`$40]; 
          Compile`$42 = Sqrt[Compile`$41]; 
      Compile`$36 Compile`$42
   ]
]

A version using it might be something like:

opCount[expr_] := Extract[
    Experimental`OptimizeExpression[expr, "OptimizationLevel"->2],
    {1,1},
    Length
] + 1

opCount[Sqrt[Sin[a x + b x - c y]]/(2 a + b)]

10

$\endgroup$
1
$\begingroup$

I'm not sure if this gets you exactly what you want, but I found this in the documentation for LeafCount:

expr = Sqrt[Sin[a x + b x - c y]]/(2 a + b)
leaves = Level[expr, {-1}, Heads -> True]
Tally[leaves]

$\left( \begin{array}{cc} \text{Times} & 5 \\ \text{Power} & 2 \\ \text{Plus} & 2 \\ 2 & 1 \\ a & 2 \\ b & 2 \\ -1 & 2 \\ \text{Sin} & 1 \\ x & 2 \\ c & 1 \\ y & 1 \\ \frac{1}{2} & 1 \\ \end{array} \right)$

Like you mentioned, subtraction is dealt with as a multiplication of a negative number and addition. Also I'm not sure if this is a deal-breaker, but division is dealt with as a multiplication with $(2a+b)^{-1}$ and the square root is dealt with as Power[..., Rational[1, 2]].

You could filter the resulting tally a bit with

Select[Tally[leaves], Or @@ Thread[#[[1]] == {Sin, Times, Power, Plus}] &]

$\left( \begin{array}{cc} \text{Times} & 5 \\ \text{Power} & 2 \\ \text{Plus} & 2 \\ \text{Sin} & 1 \\ \end{array} \right)$

$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.