Reduced row echelon form: Difference between revisions

Content deleted Content added
Line 1,646: Line 1,646:


=={{header|Maxima}}==
=={{header|Maxima}}==
<lang maxima>rref(a):=block([p,q,k],[p,q]:matrix_size(a),a:echelon(a),
<!-- {{improve|Maxima|Add an implementation of reduced row echelon form.}} -->
for i:p thru 2 step -1 do (
if not integerp(k:for j thru q do
if a[i,j]#0 then return(j)) then return(),
for j from i-1 thru 1 step -1 do a:rowop(a,j,i,a[j,k])),
a)$


m:matrix([1,2,-1,-4],[2,3,-1,-11],[-2,0,-3,22]);
Maxima does not have a built-in function for reduced row echelon form, only echelon form.
rref(m);

<lang maxima>(%i28) echelon(matrix([ 1, 2, -1, -4],
matrix([1,0,0,-8],[0,1,0,1],[0,0,1,-2])</lang>
[ 2, 3, -1, -11],
[-2, 0, -3, 22]));
(%o28) matrix([1,0,3/2,-11],[0,1,-4/3,11/3],[0,0,1,-2])</lang>

However, rref can be programmed as a Maxima batch file<ref>a version of rref by Antoine Chambert-Loir/France, taken from [http://www.ma.utexas.edu/pipermail/maxima/2007/008246.html UT Math: Maxima Mailing List]</ref>:

<lang maxima>request_rational_matrix(m, pos, fn) :=
if every('identity, map(lambda([s], every('ratnump,s)), args(m))) then true else
print("Some entries in the matrix are not rational numbers. The result might be wrong.");

rowswap(m,i,j) := block([n, p, r],
require_matrix(m, "first", "rowswap"),
require_integer(i, "second", "rowswap"),
require_integer(j, "third", "rowswap"),
n : length(m),
if (i < 1) or (i > n) or (j < 1) or (j > n)
then error("Array index out of bounds"),
p : copymatrix(m),
r : p[i],
p[i] : p[j],
p[j] : r,
p);

addrow(m,i,j,k) := block([n,p],
require_matrix(m, "first", "addrow"),
require_integer(i, "second", "addrow"),
require_integer(j, "third", "addrow"),
require_rational(k, "fourth", "addrow"),
n : length(m),
if (i < 1) or (i > n) or (j < 1) or (j > n)
then error("Array index out of bounds"),
p : copymatrix(m),
p [i] : p[i] + k * p[j],
p);

rowmul(m,i,k) := block([n,p],
require_matrix(m, "first", "addrow"),
require_integer(i, "second", "addrow"),
require_rational(k, "fourth", "addrow"),
n : length(m),
if (i < 1) or (i > n) then error("Array index out of bounds"),
p : copymatrix(m),
p [i] : k * p[i],
p);


rref(m):= block([p,nr,nc,i,j,k,pivot,pivot_row,debug],
debug : 0,
request_rational_matrix(m," ","rref"),
nc: length(first(m)),
nr: length(m),
if nc = 0 or nr = 0 then
error ("The argument to 'rref' must be a matrix with one or more rows and columns"),

p:copymatrix(m),
ci : 1, cj : 1,
while (ci<=nr) and (cj<=nc) do
(
if (debug = 1) then (
disp(p),
print("curseur en ligne ",ci," et colonne ",cj)),
pivot_row : 0, pivot : 0,
for k : ci thru nr do (
if ( abs(p[k,cj]) > pivot ) then (
pivot_row : k,
pivot : abs(p[k,cj]))),
if (debug = 1) then
print("colonne ",cj," : pivot trouve ligne ", pivot_row,", valeur : ",pivot),
if (pivot = 0) then (cj : cj +1)
else (
p : rowswap(p,ci,pivot_row),
if (debug = 1) then print (".. Echange : ",p),
p : rowmul(p,ci,1/p[ci,cj]),
if (debug = 1) then print (".. Normalisation : ",p),
for k : 1 thru nr do (
if not (k=ci) then (p : addrow (p,k,ci,-p[k,cj]))),
ci : ci+1, cj : cj+1)),
p
);</lang>

If this Maxima batch file is placed in one of the paths listed in the variable <code>file_search_maxima</code> under the name <code>rref.mac</code>, then it can be invoked as follows:

<lang maxima>load(rref)$
m:matrix(
[1,2,-1,-4],
[2,3,-1,-11],
[-2,0,-3,22]
);
rref(m);</lang>

yielding the output:
<math>\left[\begin{matrix}1 & 0 & 0 & -8\\ 0 & 1 & 0 & 1\\ 0 & 0 & 1 & -2\end{matrix}\right]</math>
<lang maxima>matrix([1,0,0,-8],[0,1,0,1],[0,0,1,-2]);</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==