Skip to main content

equation solving - Solve answer optimization


I have an equation system (here is the simplified version for illustration)


    eq = Thread[
Equal[{a[

0]^2 (a[47]^2 (2 - 2 u[2] - 2 u[5] + 6 u[7] - 2 u[9] +
6 u[10] - 2 u[11] + 6 u[13] - 2 u[15] - 2 u[17]) +
a[49]^2 (2 - 2 u[2] - 2 u[5] + 6 u[7] - 2 u[9] + 6 u[10] -
2 u[11] + 6 u[13] - 2 u[15] - 2 u[17]) +
a[52]^2 (2 - 2 u[2] - 2 u[5] + 6 u[7] - 2 u[9] + 6 u[10] -
2 u[11] + 6 u[13] - 2 u[15] - 2 u[17])) +
a[47]^2 (a[
49]^2 (2 + 2 u[1] - 2 u[2] + 2 u[3] - 6 u[4] + 6 u[5] -
6 u[6] - 2 u[7] + 2 u[8] - 2 u[9] + 6 u[10] - 2 u[11] +
2 u[12] - 2 u[13] - 6 u[14] + 6 u[15] + 2 u[16] -

2 u[17] + 2 u[18] - 6 u[19]) +
a[52]^2 (2 + 2 u[1] - 2 u[2] + 2 u[3] - 6 u[4] + 6 u[5] -
6 u[6] - 2 u[7] + 2 u[8] - 2 u[9] + 6 u[10] - 2 u[11] +
2 u[12] - 2 u[13] - 6 u[14] + 6 u[15] + 2 u[16] -
2 u[17] + 2 u[18] - 6 u[19])) +
a[0] a[47] a[49] a[
52] (8 - 12 u[1] + 12 u[3] + 12 u[4] - 12 u[6] + 12 u[8] -
24 u[9] + 24 u[10] + 24 u[11] - 12 u[12] + 12 u[14] -
12 u[16] + 12 u[18] - 12 u[19]) +
a[49]^2 a[

52]^2 (2 + 2 u[1] - 2 u[2] + 2 u[3] - 6 u[4] + 6 u[5] -
6 u[6] - 2 u[7] + 2 u[8] - 2 u[9] + 6 u[10] - 2 u[11] +
2 u[12] - 2 u[13] - 6 u[14] + 6 u[15] + 2 u[16] - 2 u[17] +
2 u[18] - 6 u[19]) +
a[47]^4 (-1 - u[1] + u[2] - u[3] - u[4] + u[5] - u[6] + u[7] -
u[8] + u[9] + u[10] + u[11] - u[12] + u[13] - u[14] + u[15] -
u[16] + u[17] - u[18] - u[19]) +
a[49]^4 (-1 - u[1] + u[2] - u[3] - u[4] + u[5] - u[6] + u[7] -
u[8] + u[9] + u[10] + u[11] - u[12] + u[13] - u[14] + u[15] -
u[16] + u[17] - u[18] - u[19]) +

a[52]^4 (-1 - u[1] + u[2] - u[3] - u[4] + u[5] - u[6] + u[7] -
u[8] + u[9] + u[10] + u[11] - u[12] + u[13] - u[14] + u[15] -
u[16] + u[17] - u[18] - u[19]) +
a[0]^4 (-1 + u[1] + u[2] + u[3] + u[4] + u[5] + u[6] + u[7] +
u[8] + u[9] + u[10] + u[11] + u[12] + u[13] + u[14] + u[15] +
u[16] + u[17] + u[18] + u[19]),
a[0]^2 a[49] a[
52] (-8 u[1] + 4 u[2] + 8 u[3] + 12 u[4] - 4 u[6] - 4 u[7] -
4 u[9] + 8 u[11] - 4 u[12] - 8 u[13] + 4 u[15] + 4 u[16] +
4 u[18]) +

a[0]^3 a[
47] (2 u[1] - 2 u[3] - 2 u[4] + 2 u[6] + 4 u[7] + 2 u[8] +
4 u[10] + 2 u[12] + 4 u[13] + 2 u[14] - 2 u[16] + 2 u[18] -
2 u[19]) +
a[49]^3 a[
52] (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] - 4 u[15] +
4 u[19]) +
a[49] a[52]^3 (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] -
4 u[15] + 4 u[19]) +
a[47]^2 a[49] a[

52] (4 u[1] - 4 u[2] + 4 u[3] - 4 u[7] + 4 u[8] - 4 u[9] +
8 u[11] - 8 u[12] + 8 u[13] + 12 u[14] - 12 u[15] -
8 u[16] + 8 u[17] - 8 u[18] + 12 u[19]) +
a[0] (a[47]^3 (-2 u[1] + 2 u[3] + 2 u[4] - 2 u[6] + 4 u[7] -
2 u[8] + 4 u[10] - 2 u[12] + 4 u[13] - 2 u[14] +
2 u[16] - 2 u[18] + 2 u[19]) +
a[47] (a[
49]^2 (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] -
2 u[6] - 2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] +
4 u[13] - 6 u[14] + 6 u[16] - 6 u[18] + 6 u[19]) +

a[52]^2 (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] -
2 u[6] - 2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] + 4 u[13]
- 6 u[14] + 6 u[16] - 6 u[18] + 6 u[19]))),
a[0]^2 a[47] a[
52] (-8 u[1] + 4 u[2] + 8 u[3] + 12 u[4] - 4 u[6] - 4 u[7] -
4 u[9] + 8 u[11] - 4 u[12] - 8 u[13] + 4 u[15] + 4 u[16] +
4 u[18]) +
a[0]^3 a[
49] (2 u[1] - 2 u[3] - 2 u[4] + 2 u[6] + 4 u[7] + 2 u[8] +
4 u[10] + 2 u[12] + 4 u[13] + 2 u[14] - 2 u[16] + 2 u[18] -

2 u[19]) +
a[47]^3 a[
52] (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] - 4 u[15] +
4 u[19]) +
a[47] a[52]^3 (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] -
4 u[15] + 4 u[19]) +
a[47] a[49]^2 a[
52] (4 u[1] - 4 u[2] + 4 u[3] - 4 u[7] + 4 u[8] - 4 u[9] +
8 u[11] - 8 u[12] + 8 u[13] + 12 u[14] - 12 u[15] -
8 u[16] + 8 u[17] - 8 u[18] + 12 u[19]) +

