Since the final polynomial obtained by @acer compares favorably under various metrics to the one produced by you by hand, produced by me by hand, and produced by codegen:-optimize(..., tryhard) (which are all the same polynomial except for slight differences in the order that the variables appear), one may wonder why optimize didn't return it. There are various metrics in use in this thread. I'd guess that the two primary ones actually used for optimization (rather than just being measured for curiosity) are
- Length: essentially order isomorphic to the number of characters in a displayed form of the polynomial. Good and essentially order-isomorphic approximations to this can be obtained by the commands length (built-in and extremely fast) and `simplify/size/size`, used by the important optimizing command simplify(..., size). The exact number of characters is returned by (length@String), which could also be used as a metric, but isn't used by any of the methods discussed so far in this thread.
- Operation count (which I'll abbreviate as opcount): A count of the number of basic computational operations (mostly arithmetic and assignment) that are needed to evaluate the expression to a (one-word) number when the variables are given (one-word) numeric values. This is the metric more closely related to computational efficiency and the one used by codegen:-optimize(..., tryhard). It allows for the use of intermediary variables (used for repeated subexpressions). This metric can be obtained (exactly) by codegen:-cost.
You may have noticed from my Answer that I used these steps:
- Extract the variables from the expression ex by using indets;
- Convert ex to a procedure by using unapply;
- Put that procedure through optimize, which returns a new-and-improved procedure;
- Apply that new procedure to the original symbolic (i.e., non-numeric) variables.
I used step 4 in case you were truly interested in the displayed length of the expression; however, for those interested in computational efficiency (as measured by opcount), step 4 is a very bad idea. Here is (essentially) the optimized procedure returned by optimize. Since it uses meaningless names for the intermediary variables, I changed them to meaningful ones; and I used modern sleek syntax (which requires 1D input):
new_ex:= (G1, G2, G3, G4, G5, G6, G7, G8, P2, P3, P5, P6)->
local G458:= G4 + G5 + G8, G34578:= G3 + G458 + G7;
G34578*P2 + (G1 + G34578)*P5 + (P3 + P6)*(G1 + G2 + G458 + G6)
You can easily obtain the opcount by eye---11 additions, 2 multiplications, 2 assignments, 2 (local) storage---which is also what codegen:-cost(new_ex) will say. This is significantly better than if step 4 is used, that result having 17 additions and 3 multiplications.