0

I have a singular homogeneous linear system of equations, which easily can be solved by applying Solve:

equs = {x2 == z2, x3 == z3, x5 == z5, w2 == y2,
   w4 == y4, w5 == y5, x1 == y1, x4 == y4,
   x3 == y5, w1 == z1, w4 == z4, w5 == z3,
   x1 == z1, x4 == z4, x5 == z5, w1 == y1,
   w3 == y3, w4 == y4, x2 == y2, x5 == y3,
   x4 == y5, w2 == z2, w3 == z5, w5 == z4};

vars = {x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, z1, z2, z3, z4, z5, w1, w2, w3, w4, w5};

Solve[equs, vars]

{{x1 -> w1, x2 -> w2, x3 -> w5, x4 -> w5, x5 -> w3, y1 -> w1, y2 -> w2, y3 -> w3, y4 -> w5, y5 -> w5, z1 -> w1, z2 -> w2, z3 -> w5, z4 -> w5, z5 -> w3, w4 -> w5}}

The problem I have is that "Solve" is a "black box" for me. I would like to know the method applied by "Solve" dealing with the kind of equations given above. Is there any other (more specific) method available in Mathematica to deal with these kind of equations?

whoever
  • 3
  • 1
  • 1
    Welcome to the Mathematica Stack Exchange. If WRI wanted to share operational details of a certain functionality they would have done so. They remain in a uniquely advantageous position to comment further on your query. Since this question requires knowledge that only WRI or a professional consultant can provide, I suspect the question would be closed after enough close votes accrue. – Syed Mar 23 '22 at 12:28
  • Just to compare. Up to infolevel[solve] := 4; solve({w1 = y1, w1 = z1, w2 = y2, w2 = z2, w3 = y3, w3 = z5, w4 = y4, w4 = z4, w5 = y5, w5 = z3, w5 = z4, x1 = y1, x1 = z1, x2 = y2, x2 = z2, x3 = y5, x3 = z3, x4 = y4, x4 = y5, x4 = z4, x5 = y3, x5 = z5}, {w1, w2, w3, w4, w5, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, z1, z2, z3, z4, z5});, Maple uses linear solver to this end. – user64494 Mar 23 '22 at 12:44

1 Answers1

2

You need a null-space solver.

equs = {x2 == z2, x3 == z3, x5 == z5, w2 == y2, w4 == y4, w5 == y5,
        x1 == y1, x4 == y4, x3 == y5, w1 == z1, w4 == z4, w5 == z3,
        x1 == z1, x4 == z4, x5 == z5, w1 == y1, w3 == y3, w4 == y4, 
        x2 == y2, x5 == y3, x4 == y5, w2 == z2, w3 == z5, w5 == z4};

Let's first convert your equations a bit. Convert to a list of terms that must be zero:

zero = equs /. Equal -> Subtract
(*    {x2 - z2, x3 - z3, x5 - z5, w2 - y2, w4 - y4, w5 - y5, x1 - y1,
       x4 - y4, x3 - y5, w1 - z1, w4 - z4, w5 - z3, x1 - z1, x4 - z4,
       x5 - z5, w1 - y1, w3 - y3, w4 - y4, x2 - y2, x5 - y3, x4 - y5,
       w2 - z2, w3 - z5, w5 - z4}                                        *)

Extract the list of variables:

vars = Sort@Variables[Times @@ zero]
(*    {w1, w2, w3, w4, w5, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, z1, z2, z3, z4, z5}    *)

Express the equations as a matrix $M$ that, when multiplied by the list of variables, must give a zero vector:

M = D[zero, {vars}]

$$ \left( \begin{array}{cccccccccccccccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\ \end{array} \right) $$

Now we know that M . vars must give zeros, so vars must be a linear combination of vectors from the null space of M:

nullvecs = NullSpace[M]
(*    {{0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
       {0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0},
       {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0},
       {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}}    *)

So any solution vector that is such a linear combination will satisfy the equations:

sol = {a, b, c, d} . nullvecs
(*    {d, c, a, b, b, d, c, b, b, a, d, c, a, b, b, d, c, b, b, a}    *)

Check:

equs /. Thread[vars -> sol]
(*    {True, True, True, True, True, True, True, True, True, True,
       True, True, True, True, True, True, True, True, True, True,
       True, True, True, True}                                        *)
Roman
  • 47,322
  • 2
  • 55
  • 121
  • Perfect! That is exactly what I wanted :-) – whoever Mar 23 '22 at 16:39
  • A slight improvementM=CoefficientArrays[equs,vars][[2]]//MatrixForm. – user64494 Mar 23 '22 at 18:00
  • I agree with the comment of @Roman regarding MatrixForm. MatrixForm is just a display form and should never be part of a definition. Just as a sidenote: it is easily possible to present the result as a so called "dispatch table" (which is the way "Solve" does present the result): {Table[vars[[i]] -> sol[[i]], {i, 1, Length[sol]}]}. This would be a complete dispatch table while Solve in above case only provides a partial one (together with a corresponding warning: Solve::vars: Equations may not give solutions for all "solve" variables.) – whoever Mar 24 '22 at 06:03
  • @whoever That's exactly what my Thread[vars -> sol] does (but without needing to loop explicitly). – Roman Mar 24 '22 at 06:11