a[0] (a[49]^3 (-2 u[1] + 2 u[3] + 2 u[4] - 2 u[6] + 4 u[7] -
2 u[8] + 4 u[10] - 2 u[12] + 4 u[13] - 2 u[14] +
2 u[16] - 2 u[18] + 2 u[19]) +
a[49] (a[
47]^2 (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] -
2 u[6] - 2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] +
4 u[13] - 6 u[14] + 6 u[16] - 6 u[18] + 6 u[19]) +
a[52]^2 (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] -
2 u[6] - 2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] +
4 u[13] - 6 u[14] + 6 u[16] - 6 u[18] + 6 u[19]))),

a[0]^2 a[47] a[
49] (-8 u[1] + 4 u[2] + 8 u[3] + 12 u[4] - 4 u[6] - 4 u[7] -
4 u[9] + 8 u[11] - 4 u[12] - 8 u[13] + 4 u[15] + 4 u[16] +
4 u[18]) +
a[0]^3 a[
52] (2 u[1] - 2 u[3] - 2 u[4] + 2 u[6] + 4 u[7] + 2 u[8] +
4 u[10] + 2 u[12] + 4 u[13] + 2 u[14] - 2 u[16] + 2 u[18] -
2 u[19]) +
a[47]^3 a[
49] (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] - 4 u[15] +

4 u[19]) +
a[0] (a[52]^3 (-2 u[1] + 2 u[3] + 2 u[4] - 2 u[6] + 4 u[7] -
2 u[8] + 4 u[10] - 2 u[12] + 4 u[13] - 2 u[14] +
2 u[16] - 2 u[18] + 2 u[19]) +
a[47]^2 a[
52] (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] - 2 u[6] -
2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] + 4 u[13] - 6 u[14] +
6 u[16] - 6 u[18] + 6 u[19]) +
a[49]^2 a[
52] (6 u[1] - 4 u[2] + 2 u[3] - 6 u[4] + 4 u[5] - 2 u[6] -

2 u[8] + 4 u[9] - 8 u[11] + 2 u[12] + 4 u[13] - 6 u[14] +
6 u[16] - 6 u[18] + 6 u[19])) +
a[47] (a[
49]^3 (4 u[4] - 4 u[5] + 4 u[6] - 4 u[10] + 4 u[14] -
4 u[15] + 4 u[19]) +
a[49] a[52]^2 (4 u[1] - 4 u[2] + 4 u[3] - 4 u[7] + 4 u[8] -
4 u[9] + 8 u[11] - 8 u[12] + 8 u[13] + 12 u[14] -
12 u[15] - 8 u[16] + 8 u[17] - 8 u[18] + 12 u[19]))}, 0]];

