1

Solving the following equations

eq =
{
0 == e["P", {m["f6p", "c"], m["atp", "c"]}, {}, {}]*
 k["1", False] - e["P", {m["f6p", "c"]}, {}, {}]*m["atp", "c"]*
 k["1", True] - 
 e["P", {m["f6p", "c"]}, {}, {}]*k["2", False] + 
 e["P", {}, {}, {}]*m["f6p", "c"]*k["2", True], 
0 == -(e["P", {m["fdp", "c"]}, {}, {}]*m["adp", "c"]*
 k["3", False]) + 
 e["P", {m["fdp", "c"], m["adp", "c"]}, {}, {}]*
 k["3", True] + 
 e["P", {}, {}, {}]*m["fdp", "c"]*k["4", False] - 
 e["P", {m["fdp", "c"]}, {}, {}]*k["4", True], 
0 == -(e["P", {m["f6p", "c"], m["atp", "c"]}, {}, {}]*
 k["1", False]) + e["P", {m["f6p", "c"]}, {}, {}]*m["atp", "c"]*
 k["1", True] + 
 e["P", {m["fdp", "c"], m["adp", "c"]}, {}, {}]*k["5", False] - 
 e["P", {m["f6p", "c"], m["atp", "c"]}, {}, {}]*k["5", True], 
0 == e["P", {m["fdp", "c"]}, {}, {}]*m["adp", "c"]*
 k["3", False] - e["P", {m["fdp", "c"], m["adp", "c"]}, {}, {}]*
 k["3", True] - 
 e["P", {m["fdp", "c"], m["adp", "c"]}, {}, {}]*k["5", False] + 
 e["P", {m["f6p", "c"], m["atp", "c"]}, {}, {}]*k["5", True], 
0 == eTotal - e["P", {}, {}, {}] - 
 e["P", {m["f6p", "c"]}, {}, {}] - 
 e["P", {m["fdp", "c"]}, {}, {}] - 
 e["P", {m["f6p", "c"], m["atp", "c"]}, {}, {}] - 
 e["P", {m["fdp", "c"], m["adp", "c"]}, {}, {}]
};

for

vars=
{
 e["P",{},{},{}],
 e["P",{m["f6p","c"]},{},{}],
 e["P",{m["fdp","c"]},{},{}],
 e["P",{m["f6p","c"], m["atp","c"]},{},{}],
 e["P",{m["fdp","c"], m["adp","c"]},{},{}]
};

using Solve, yields two different results (depending on the approach chosen):

(1) Solving 'as is':

sol = Solve[eq, vars][[1]];
sol[[2]] /. {catch_e :> catch, m["adp", "c"] -> 0}

returns

e["P", {m["f6p", "c"]}, {}, {}] -> 0

which is simply wrong. Read Prohibit replacement by ReplaceAll (/.), if you're wondering about

{catch_e :> catch, m["adp", "c"] -> 0}

(2) Anonymize, Solve, Back-translation Anonymizing the whole system (using Unique[]), solving, and back-translating

anon = # -> Unique[] & /@ Cases[eq, (_m | _e | _k), \[Infinity]];
revAnon = Reverse /@ anon;
anonEq = eq /. anon;
anonVars = vars /. anon;
sol2 = Solve[anonEq, anonVars][[1]] /. revAnon;
sol2[[2]] /. {catch_e :> catch, m["adp", "c"] -> 0}

returns something different

e[P,{m[f6p,c]},{},{}]->(eTotal (k[1,False] k[2,True] k[3,True] k[4,True] m[f6p,c]+k[1,False] k[2,True] k[4,True] k[5,False] m[f6p,c]+k[2,True] k[3,True] k[4,True] k[5,True] m[f6p,c]))/(k[1,False] k[2,False] k[3,True] k[4,True]+k[1,False] k[2,False] k[4,True] k[5,False]+k[2,False] k[3,True] k[4,True] k[5,True]+k[1,True] k[3,True] k[4,True] k[5,True] m[atp,c]+k[1,False] k[2,True] k[3,True] k[4,True] m[f6p,c]+k[1,False] k[2,True] k[4,True] k[5,False] m[f6p,c]+k[2,True] k[3,True] k[4,True] k[5,True] m[f6p,c]+k[1,True] k[2,True] k[3,True] k[4,True] m[atp,c] m[f6p,c]+k[1,True] k[2,True] k[4,True] k[5,False] m[atp,c] m[f6p,c]+k[1,True] k[2,True] k[3,True] k[5,True] m[atp,c] m[f6p,c]+k[1,True] k[2,True] k[4,True] k[5,True] m[atp,c] m[f6p,c]+k[1,False] k[2,False] k[3,True] k[4,False] m[fdp,c]+k[1,False] k[2,False] k[4,False] k[5,False] m[fdp,c]+k[2,False] k[3,True] k[4,False] k[5,True] m[fdp,c]+k[1,True] k[3,True] k[4,False] k[5,True] m[atp,c] m[fdp,c])

wich is correct.

