# Want to tally the arithmetic operations of a recursive computation

Say I have a recursive computation func[n], and it involves the standard arithmetic operations +, -, *, /. I want to know how many additions, subtractions, multiplications, and divisions where done in the computation of func[n] for a given n, but separated out by these four categories, not the overall total of numeric operations. Something like: k1 additions, k2 subtractions, k3 multiplications, k4 divisions.

The only thing I could come up with was to look at func[n] in its FullForm, write my own functions for Times[...] etc. that contain accumulators, then re-implement the algorithm with my own functions (basically writing it in FullForm now), and then when running it all the arithmetic operations get tallied -- after the computation I query the accumulators. That seems terribly inefficient to me. Is there an easier way than to implement my own functions for +, -, *, /? Perhaps something with Trace or its brethren?

• Instead of rewriting your programs with custom functions, you can redefine Plus, Times to include your accumulators. Counting occurrences of Plus, Times in Trace is also your very good idea. Commented Feb 2, 2022 at 19:39

Writing a wrapper function with an accumulator would work, but might get tricky with the recursion. Another approach is to "mimic" your original function by accessing its DownValues. Here are some steps:

1. Let's say your original function was named SomeFunc. We're going to use Sow/Reap, so we'll come up with a new name: SowSomeFunc.

2. Define new arithmetic functions that use Sow. For example:

SowPlus[expr___] := (Sow[1, "plus"]; Plus[expr])

SowTimes[expr___] := (Sow[1, "times"]; Times[expr])

3. Define SowSomeFunc by using the DownValues of SomeFunc:

DownValues[SowSomeFunc] = DownValues[SomeFunc] /. {Plus -> SowPlus, Times -> SowTimes, SomeFunc -> SowSomeFunc}

4. Call SowSomeFunc wrapped in Reap:

Reap[SowSomeFunc[2], {"plus", "times"}]

This will return something like {5, {{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}}

1. Since you want to just tally them, you could provide a function that sums up the counts: ReapSummary[tag_, reaped_] := Sequence[tag, Total[reaped]]

and now...

Reap[SowSomeFunc[2], {"plus", "times"}, ReapSummary]

which should give something like: {5, {{"plus", 4}, {"times", 4}}}