I want to solve them for any parameters a[_]. For this simple equation the answer is



SolveAlways[eq, {a[0], a[47], a[49], a[52]}]

Out[2]= {{u[2] -> -u[4] - u[6] - u[8] - 2 u[12] + 2 u[13] - 2 u[15] - u[16] + u[17] - 3 u[18] + 2 u[19],


u[5] -> u[4] + u[6] - u[10] + u[14] - u[15] + u[19],


u[7] -> -u[10] - u[13],


u[9] -> 2/3 + u[8] + u[10] + u[12] - u[13] + u[15] - u[17] + 2 u[18] - 2 u[19],


u[11] -> 1/3 + u[12] - u[13] - u[14] + u[15] + u[16] - u[17] + u[18] - u[19],


u[1] -> -u[6] - u[8] - u[12] - u[14] - u[18],


u[3] -> -u[4] - u[16] - u[19]}}


So, I have 7 solution, from which only two of them have free constants 1/3 and 2/3. All other u[_], I can take zeros, so my simple answer is just u[9]->2/3 && u[11]->1/3



Unfortunately I need to solve much large system, which contains more that 7000 u[], and SolveAlways[ ] simply cannot do that. Fortunately, I can use linearity in u[] and avoid SolveAlways[] completely using simple variable replacement


