0
$\begingroup$

I have a system of linear equations (here 9) as below:

$ 2 a_{\{1,2,1,2,2,1,2,1,2,2\}}+2 a_{\{1,1\}}=1, \\ \left(a_{\{1,2,1,2,2,1,2,1,2,2,2\}}+a_{\{1,2,1,2,2,1,2,2,1,2,2\}}\right)+2 a_{\{1,1,2\}}=1, \\ 2 a_{\{1,1,1,2,1,2,2,1,2,1,2,2\}}+2 a_{\{1,1,1,1\}}=2 a_{\{1,1\}}, \\ \left(a_{\{1,2,1,2,2,1,2,1,2,2,2,2\}}+a_{\{1,2,1,2,2,1,2,2,2,1,2,2\}}\right)+2 a_{\{1,1,2,2\}}=1, \\ 2 a_{\{1,2,1,2,2,1,2,2,1,2,2,2\}}+2 a_{\{1,2,1,2\}}=1, \\ \left(a_{\{1,1,1,2,1,2,2,1,2,1,2,2,2\}}+a_{\{1,1,1,2,2,1,2,1,2,2,1,2,2\}}\right)+2 a_{\{1,1,1,1,2\}}=a_{\{1,1\}}+a_{\{1,1,2\}}, \left(a_{\{1,1,2,1,2,1,2,2,1,2,1,2,2\}}+a_{\{1,1,2,1,2,2,1,2,1,2,2,1,2\}}\right)+2 a_{\{1,1,1,1,2\}}=2 a_{\{1,1,2\}}, \left(a_{\{1,2,1,2,2,1,2,1,2,2,2,2,2\}}+a_{\{1,2,1,2,2,1,2,2,2,2,1,2,2\}}\right)+2 a_{\{1,1,2,2,2\}}=1, \\\left(a_{\{1,2,1,2,2,1,2,2,1,2,2,2,2\}}+a_{\{1,2,1,2,2,1,2,2,2,1,2,2,2\}}\right)+2 a_{\{1,2,1,2,2\}}=1 $

and I get solution in Mathematica as below: $\left\{a_{\{1,2,1,2,2,1,2,1,2,2\}}\to \frac{1}{2}-a_{\{1,1\}},a_{\{1,2,1,2,2,1,2,2,1,2,2\}}\to -2 a_{\{1,1,2\}}-a_{\{1,2,1,2,2,1,2,1,2,2,2\}}+1,a_{\{1,1,1,2,1,2,2,1,2,1,2,2\}}\to a_{\{1,1\}}-a_{\{1,1,1,1\}},a_{\{1,2,1,2,2,1,2,2,1,2,2,2\}}\to \frac{1}{2}-a_{\{1,2,1,2\}},a_{\{1,2,1,2,2,1,2,2,2,1,2,2\}}\to -2 a_{\{1,1,2,2\}}-a_{\{1,2,1,2,2,1,2,1,2,2,2,2\}}+1,a_{\{1,1,1,2,2,1,2,1,2,2,1,2,2\}}\to a_{\{1,1\}}+a_{\{1,1,2\}}-2 a_{\{1,1,1,1,2\}}-a_{\{1,1,1,2,1,2,2,1,2,1,2,2,2\}},a_{\{1,1,2,1,2,2,1,2,1,2,2,1,2\}}\to 2 a_{\{1,1,2\}}-2 a_{\{1,1,1,1,2\}}-a_{\{1,1,2,1,2,1,2,2,1,2,1,2,2\}},a_{\{1,2,1,2,2,1,2,2,2,1,2,2,2\}}\to -2 a_{\{1,2,1,2,2\}}-a_{\{1,2,1,2,2,1,2,2,1,2,2,2,2\}}+1,a_{\{1,2,1,2,2,1,2,2,2,2,1,2,2\}}\to -2 a_{\{1,1,2,2,2\}}-a_{\{1,2,1,2,2,1,2,1,2,2,2,2,2\}}+1\right\}$

This takes about 0.08 seconds. I reproduced the same solution in Python using SymPy Solve. It takes about 0.85 seconds.

Why is Mathematica faster than Python and is there a way to improve the timing further?