I have no clear idea why this is happening, only speculations. Using something else than Symbols as variables must be the problem, as replacing all those complicated expressions by real Symbols makes the difference. Has anyone ever had a problem like this? Using these nested expressions (together with custom notations in the notebook interface) is my way of keeping track of variables and parameters in large problems. It would very frustrating if I had to abandon this habit.

Update: Something I should have done before posting the question (I changed the variable name that contains the solution from the anonymizing approach to sol2 in the problem description):

testRules = # -> RandomReal[] & /@ 
    Union@Cases[{sol[[2, 2]], 
      sol2[[2, 2]]}, (_m | _e | _k), \[Infinity]];
(sol[[2, 2]] /. testRules) == (sol2[[2, 2]] /. testRules)

yields True. So both solutions are actually correct, they are just differently arranged.

Following Mr.Wizard's suggestion/post (using Simplify):

sol[[2, 2]] === sol2[[2, 2]]

yields False, while

Simplify[sol[[2, 2]]] === Simplify[sol2[[2, 2]]]

yields True.

Community
  • 1
  • 1
phantomas1234
  • 470
  • 3
  • 13
  • Do you get the correct answer if you replace just the `String` elements such as "1", "2" etc with their `Integer` equivalents, and `True` and `False` with their `Boole` equivalents? Similarly, do you get the correct answer if you do that, plus changing the arguments to `m` into `Symbols`, i.e. `m[fdp,c]` rather than `m["fdp","c"]`? – Verbeia Nov 16 '11 at 23:49
  • @Verbeia `sol = Solve[eq /. s_String :> ToExpression[s], vars /. s_String :> ToExpression[s]][[1]]; sol[[2]] /. {catch_e :> catch, m[adp, c] -> 0}` still yields the wrong answer. Replacing `True` and `False` with `1` and `0` doesn't help either. – phantomas1234 Nov 17 '11 at 00:14
  • @Mr.Wizard so you say that one has to limit variable declarations to `Symbols`? In that case, shouldn't `Solve` raise at least a warning? – phantomas1234 Nov 17 '11 at 00:17
  • @Mr.Wizard, this works `Solve[{a[1] == b[1] + b[2], a[2] == b[1] - b[2]}, {b[1], b[2]}]`, so why not the more exotic forms used by the OP? – rcollyer Nov 17 '11 at 04:42
  • @rcollyer I guess I was just professing my ignorance. I have seen indexed or subscripted symbols, but not expressions this large. I thought it might be causing a problem, but then I realized it was probably the simpler divide-by-zero. I shall remove my comments above so as not to confuse others. – Mr.Wizard Nov 17 '11 at 04:55
  • @Mr.Wizard, definitely confusing to read at first. – rcollyer Nov 17 '11 at 04:57

1 Answers1

4

If I add Simplify:

sol = Solve[eq, vars][[1]] // Simplify;
sol[[2]] /. {catch_e :> catch, m["adp", "c"] -> 0}

I get:

e["P", {m["f6p", "c"]}, {}, {}] ->
    (eTotal (k["1", False] k["2", 
        True] (k["3", True] k["4", True] + 
         k["4", True] k["5", False]) m["f6p", "c"] + 
      k["2", True] k["3", True] k["4", True] k["5", True] m["f6p", 
        "c"]))/(k["1", True] k["3", True] k["4", True] k["5", True] m[
      "atp", "c"] + 
    k["2", True] k["3", True] k["4", True] k["5", True] m["f6p", 
      "c"] + k["1", True] k["2", True] k["3", True] k["4", True] m[
      "atp", "c"] m["f6p", "c"] + 
    k["1", True] k["2", True] k["4", True] k["5", False] m["atp", 
      "c"] m["f6p", "c"] + 
    k["1", True] k["2", True] k["3", True] k["5", True] m["atp", 
      "c"] m["f6p", "c"] + 
    k["1", True] k["2", True] k["4", True] k["5", True] m["atp", 
      "c"] m["f6p", "c"] + 
    k["1", True] k["3", True] k["4", False] k["5", True] m["atp", 
      "c"] m["fdp", "c"] + 
    k["2", False] k["3", True] k["5", 
      True] (k["4", True] + k["4", False] m["fdp", "c"]) + 
    k["1", False] (k["2", 
         True] (k["3", True] k["4", True] + 
          k["4", True] k["5", False]) m["f6p", "c"] + 
       k["2", False] (k["4", True] k["5", False] + 
          k["4", False] k["5", False] m["fdp", "c"] + 
          k["3", True] (k["4", True] + k["4", False] m["fdp", "c"]))))

How does that look? If I don't use Simplify I get a divide by zero error due to the replacement.

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • I think you're right. The unsimplified answer has m["adb","c"] in the numerator, possibly causing the collapse to zero? – Arnoud Buzing Nov 17 '11 at 00:38
  • @Mr.Wizard After all, it seems that `Solve` can handle arbitrary expressions as variables, it's just confusing that the arrangement of the solution equations seems to non unique. Thank you for bringing up the `Simplify` issue. – phantomas1234 Nov 17 '11 at 17:49