# Computations with OptimizedExpressions without completely expanding them

I have to manipulate huge expressions that are rational functions of many (∼30) variables with integer coefficients. Storing them just as a ratio of two polynomials would be impractical. But they can be represented as multi-level (∼140 levels) nested sums of fractions. Storing them in this form still would be impractical (billions of nodes), but, luckily, they have lots of repeated sub-expressions, so I store them as expressions with ExperimentalOptimizedExpression head, where all repeated parts are recursively extracted and denoted by auxiliary intermediate variables. In this form my expressions only have a few thousands of nodes.

To convert expressions to this optimized form I use ExperimentalOptimizeExpression function, with some additional custom post-processing. Often, I have a list of expressions, but as they usually have many shared repeated parts, the list can be efficiently represented as a single optimized expression where all shared parts are extracted.

Now, I need to do some symbolic computations with optimized expressions: addition, multiplication, division and a substitution of one optimized expression for a variable in another. In all these cases, I want to get a single optimized expression as a result, where each shared repeated part among operands is extracted and denoted by a single variable.

For smaller expressions, this can be done by a brute-force approach: expand the operands first, perform the operation as usual and, finally, apply ExperimentalOptimizeExpression` to the result to get an optimized form. For larger expressions, it becomes too slow. I was about to write my custom algorithm for extracting shared parts from several optimized expressions without fully expanding them. But I thought that other people, likely, already have faced a similar problem. So, I would appreciate if anybody has an existing solution, and is willing to share it. Or, maybe, there is already a function in Mathematica that can do it?

• May 15 '20 at 21:43
• Since these are tree structures, it might make sense to use Graph and create new trees fro old in that setting.You still have your several thousand vertices (nodes) to keep track of, but you never need to expand them except perhaps when you might want to "reoptimize" e.g. after many operations. May 16 '20 at 15:07