(** Equivalent forms: trace invariant terms + transpose invariance **)
equivalentForms[nl_]:=If[nl=={},{{}},Join[NestList[RotateLeft,nl,Length[nl]-1],NestList[RotateLeft,Reverse[nl],Length[nl]-1]]];
cForm[nl_]:=First@Sort@equivalentForms[nl];deleteDuplicate[list_]:=DeleteDuplicates[Map[cForm,list]];
bracelets[k_Integer]:=deleteDuplicate@Tuples[{1,2},k];
formal=Subscript[a, #]/.{Subscript[a, {}]->1}&;
process[nl_]:=If[EvenQ[Count[nl,1]],
formal@cForm@Flatten@nl,0];
fh1[1]:={2,1,2,2,1,2,1,2,2};
fh2[1]:={2,2,1,2,1,2,2,1,2};
(** This is the LHS (Left-Hand Side)**)
loopyInteraction[nl_,pos_Integer]:=
If[nl[[pos]]==1,
2*process[nl]+g1( process[Flatten[MapAt[fh1,nl,pos]]]+process[Flatten[MapAt[fh2,nl,pos]]]),
0];
(** This is the RHS (Right-Hand Side)**)
loopyQuad[nl_,pos_Integer]:=
Module[{d=Flatten@DeleteCases[Position[nl,nl[[pos]]],{pos}],td,doubleTr},
If[Length[d] ==0,
0,
If[nl[[pos]]==1,
td=Sort@{pos,#}&/@d;
doubleTr=Map[process,MapAt[Delete[{{1},{-1}}],#,1]&/@(TakeDrop[nl,#]&/@td),{2}];
Total[Times@@@doubleTr]/.{Subscript[a, {}]->1},
0
]
]
];
constr[nl_,pos_Integer]:=loopyInteraction[nl,pos]==loopyQuad[nl,pos];
loop[k_Integer]:=DeleteDuplicates@Flatten@Outer[constr,bracelets[k],Range@k,1];
br=bracelets;
loopAll[k_Integer]:=Flatten[loop/@Range[k]];
brAll[k_Integer]:=formal/@Flatten[br/@Range[k],1];

(** Max degree and run **)
kmax=5;
MatrixForm[DeleteCases[loopAll[kmax](*/.g1\[Rule]1*)/.Subscript[a, {2}]->1/.Subscript[a, {2,2}]->1/.Subscript[a, {2,2,2}]->1/.Subscript[a, {2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2}]->1,True],TableAlignments->Left]; 

loopsNumeric[k_Integer,g_]:=loopAll[k]/.g1->g/.Subscript[a, {2}]->1/.Subscript[a, {2,2}]->1/.Subscript[a, {2,2,2}]->1/.Subscript[a, {2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2,2,2,2}]->1/.Subscript[a, {2,2,2,2,2,2,2,2,2,2}]->1;

sol10=Flatten@Solve[loopsNumeric[5,1]] (* Timing :~ 0.08 sec *) 
$\endgroup$
4
  • 1
    $\begingroup$ Please provide the code. $\endgroup$
    – C. E.
    Sep 20, 2020 at 11:23
  • $\begingroup$ This site is Mathematica specific. A comparison with the package SymPy in Python seems pointless, since that will surely depend on the versions. $\endgroup$ Sep 20, 2020 at 11:27
  • $\begingroup$ @C.E.: I have added the code to the main body of the question. Thanks. $\endgroup$
    – R.G.J
    Sep 21, 2020 at 10:11
  • $\begingroup$ An explanation of why the subscripts are important (i.e. more context) or dropping them for a shorter "minimal working example" may help. $\endgroup$
    – Sterling
    Sep 21, 2020 at 12:10

1 Answer 1

1
$\begingroup$

It may come as no surprise to many that Mathematica (excels in symbolic computation) is faster and more versatile than symbolic solvers in other languages (MATLAB, Python, etc.).

If you're interested in calling Mathematica code from Python, see

If you're looking to speed up the Mathematica code, it's unlikely you're going to get something faster than Solve[] in my opinion. It's not clear to me what your "loops" are doing, but is there a reason the elements of your list need separate calls to Solve? If so, that's probably as fast as you'll get without e.g. hard-coding the solution.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.