eqToUspace = (eq /. {y_Plus?(FreeQ[#, a[_]] &) :> uSpace[y]});
(toReplace = Union[Cases[eqToUspace, _uSpace, Infinity]]);
newvarsList = Table[ur[i], {i, Length[toReplace]}];
uReplRules = Thread[Rule[toReplace, newvarsList]];

Which yields the system


simpleEq = eqToUspace /. uReplRules

Out[2]= {a[0]^2 (a[47]^2 ur[1] + a[49]^2 ur[1] + a[52]^2 ur[1]) + a[0] a[47] a[49] a[52] ur[3] + a[49]^2 a[52]^2 ur[4] + a[47]^2 (a[49]^2 ur[4] + a[52]^2 ur[4]) + a[47]^4 ur[6] + a[49]^4 ur[6] + a[52]^4 ur[6] + a[0]^4 ur[7] == 0, a[0]^2 a[49] a[52] ur[2] + a[0]^3 a[47] ur[5] + a[49]^3 a[52] ur[9] + a[49] a[52]^3 ur[9] + a[0] (a[47]^3 ur[8] + a[47] (a[49]^2 ur[10] + a[52]^2 ur[10])) + a[47]^2 a[49] a[52] ur[11] == 0, a[0]^2 a[47] a[52] ur[2] + a[0]^3 a[49] ur[5] + a[47]^3 a[52] ur[9] + a[47] a[52]^3 ur[9] + a[0] (a[49]^3 ur[8] + a[49] (a[47]^2 ur[10] + a[52]^2 ur[10])) + a[47] a[49]^2 a[52] ur[11] == 0, a[0]^2 a[47] a[49] ur[2] + a[0]^3 a[52] ur[5] + a[47]^3 a[49] ur[9] + a[0] (a[52]^3 ur[8] + a[47]^2 a[52] ur[10] + a[49]^2 a[52] ur[10]) + a[47] (a[49]^3 ur[9] + a[49] a[52]^2 ur[11]) == 0}



Solution of which (can be tested by SolveAlways[] as well) is just zeroes: {{ur[1] -> 0, ur[2] -> 0, ur[3] -> 0, ur[4] -> 0, ur[5] -> 0, ur[6] -> 0, ur[7] -> 0, ur[8] -> 0, ur[9] -> 0, ur[10] -> 0, ur[11] -> 0}}


After back substitution of old variables I can then solve the new system


unOptimized = 
Solve[Thread[Equal[toReplace /. {uSpace -> Identity}, 0]],
Cases[toReplace, _u, Infinity]]

During evaluation of In[]:= Solve::svars: Equations may not give solutions for all "solve" variables. >>


Out[167]= {{u[13] -> -u[7] - u[10], u[17] -> 1 - u[2] - u[5] - u[9] - u[11] - u[15], u[12] -> 1/3 - u[1] + u[3] + u[4] - u[6] - u[9] + u[10] + u[11], u[18] -> 1/3 + u[1] - u[2] - u[3] - 2 u[4] - u[7] - u[10] - u[11] - u[15] - u[16], u[8] -> -(2/3) - u[1] + u[2] - u[3] + u[4] - u[5] + u[6] + u[7] + u[9] - u[10], u[14] -> u[3] + u[5] - u[6] + u[10] + u[15] + u[16], u[19] -> -u[3] - u[4] - u[16]}}


It contains same number of solutions. The only problem is that it is unoptimal in the sense that instead of just 2 free constants I have 4. Of course this is related to which u[_] Solve decides to solve first.


My question is how to find optimal solution of the reformulated problem with smallest number of constant terms (i.e. which have no u[_]). I even cannot identify the type of problem here.




Answer



Here a way, may be not to reduce calculation time, but to reduce memory usage with large systems.


First define all possible parameter combinations of the a[i] and then find the corresponding equations for the u[i]. In order to be valid for all a[i], these equations have all to equal zero.


paracomb = (Outer[
Times, {a[0], a[47], a[49], a[52]}, {a[0], a[47], a[49],
a[52]}, {a[0], a[47], a[49], a[52]}, {a[0], a[47], a[49],
a[52]}] // Flatten // Union)

(* {a[0]^4, a[0]^3 a[47], a[0]^2 a[47]^2, a[0] a[47]^3, a[47]^4,
a[0]^3 a[49], a[0]^2 a[47] a[49], a[0] a[47]^2 a[49], a[47]^3 a[49],

a[0]^2 a[49]^2, a[0] a[47] a[49]^2, a[47]^2 a[49]^2, a[0] a[49]^3,
a[47] a[49]^3, a[49]^4, a[0]^3 a[52], a[0]^2 a[47] a[52],
a[0] a[47]^2 a[52], a[47]^3 a[52], a[0]^2 a[49] a[52],
a[0] a[47] a[49] a[52], a[47]^2 a[49] a[52], a[0] a[49]^2 a[52],
a[47] a[49]^2 a[52], a[49]^3 a[52], a[0]^2 a[52]^2,
a[0] a[47] a[52]^2, a[47]^2 a[52]^2, a[0] a[49] a[52]^2,
a[47] a[49] a[52]^2, a[49]^2 a[52]^2, a[0] a[52]^3, a[47] a[52]^3,
a[49] a[52]^3, a[52]^4} *)

coe = Coefficient[eq[[All, 1]], #, 1] & /@ paracomb;


coeu = Union[Flatten[DeleteCases[#, 0] & /@ coe] // Simplify,
SameTest -> (#1 === -#2 || #1 === #2 &)]

(* {-2 (-1 + u[2] + u[5] - 3 u[7] + u[9] - 3 u[10] + u[11] - 3 u[13] +
u[15] + u[17]), -4 (2 u[1] - u[2] - 2 u[3] - 3 u[4] + u[6] +
u[7] + u[9] - 2 u[11] + u[12] + 2 u[13] - u[15] - u[16] - u[18]),
2 (1 + u[1] - u[2] + u[3] - 3 u[4] + 3 u[5] - 3 u[6] - u[7] + u[8] -
u[9] + 3 u[10] - u[11] + u[12] - u[13] - 3 u[14] + 3 u[15] +
u[16] - u[17] + u[18] - 3 u[19]), -1 - u[1] + u[2] - u[3] - u[4] +

u[5] - u[6] + u[7] - u[8] + u[9] + u[10] + u[11] - u[12] + u[13] -
u[14] + u[15] - u[16] + u[17] - u[18] -
u[19], -2 (u[1] - u[3] - u[4] + u[6] - 2 u[7] + u[8] - 2 u[10] +
u[12] - 2 u[13] + u[14] - u[16] + u[18] - u[19]),
2 (u[1] - u[3] - u[4] + u[6] + 2 u[7] + u[8] + 2 u[10] + u[12] +
2 u[13] + u[14] - u[16] + u[18] - u[19]),
4 (u[4] - u[5] + u[6] - u[10] + u[14] - u[15] + u[19]), -1 + u[1] +
u[2] + u[3] + u[4] + u[5] + u[6] + u[7] + u[8] + u[9] + u[10] +
u[11] + u[12] + u[13] + u[14] + u[15] + u[16] + u[17] + u[18] +
u[19], -4 (-2 + 3 u[1] - 3 u[3] - 3 u[4] + 3 u[6] - 3 u[8] +

6 u[9] - 6 u[10] - 6 u[11] + 3 u[12] - 3 u[14] + 3 u[16] -
3 u[18] + 3 u[19]),
2 (3 u[1] - 2 u[2] + u[3] - 3 u[4] + 2 u[5] - u[6] - u[8] + 2 u[9] -
4 u[11] + u[12] + 2 u[13] - 3 u[14] + 3 u[16] - 3 u[18] +
3 u[19]),
4 (u[1] - u[2] + u[3] - u[7] + u[8] - u[9] + 2 u[11] - 2 u[12] +
2 u[13] + 3 u[14] - 3 u[15] - 2 u[16] + 2 u[17] - 2 u[18] +
3 u[19])} *)

SolveAlways with a arbitrary variable r gives you the desired result



SolveAlways[Thread[coeu == 0], r] // Timing

(* {0.015, {{u[2] -> -u[4] - u[6] - u[8] - 2 u[12] + 2 u[13] - 2 u[15] -
u[16] + u[17] - 3 u[18] + 2 u[19],
u[5] -> u[4] + u[6] - u[10] + u[14] - u[15] + u[19],
u[7] -> -u[10] - u[13],
u[9] -> 2/3 + u[8] + u[10] + u[12] - u[13] + u[15] - u[17] +
2 u[18] - 2 u[19],
u[11] ->
1/3 + u[12] - u[13] - u[14] + u[15] + u[16] - u[17] + u[18] -

u[19], u[1] -> -u[6] - u[8] - u[12] - u[14] - u[18],
u[3] -> -u[4] - u[16] - u[19]}}} *)

Despite expectation Solve doesn't give the minimal solution


Solve[Thread[coeu == 0], Array[u, 19]] // Timing

(* {0., {{u[10] -> -(2/3) - u[1] + u[2] - u[3] + u[4] - u[5] + u[6] +
u[7] - u[8] + u[9],
u[12] -> -(1/3) - 2 u[1] + u[2] + 2 u[4] - u[5] + u[7] - u[8] +
u[11], u[13] ->

2/3 + u[1] - u[2] + u[3] - u[4] + u[5] - u[6] - 2 u[7] + u[8] -
u[9], u[16] ->
2/3 + u[1] - u[2] - u[4] - u[7] + u[8] - u[9] + u[14] - u[15],
u[17] -> 1 - u[2] - u[5] - u[9] - u[11] - u[15],
u[18] ->
1/3 + u[1] - u[2] - 2 u[4] + u[5] - u[6] - u[7] - u[11] - u[14],
u[19] -> -(2/3) - u[1] + u[2] - u[3] + u[7] - u[8] + u[9] - u[14] +
u[15]}}} *)

But Solve with reduced variable set does like SolveAlways.



Solve[Thread[coeu == 0], Array[u, 12]] // Timing

Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...

list manipulation - Selecting multiple columns from a matrix?

Sample data: data = { {{2013, 1, 1}, 24.13, 167.67, 231.82}, {{2013, 1, 2}, 32.15, 170.92, 225.99}, {{2013, 1, 3}, 35.43, 172.68, 221.67}, {{2013, 1, 4}, 36.73, 173.05, 218.32}, {{2013, 1, 5}, 58.19, 165.96, 197.05}, {{2013, 1, 6}, 69.99, 163.50, 187.52}, {{2013, 1, 7}, 71.37, 154.21, 175.58}, {{2013, 1, 8}, 72.51, 149.66, 163.25}}; I want a DateListPlot with three graphs, so for a matrix formed by columns 1 and 2, one for columns 1 and 3, and 1 for columns 1 and 4. At the moment I'm using this code: data2 = Transpose[{data[[All, 1]], data[[All, 2]]}]; data3 = Transpose[{data[[All, 1]], data[[All, 3]]}]; data4 = Transpose[{data[[All, 1]], data[[All, 4]]}]; DateListPlot[{data2, data3, data4}, Joined -> True, Filling -> {3 -> {1}}] but I have a hunch that this can be done more efficiently. I don't like the Transpose s in particular. Any ideas? edit (for extra credit) What if I need to multiply the second column by 2, which in my solution is simp...