0

I asked a similar question in this post before and understand the reason why RowReduce function can't reduce symbolic matrix.

I wrote an RowReduce function that can handle symbolic matrices:

exchanges[v1_, v2_] := 
 Module[{t}, 
  t = InversePermutation[PermutationList[FindPermutation[v1, v2]]]; 
  If[t != {}, 
   Select[MapIndexed[First[#2] -> #1 &, 
     LinearAlgebra`LAPACK`PermutationToPivot[t]], Apply[Unequal]], {}]]

matrixWrapOperation[mat_, rule_] := Module[{B = mat}, If[rule != {}, Do[B[[{Keys[rule[[n]]], Values[rule[[n]]]}, ;;]] = B[[{Values[rule[[n]]], Keys[rule[[n]]]}, ;;]]; Print["Swap the elements in row", Keys[rule[[n]]], "and row ", Values[rule[[n]]], "->", MatrixForm@B], {n, 1, Length[rule]}]; B, B]]

rref[A_?MatrixQ] := Module[{sysa, sysm, sysn, sysi, sysj, sysk, sysl, sysL, sysB}, {sysm, sysn} = Dimensions[A]; sysB = A; Print[MatrixForm@A];

(Below is the preprocessing sort[DownArrow]) Print["Start preprocessing"]; sysB = matrixWrapOperation[A, exchanges[ A[[;; , 1]], (SortBy[A /. {0 -> Infinity}, First] /. {Infinity -> 0})[[All, 1]]]]; Print["End of preprocessing"]; (The above is the preprocessing sort[UpArrow])

sysi = 1(sysi represents the row number); sysk = 1(sysk represents the column number); While[sysi <= sysm, While[sysk < sysn && sysB[[sysi ;;, sysk]] == ConstantArray[0, sysm - sysi + 1], sysk++; If[sysk == sysn && sysB[[sysi ;;, sysk]] == 0, Return[sysB]; Goto[end]]];

(For[sysl=sysi,sysl[LessEqual]sysm,sysl++,If[(sysa=sysB[[sysl, sysk]])[NotEqual]0&&sysk<sysn&&sysB[[ sysl,(sysk+1);;]][Equal]ConstantArray[0,sysn-sysk],sysB[[sysl, sysk]]=1;Print["Divide all elements in row",sysl," by ",sysa,"->", MatrixForm@sysB];]];)

sysa = DeleteCases[sysB[[sysi ;;, sysk]], 0]; If[Length[sysa] == 0, sysL = 1, sysL = First[sysa]];

sysj = sysi; While[sysj < sysm && sysB[[sysj, sysk]] =!= sysL, sysj++;];

If[sysi != sysj, If[sysB[[sysj, sysk]] =!= 0, sysB[[{sysi, sysj}, ;;]] = sysB[[{sysj, sysi}, ;;]]; Print["Swap the elements in row", sysi, "and row ", sysj, "->", MatrixForm@sysB], Return[sysB]] ];

For[sysl = sysi, sysl <= sysm, sysl++, If[(sysa = sysB[[sysl, sysk]]) =!= 0 && sysl > sysi, sysB[[sysl, ;;]] = sysB[[sysl, ;;]] - sysB[[sysl, sysk]]/sysB[[sysi, sysk]] sysB[[sysi, ;;]];

 Print[&quot;The &quot;, sysl, &quot; row of elements plus &quot;, -(sysa/sysL), 
  &quot; times the &quot;, sysi, &quot; row of elements&quot;, 
  &quot;-&gt; &quot; MatrixForm@sysB]]];

sysi++(Outermost row loop count);]; Label[end];

Return[sysB];]

Examples for testing:

A = RandomInteger[{0, 10}, {4, 4}]; 
rref[A]
rref[{{1, 9, 7, 2}, {0, 2, -(9/2), 
    2}, {0, -(11/2), -(11/2), -t}, 
       {s, 10, 9, 7}, {1, 2, 4, 3}}]

rref[{{8, 0, 0, 1, 3}, {8, 0, 0, 0, 3}, {6, 0, 0, 2, 4}, {7, 0, 0, 8, 9}, {10, 0, 0, 1, 5}}]

rref[{{1, -1, -1}, {2, a, 1}, {-1, 1, a}}]

rref[{{1, -1, -1, 2, 2}, {2, a, 1, 1, a}, {-1, 1, a, -a - 1, -2}}]

But the above code is too cumbersome. Is there a more concise way to realize the function of rref function?

  • 2
    One concise possibility is, well, 'RowReduce'. You should therefore explain why it is not suitable. – Daniel Lichtblau Aug 08 '20 at 16:21
  • 1
    @DanielLichtblau For example: the row simplest form of matrix $\left(\begin{array}{ccc} 1 & a & 2 \ 0 & 1 & 1 \ -1 & 1 & 1 \end{array}\right)$ should be $\left(\begin{array}{ccc} 1 & -1 & -1 \ 0 & 1 & 1 \ 0 & a-2 & 0 \end{array}\right)$ instead of $\left(\begin{array}{lll} 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 \end{array}\right)$. RowReduce[{{1, a, 2}, {0, 1, 1}, {-1, 1, 1}}] rref[{{1, a, 2}, {0, 1, 1}, {-1, 1, 1}}] – A little mouse on the pampas Aug 08 '20 at 22:24
  • 3
    Perhaps the point to emphasize is that RowReduce seems to make the generic assumption that any expression that is not literally zero is nonzero. – Michael E2 Aug 09 '20 at 11:29
  • 1
    @Montevideo Perhaps you should refer to your previous question (https://mathematica.stackexchange.com/q/227929/43522) to clarify the problem. As it stands, this question doesn't explain the problem very well. – Sjoerd Smit Aug 11 '20 at 12:10
  • @SjoerdSmit Thank you very much for your advice. I have updated the question. – A little mouse on the pampas Aug 11 '20 at 22:18
  • 1
    Please stop making many tiny edits to this post. It inappropriately bumps it up the active questions page and generates moderator flags that have to be handled. Thank you. – Mr.Wizard Aug 12 '20 at 13:12
  • @Mr.Wizard Thank you very much for your suggestion. I will hardly edit this post any more. If you have time, I hope you can write a custom function to solve my problem. If you don't have time, it doesn't matter. Have a good weekend. – A little mouse on the pampas Aug 12 '20 at 22:25

1 Answers1

7

Perhaps this, but I'm unsure how safe it is to treat a - 2 as zero:

mat = {{1, a, 2}, {0, 1, 1}, {-1, 1, 1}};
RowReduce[mat,
 ZeroTest -> (Quiet[Length@Solve[# == 0, Reals] > 0] &)]

$$ \left( \begin{array}{ccc} 1 & 0 & 2-a \\ 0 & 1 & 1 \\ 0 & 0 & 2-a \\ \end{array} \right) $$

There's also

UpperTriangularize@First@LUDecomposition@mat

$$ \left( \begin{array}{ccc} 1 & a & 2 \\ 0 & 1 & 1 \\ 0 & 0 & 2-a \\ \end{array} \right) $$

The columns are not reduced. Also, I suspect LUDecomposition would divide by a - 2 if needed.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Thank you very much, but I hope your method can handle the following situation:mat = {{1, -1, -1, 2, 2}, {2, a, 1, 1, a}, {-1, 1, a, -a - 1, -2}}; RowReduce[mat, ZeroTest -> (Quiet[Length@Solve[# == 0, Reals] > 0] &)].
    Reference answer: $\left(\begin{array}{ccccc} 1 & -1 & -1 & 2 & 2 \ 2 & a & 1 & 1 & a \ -1 & 1 & a & -a-1 & -2 \end{array}\right) \rightarrow\left(\begin{array}{ccccc} 1 & -1 & -1 & 2 & 2 \ 0 & a+2 & 3 & -3 & a-4 \ 0 & 0 & a-1 & 1-a & 0 \end{array}\right)$
    – A little mouse on the pampas Aug 10 '20 at 01:23
  • 3
    I hope it can handle it, too, but there are doubts. Nonetheless: Take[UpperTriangularize@First@LUDecomposition@ArrayReshape[mat, {5, 5}], 3] – Michael E2 Aug 10 '20 at 02:06
  • Thank you very much for your reply, your code works very well. – A little mouse on the pampas Aug 10 '20 at 03:26
  • I also have a problem, for the following case, can not be simplified to the simplest form and output error message:Take[UpperTriangularize@ First@LUDecomposition@ ArrayReshape[{{0, 0, c1}, {1, -1, c3}, {-1, 1, c4}}, {3, 3}], 3]. – A little mouse on the pampas Aug 11 '20 at 00:44
  • Thank you very much for your help. If you can, I hope you can write a concise custom function to perfectly deal with the row reduction problem of the symbol matrix. – A little mouse on the pampas Aug 11 '20 at 00:49
  • 1
    @Montevideo I'm not sure exactly what you want. I'm pretty sure the built-in functions as I've shown them, do something close, but not exactly the same. If your requirements differ too greatly or cannot be relaxed, you may have to write your own custom function. I don't have time to do that. I can help show what's done easily, though. For instance, clearing denominators: # * PolynomialLCM @@@ Denominator[#] &@ Take[UpperTriangularize@First@LUDecomposition@ArrayReshape[{{0, 0, c1}, {1, -1, c3}, {-1, 1, c4}}, {3, 3}], 3] – Michael E2 Aug 11 '20 at 15:49
  • Thank you very much. I mean that the reduction result of $\left(\begin{array}{ccc} 0 & 0 & \mathbf{c} 1 \ \mathbf{1} & -1 & \mathbf{c} 3 \ -1 & \mathbf{1} & \mathbf{c} 4 \end{array}\right)$ should be $\left(\begin{array}{ccc} -1 & 1 & c 4 \ 0 & 0 & c 3+c 4 \ 0 & 0 & 0 \end{array}\right)$ rather than $\left(\begin{array}{ccc} 1 & -1 & c 3 \ 0 & 0 & c 1 \ 0 & 0 & c 3+c 4 \end{array}\right)$. The calculation result of LUDecomposition function does not meet the requirements. So I would like to ask you to write a perfect row reduction function. – A little mouse on the pampas Aug 11 '20 at 22:01
  • However, your free time is very limited. I will try to rewrite and improve this custom function first. If I encounter any problems, I will ask for your help. Thank you again. – A little mouse on the pampas Aug 11 '20 at 22:05
  • 1
    @Montevideo The desired (first) result seems wrong if $c3+c4=0$ and $c1\ne0$. My result where they are both in the third column comprises $c3+c4\ne0$ and $c1=0$ and the one just mentioned. It's technically not in row-echelon form when $c1=0$, and it's not reduced if both are nonzero. It sort of in the next-to-last step, still comprising all possibilities and waiting for the values of the $c$'s. At least that's how I understand the problem. The only way to get a completely correct result is by cases (a Piecewise result perhaps). – Michael E2 Aug 11 '20 at 23:03
  • @Montevideo Thanks for the bounty! – Michael E2 Aug 11 '20 at 23:04