I have a large list of transformation rules that I want to simplify.
I find Experimental`OptimizeExpression
works as it gets me the answers.
My question is:
I can only get this to work when I convert my list of rules into a list of assignments - which is obviously what i want to avoid doing - by using
list1 /.Rule -> Set
How can I avoid making the assignments and still useExperimental`OptimizeExpression
?
Please note:
I have a solution that gives me the outcome, I want to avoid the side effect of the assignments. Whilst alternative solutions are appreciated, the real issue I have is the side effect that assigns values to the symbols in the rule sets!
I apologise for my incompetence making this clear.
For example
list1 = {a -> b + c, d -> b + c};
list2 = {b -> 1, c -> 1};
Experimental`OptimizeExpression[{list1 /. Rule -> Set, list2 /. Rule -> Set}];
%[[1, 2]]
(* Out= {{2, 2}, {1, 1}} *)
This does indeed simplify my list of transformation rules, however the assignment has some drawbacks as my rules are now evaluating, which I clearly do not want. I am creating OwnValues for each individual transformation rule, effectively disabling the transformation rules.
list1
list2
(* Out= {2 -> 2, 2 -> 2} *)
(* Out= {1 -> 1, 1 -> 1} *)
PLEASE NOTE THE DESIRED RESULT SHOULD BE
(* Out= {a -> b + c, d -> b + c} *)
(* Out= {b -> 1, c -> 1}; *)
I can clear the assignments, and then all works fine, but there must be a more elegant solution.
Clear[a, b, c, d]
list1
list2
(* Out= {a -> b + c, d -> b + c} *)
(* Out= {b -> 1, c -> 1} *)
Now there have kindly been several alternative solutions for the above example provided and I have tried a lot myself as well, however I cannot get any of them to work with the full set of lists which is more complex (and imported from another application so it looks a bit messy):
lists = {v[4] -> v[22], v[6] -> v[16], v[15] -> v[17], v[31] -> v[22]*v[39],
v[32] -> v[75], v[33] -> v[22], v[35] -> v[21], v[41] -> v[22] + v[26] - v[63],
v[45] -> v[23], v[51] -> v[22], v[2] -> 0.25, v[3] -> 14, v[17] -> 100000000,
v[20] -> 5, v[22] -> 2000000000000, v[23] -> 1, v[18] -> 400000000000,
v[19] -> 200000000000, v[24] -> 0.5, v[27] -> 0.7, v[29] -> -1, v[34] -> 0.03,
v[36] -> 0.05, v[37] -> 333, v[38] -> 222, v[39] -> 0.3, v[46] -> 0.01,
v[47] -> 1000, v[52] -> 0.0175, v[53] -> 0, v[54] -> 0, v[55] -> 0, v[56] -> 0,
v[57] -> 0, v[58] -> 0, v[59] -> 0, v[60] -> 1, v[61] -> 0, v[64] -> 3,
v[65] -> 0.4, v[67] -> 0.0625, v[66] -> 0.4, v[68] -> 0.25, v[69] -> 0.25,
v[71] -> 2.5, v[73] -> 0.5, v[70] -> 2.5, v[72] -> 4, v[74] -> 0.0625,
v[1] -> v[6]/v[3] + v[7] + v[14] + v[25] + (-v[6] + v[11])/v[64],
v[7] -> v[5]*v[41], v[8] -> v[18]*v[43]*v[55], v[9] -> v[19]*v[43]*v[56],
v[10] -> v[26] + (1 - v[24])*v[44] + v[24]*v[51] - v[63],
v[11] -> (v[2]*v[33])/(v[3]^(-1) + v[30]), v[12] -> ((1 - v[2])*v[51])/v[50],
v[13] -> v[33] v[39], v[14] -> (v[13] - v[31])/v[66], v[25] -> v[8] + v[18],
v[26] -> v[9] + v[19], v[28] -> v[36],
v[30] -> v[
34]/((v[4]/v[22])^(v[27]/v[29]) ((v[22]*v[45])/(v[20]*v[35]))^v[29]^(-1)),
v[40] -> (v[18] + v[19])/v[22],
v[42] -> -(v[6]/v[3]) + (1 - v[24])*v[44] + v[24]*v[51],
v[43] -> v[32] - v[36] + ((-v[12] + v[15])*v[59])/(v[15] v[65]),
v[44] -> (v[6]/v[16])^v[2] (v[15]/v[17])^(1 - v[2])*v[22],
v[48] -> (v[12] - v[15])/(v[15]*v[65]),
v[49] -> -(v[6]/v[3]) - v[7] - v[25] + (1 - v[24])*v[44] +
v[24] v[51] - (-v[6] + v[11])/v[64], v[62] -> v[21] (1 + v[43] v[58]),
v[63] -> (v[18] + v[19]) (1 - v[60]) +
v[40]*((1 - v[24])*v[44] + v[24]*v[51]) v[60],
v[75] -> ((-v[15] + v[17]/(1 - v[36])) (1 - v[36]))/v[17],
v[5] -> (-(v[6]/v[3]) + v[41])/v[41], v[16] -> (v[2]*v[22])/(v[3]^(-1) + v[34]),
v[21] -> (v[22]*v[23])/v[20], v[50] -> ((1 - v[2])*v[22])/v[17]};
Daniel Lichtblau's suggestion was:
polys = lists /. Rule -> Subtract;
vars = Cases[lists, _Symbol, Infinity] // Union;
gb = GroebnerBasis[polys, vars];
reds = PolynomialReduce[vars, gb, vars][[All, 2]];
Thread[vars->reds]
(* Out = {v[1] -> 0., v[2] -> 0., v[3] -> 0., v[4] -> 0., v[5] -> 0., v[6] -> 0., v[7] -> 0., v[8] -> 0., v[9] -> 0., v[10] -> 0., v[11] -> 0., v[12] -> 0., v[13] -> 0., v[14] -> 0., v[15] -> 0., ...*)
I am most likely missing the point (Groebnerbasis[]
are not something I am familiar with) but this is not the desired result.
Te compare with an approach using Experimental`OptimizeExpression, this provides the expected outcome, but I assign values to symbols to make it work (undesirable):
blocks = lists;
Block[{blocks2 = blocks /. Rule -> Set},
res=Experimental`OptimizeExpression[blocks2]];
res[[1]]
(* Out = {2000000000000, 4.92958*10^12, 100000000, 6.*10^11, 0.05, 2000000000000, 400000000000, 1.6*10^12, 1, 2000000000000, 0.25, 14, 100000000, 5, 2000000000000, ...} *)
And the illustration how the assignments make the symbols in the original rules evaluate, thereby making the transformation list useless:
Thread[vars->res[[1]]]
(* Out = {2000000000000 -> 2000000000000, 4.92958*10^12 -> 4.92958*10^12, 100000000 -> 100000000, 6.*10^11 -> 6.*10^11, 0.05 -> 0.05...} *)
Without having to resort to assigning via /.Rule->Set
I would have gotten the correct answer:
(* Out = {v[1] -> 2000000000000, v[2] -> 4.92958*10^12, v[3] -> 100000000, v[4] -> 6.*10^11, v[5] -> 0.05, v[6] -> 2000000000000, v[7] -> 400000000000, v[8] -> 1.6*10^12, v[9] -> 1, ...} *)
lhs==rhs
but you useSet
(=
, only one=
) which is the assignment operator. I'm pretty sure that you don't want this in the first place. $\endgroup$Experimental`OptimizeExpression
does not require "a list of assignments" even if that is what your code produced, which as halirutan explains it does not. Give an example of the simplified rules that you expect as output or this question cannot be answered. $\endgroup$