Reduced row echelon form: Difference between revisions

m
 
(101 intermediate revisions by 42 users not shown)
Line 1:
 
{{wikipedia|Rref#Pseudocode}}{{task|Matrices}}Show how to compute the '''reduced row echelon form''' (a.k.a. '''row canonical form''') of a matrix. The matrix can be stored in any datatype that is convenient (for most languages, this will probably be a two-dimensional array). Built-in functions or this pseudocode (from Wikipedia) may be used:
{{wikipedia|Rref#Pseudocode}}
{{task|Matrices}}
{{omit from|GUISS}}
 
 
;Task:
Show how to compute the '''reduced row echelon form'''
(a.k.a. '''row canonical form''') of a matrix.
 
The matrix can be stored in any datatype that is convenient
(for most languages, this will probably be a two-dimensional array).
 
Built-in functions or this pseudocode (from Wikipedia) may be used:
'''function''' ToReducedRowEchelonForm(Matrix M) '''is'''
''lead'' := 0
Line 31 ⟶ 44:
 
For testing purposes, the RREF of this matrix:
<pre>1 2 -1 -4
2 1 3 2 -1 -114
- 2 0 3 -31 22</pre>-11
-2 0 -3 22
</pre>
is:
<pre>1 0 0 -8
0 1 1 0 0 1-8
0 0 1 1 0 -2</pre> 1
0 0 1 -2
</pre>
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F ToReducedRowEchelonForm(&M)
V lead = 0
V rowCount = M.len
V columnCount = M[0].len
L(r) 0 .< rowCount
I lead >= columnCount
R
V i = r
L M[i][lead] == 0
i++
I i == rowCount
i = r
lead++
I columnCount == lead
R
swap(&M[i], &M[r])
V lv = M[r][lead]
M[r] = M[r].map(mrx -> mrx / Float(@lv))
L(i) 0 .< rowCount
I i != r
lv = M[i][lead]
M[i] = zip(M[r], M[i]).map((rv, iv) -> iv - @lv * rv)
lead++
 
V mtx = [[ 1.0, 2.0, -1.0, -4.0],
[ 2.0, 3.0, -1.0, -11.0],
[-2.0, 0.0, -3.0, 22.0]]
 
ToReducedRowEchelonForm(&mtx)
 
L(rw) mtx
print(rw.join(‘, ’))</syntaxhighlight>
 
{{out}}
<pre>
1, 0, 0, -8
0, 1, 0, 1
0, 0, 1, -2
</pre>
 
=={{header|360 Assembly}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="360asm">* reduced row echelon form 27/08/2015
RREF CSECT
USING RREF,R12
LR R12,R15
LA R10,1 lead=1
LA R7,1
LOOPR CH R7,NROWS do r=1 to nrows
BH ELOOPR
CH R10,NCOLS if lead>=ncols
BNL ELOOPR
LR R8,R7 i=r
WHILE LR R1,R8 do while m(i,lead)=0
BCTR R1,0
MH R1,NCOLS
LR R6,R10 lead
BCTR R6,0
AR R1,R6
SLA R1,2
L R6,M(R1) m(i,lead)
LTR R6,R6
BNZ EWHILE m(i,lead)<>0
LA R8,1(R8) i=i+1
CH R8,NROWS if i=nrows
BNE EIF
LR R8,R7 i=r
LA R10,1(R10) lead=lead+1
CH R10,NCOLS if lead=ncols
BE ELOOPR
EIF B WHILE
EWHILE LA R9,1
LOOPJ1 CH R9,NCOLS do j=1 to ncols
BH ELOOPJ1
LR R1,R7 r
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
LA R3,M(R1) R3=@m(r,j)
LR R1,R8 i
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
LA R4,M(R1) R4=@m(i,j)
L R2,0(R3)
MVC 0(2,R3),0(R4) swap m(i,j),m(r,j)
ST R2,0(R4)
LA R9,1(R9) j=j+1
B LOOPJ1
ELOOPJ1 LR R1,R7 r
BCTR R1,0
MH R1,NCOLS
LR R6,R10 lead
BCTR R6,0
AR R1,R6
SLA R1,2
L R11,M(R1) n=m(r,lead)
CH R11,=H'1' if n^=1
BE ELOOPJ2
LA R9,1
LOOPJ2 CH R9,NCOLS do j=1 to ncols
BH ELOOPJ2
LR R1,R7 r
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
LA R5,M(R1) R5=@m(i,j)
L R2,0(R5) m(r,j)
LR R1,R11 n
SRDA R2,32
DR R2,R1 m(r,j)/n
ST R3,0(R5) m(r,j)=m(r,j)/n
LA R9,1(R9) j=j+1
B LOOPJ2
ELOOPJ2 LA R8,1
LOOPI3 CH R8,NROWS do i=1 to nrows
BH ELOOPI3
CR R8,R7 if i^=r
BE ELOOPJ3
LR R1,R8 i
BCTR R1,0
MH R1,NCOLS
LR R6,R10 lead
BCTR R6,0
AR R1,R6
SLA R1,2
L R11,M(R1) n=m(i,lead)
LA R9,1
LOOPJ3 CH R9,NCOLS do j=1 to ncols
BH ELOOPJ3
LR R1,R8 i
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
LA R4,M(R1) R4=@m(i,j)
L R5,0(R4) m(i,j)
LR R1,R7 r
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
L R3,M(R1) m(r,j)
MR R2,R11 m(r,j)*n
SR R5,R3 m(i,j)-m(r,j)*n
ST R5,0(R4) m(i,j)=m(i,j)-m(r,j)*n
LA R9,1(R9) j=j+1
B LOOPJ3
ELOOPJ3 LA R8,1(R8) i=i+1
B LOOPI3
ELOOPI3 LA R10,1(R10) lead=lead+1
LA R7,1(R7) r=r+1
B LOOPR
ELOOPR LA R8,1
LOOPI4 CH R8,NROWS do i=1 to nrows
BH ELOOPI4
SR R10,R10 pgi=0
LA R9,1
LOOPJ4 CH R9,NCOLS do j=1 to ncols
BH ELOOPJ4
LR R1,R8 i
BCTR R1,0
MH R1,NCOLS
LR R6,R9 j
BCTR R6,0
AR R1,R6
SLA R1,2
L R6,M(R1) m(i,j)
LA R3,PG
AR R3,R10
XDECO R6,0(R3) edit m(i,j)
LA R10,12(10) pgi=pgi+12
LA R9,1(R9) j=j+1
B LOOPJ4
ELOOPJ4 XPRNT PG,48 print m(i,j)
LA R8,1(R8) i=i+1
B LOOPI4
ELOOPI4 XR R15,R15
BR R14
NROWS DC H'3'
NCOLS DC H'4'
M DC F'1',F'2',F'-1',F'-4'
DC F'2',F'3',F'-1',F'-11'
DC F'-2',F'0',F'-3',F'22'
PG DC CL48' '
YREGS
END RREF</syntaxhighlight>
{{out}}
<pre>
1 0 0 -8
0 1 0 1
0 0 1 -2
</pre>
 
=={{header|ActionScript}}==
_m being of type Vector.<Vector.<Number>> the following function is a method of Matrix class. Therefore return this statements are returning the Matrix object itself.
is a method of Matrix class.
Therefore return this statements are returning the Matrix object itself.
 
<langsyntaxhighlight Actionscriptlang="actionscript">public function RREF():Matrix {
var lead:uint, i:uint, j:uint, r:uint = 0;
 
Line 78 ⟶ 308:
}
return this;
}</langsyntaxhighlight>
 
=={{header|Ada}}==
matrices.ads:
<langsyntaxhighlight Adalang="ada">generic
type Element_Type is private;
Zero : Element_Type;
Line 92 ⟶ 322:
array (Positive range <>, Positive range <>) of Element_Type;
function Reduced_Row_Echelon_form (Source : Matrix) return Matrix;
end Matrices;</langsyntaxhighlight>
 
matrices.adb:
<langsyntaxhighlight Adalang="ada">package body Matrices is
procedure Swap_Rows (From : in out Matrix; First, Second : in Positive) is
Temporary : Element_Type;
Line 165 ⟶ 395:
return Result;
end Reduced_Row_Echelon_form;
end Matrices;</langsyntaxhighlight>
 
Example use: main.adb:
<langsyntaxhighlight Adalang="ada">with Matrices;
with Ada.Text_IO;
procedure Main is
Line 195 ⟶ 425:
Ada.Text_IO.Put_Line ("reduced to:");
Print_Matrix (Reduced);
end Main;</langsyntaxhighlight>
 
{{out}}
Output:
<pre>1.0 2.0 -1.0 -4.0
2.0 3.0 -1.0 -11.0
Line 207 ⟶ 437:
 
=={{header|Aime}}==
<syntaxhighlight lang="aime">rref(list l, integer rows, columns)
<lang aime>void
rref(list l, integer rows, integer columns)
{
integer e, f, i, j, lead, r;
list u, v;
 
lead = r = 0;
while (r < rows && lead < columns) {
r = 0;
while (r < rows) {
if (columns <= lead) {
break;
}
 
i = r;
while (!l_q_integerl.q_list(l_q_list(l, i), [lead)]) {
i += 1;
if (i == rows) {
Line 235 ⟶ 459:
}
 
u = l_q_list(l, [i)];
 
l_spin(l, .spin(i, r);
e = l_q_integer(u, [lead)];
if (e) {
for (j, f in =u) 0;{
while ( u[j] = <f columns)/ {e;
l_r_integer(u, j, l_q_integer(u, j) / e);
j += 1;
}
}
 
for (i, v in =l) 0;{
while (i < rows) {
if (i != r) {
ve = l_q_list(l, i)v[lead];
efor = l_q_integer(vj, leadf in v); {
v[j] = 0f - u[j] * e;
while (j < columns) {
l_r_integer
(v, j, l_q_integer(v, j) - l_q_integer(u, j) * e);
j += 1;
}
}
i += 1;
}
 
Line 268 ⟶ 484:
}
 
display_2(list l)
void
display_2(list l, integer rows, integer columns)
{
integerfor i(, j;list u in l) {
u.ucall(o_winteger, -1, 4);
list u;
 
i = 0;
while (i < rows) {
u = l_q_list(l, i);
j = 0;
while (j < columns) {
o_winteger(4, l_q_integer(u, j));
j += 1;
}
i += 1;
o_byte('\n');
}
}
 
integer
main(void)
{
list l;
 
l = l_effectlist(l_effectlist(1, 2, -1, -4),
l_effectlist(2, 3, -1, -11),
l_effectlist(-2, 0, -3, 22));
rref(l, 3, 4);
display_2(l, 3, 4);
 
return 0;
}</langsyntaxhighlight>
{{Out}}
<pre> 1 0 0 -8
0 1 0 1
0 0 1 -2</pre>
 
=={{header|ALGOL 68}}==
Line 306 ⟶ 514:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards AND formatted transput statements removed) - tested with release 1.8.8d.fc9.i386 - ELLA has not FORMATted transput, also it generates a call to undefined C external }} -->
<langsyntaxhighlight lang="algol68">MODE FIELD = REAL; # FIELD can be REAL, LONG REAL etc, or COMPL, FRAC etc #
MODE VEC = [0]FIELD;
MODE MAT = [0,0]FIELD;
Line 359 ⟶ 567:
mat repr = $"("n(1 UPB mat-1)(f(vec repr)", "lx)f(vec repr)")"$;
 
printf((mat repr, mat, $l$))</langsyntaxhighlight>
{{out}}
Output:
<pre>
(( 1.0000, 0.0000, 0.0000, -8.0000),
( 0.0000, 1.0000, 0.0000, 1.0000),
( 0.0000, 0.0000, 1.0000, -2.0000))
</pre>
 
=={{header|ALGOL W}}==
From the pseudo code.
<syntaxhighlight lang="algolw">begin
% replaces M with it's reduced row echelon form %
% M should have bounds ( 0 :: rMax, 0 :: cMax ) %
procedure toReducedRowEchelonForm ( real array M ( *, * )
; integer value rMax, cMax
) ;
begin
integer lead;
lead := 0;
for r := 0 until rMax do begin
integer i;
if lead > cMax then goto done;
i := r;
while M( i, lead ) = 0 do begin
i := i + 1;
if rMax = i then begin
i := r;
lead := lead + 1;
if cMax = lead then goto done
end if_rowCount_eq_i
end while_M_i_lead_eq_0 ;
% Swap rows i and r %
for c := 0 until cMax do begin
real t;
t := M( i, c );
M( i, c ) := M( r, c );
M( r, c ) := t
end swap_rows_i_and_r ;
If M( r, lead ) not = 0 then begin
% divide row r by M[r, lead] %
real rLead;
rLead := M( r, lead );
for c := 0 until cMax do M( r, c ) := M( r, c ) / rLead
end if_M_r_lead_ne_0 ;
for i := 0 until rMax do begin
if i not = r then begin
% Subtract M[i, lead] multiplied by row r from row i %
real iLead;
iLead := M( i, lead );
for c := 0 until cMax do M( i, c ) := M( i, c ) - ( iLead * M( r, c ) )
end if_i_ne_r
end for_i ;
lead := lead + 1
end for_r ;
done:
end toReducedRowEchelonForm ;
% test the toReducedRowEchelonForm procedure %
begin
real array m( 0 :: 2, 0 :: 3 );
M( 0, 0 ) := 1; M( 0, 1 ) := 2; M( 0, 2 ) := -1; M( 0, 3 ) := -4;
M( 1, 0 ) := 2; M( 1, 1 ) := 3; M( 1, 2 ) := -1; M( 1, 3 ) := -11;
M( 2, 0 ) := -2; M( 2, 1 ) := 0; M( 2, 2 ) := -3; M( 2, 3 ) := 22;
toReducedRowEchelonForm( M, 2, 3 );
r_format := "A"; s_w := 0; r_w := 6; r_d := 1; % set output formating %
for r := 0 until 2 do begin
write( M( r, 0 ) );
for c := 1 until 3 do writeon( " ", M( r, c ) );
end for_r
end
end.</syntaxhighlight>
{{out}}
<pre>
1.0 0.0 0.0 -8.0
0.0 1.0 0.0 1.0
0.0 0.0 1.0 -2.0
</pre>
 
=={{header|ATS}}==
This program was made by modifying [[Gauss-Jordan_matrix_inversion#ATS]]. (The latter program is equivalent to finding the RREF of a particular matrix.)
 
<syntaxhighlight lang="ats">
%{^
#include <math.h>
#include <float.h>
%}
 
#include "share/atspre_staload.hats"
 
macdef NAN = g0f2f ($extval (float, "NAN"))
macdef Zero = g0i2f 0
macdef One = g0i2f 1
macdef Two = g0i2f 2
 
(* The following is often done by a single machine instruction. *)
macdef multiply_and_add (x, y, z) = (,(x) * ,(y)) + ,(z)
 
(*------------------------------------------------------------------*)
(* A "little matrix library" *)
 
typedef Matrix_Index_Map (m1 : int, n1 : int, m0 : int, n0 : int) =
{i1, j1 : pos | i1 <= m1; j1 <= n1}
(int i1, int j1) -<cloref0>
[i0, j0 : pos | i0 <= m0; j0 <= n0]
@(int i0, int j0)
 
datatype Real_Matrix (tk : tkind,
m1 : int, n1 : int,
m0 : int, n0 : int) =
| Real_Matrix of (matrixref (g0float tk, m0, n0),
int m1, int n1, int m0, int n0,
Matrix_Index_Map (m1, n1, m0, n0))
typedef Real_Matrix (tk : tkind, m1 : int, n1 : int) =
[m0, n0 : pos] Real_Matrix (tk, m1, n1, m0, n0)
typedef Real_Vector (tk : tkind, m1 : int, n1 : int) =
[m1 == 1 || n1 == 1] Real_Matrix (tk, m1, n1)
typedef Real_Row (tk : tkind, n1 : int) = Real_Vector (tk, 1, n1)
typedef Real_Column (tk : tkind, m1 : int) = Real_Vector (tk, m1, 1)
 
extern fn {tk : tkind}
Real_Matrix_make_elt :
{m0, n0 : pos}
(int m0, int n0, g0float tk) -< !wrt >
Real_Matrix (tk, m0, n0, m0, n0)
 
extern fn {tk : tkind}
Real_Matrix_copy :
{m1, n1 : pos}
Real_Matrix (tk, m1, n1) -< !refwrt > Real_Matrix (tk, m1, n1)
 
extern fn {tk : tkind}
Real_Matrix_copy_to :
{m1, n1 : pos}
(Real_Matrix (tk, m1, n1), (* destination *)
Real_Matrix (tk, m1, n1)) -< !refwrt >
void
 
extern fn {tk : tkind}
Real_Matrix_fill_with_elt :
{m1, n1 : pos}
(Real_Matrix (tk, m1, n1), g0float tk) -< !refwrt > void
 
extern fn {}
Real_Matrix_dimension :
{tk : tkind}
{m1, n1 : pos}
Real_Matrix (tk, m1, n1) -<> @(int m1, int n1)
 
extern fn {tk : tkind}
Real_Matrix_get_at :
{m1, n1 : pos}
{i1, j1 : pos | i1 <= m1; j1 <= n1}
(Real_Matrix (tk, m1, n1), int i1, int j1) -< !ref > g0float tk
 
extern fn {tk : tkind}
Real_Matrix_set_at :
{m1, n1 : pos}
{i1, j1 : pos | i1 <= m1; j1 <= n1}
(Real_Matrix (tk, m1, n1), int i1, int j1, g0float tk) -< !refwrt >
void
 
extern fn {}
Real_Matrix_apply_index_map :
{tk : tkind}
{m1, n1 : pos}
{m0, n0 : pos}
(Real_Matrix (tk, m0, n0), int m1, int n1,
Matrix_Index_Map (m1, n1, m0, n0)) -<>
Real_Matrix (tk, m1, n1)
 
extern fn {}
Real_Matrix_transpose :
(* This is transposed INDEXING. It does NOT copy the data. *)
{tk : tkind}
{m1, n1 : pos}
{m0, n0 : pos}
Real_Matrix (tk, m1, n1, m0, n0) -<>
Real_Matrix (tk, n1, m1, m0, n0)
 
extern fn {}
Real_Matrix_block :
(* This is block (submatrix) INDEXING. It does NOT copy the data. *)
{tk : tkind}
{p0, p1 : pos | p0 <= p1}
{q0, q1 : pos | q0 <= q1}
{m1, n1 : pos | p1 <= m1; q1 <= n1}
{m0, n0 : pos}
(Real_Matrix (tk, m1, n1, m0, n0),
int p0, int p1, int q0, int q1) -<>
Real_Matrix (tk, p1 - p0 + 1, q1 - q0 + 1, m0, n0)
 
extern fn {tk : tkind}
Real_Matrix_unit_matrix :
{m : pos}
int m -< !refwrt > Real_Matrix (tk, m, m)
 
extern fn {tk : tkind}
Real_Matrix_unit_matrix_to :
{m : pos}
Real_Matrix (tk, m, m) -< !refwrt > void
 
extern fn {tk : tkind}
Real_Matrix_matrix_sum :
{m, n : pos}
(Real_Matrix (tk, m, n), Real_Matrix (tk, m, n)) -< !refwrt >
Real_Matrix (tk, m, n)
 
extern fn {tk : tkind}
Real_Matrix_matrix_sum_to :
{m, n : pos}
(Real_Matrix (tk, m, n), (* destination*)
Real_Matrix (tk, m, n),
Real_Matrix (tk, m, n)) -< !refwrt >
void
 
extern fn {tk : tkind}
Real_Matrix_matrix_difference :
{m, n : pos}
(Real_Matrix (tk, m, n), Real_Matrix (tk, m, n)) -< !refwrt >
Real_Matrix (tk, m, n)
 
extern fn {tk : tkind}
Real_Matrix_matrix_difference_to :
{m, n : pos}
(Real_Matrix (tk, m, n), (* destination*)
Real_Matrix (tk, m, n),
Real_Matrix (tk, m, n)) -< !refwrt >
void
 
extern fn {tk : tkind}
Real_Matrix_matrix_product :
{m, n, p : pos}
(Real_Matrix (tk, m, n), Real_Matrix (tk, n, p)) -< !refwrt >
Real_Matrix (tk, m, p)
 
extern fn {tk : tkind}
Real_Matrix_matrix_product_to :
{m, n, p : pos}
(Real_Matrix (tk, m, p), (* destination*)
Real_Matrix (tk, m, n),
Real_Matrix (tk, n, p)) -< !refwrt >
void
 
extern fn {tk : tkind}
Real_Matrix_scalar_product :
{m, n : pos}
(Real_Matrix (tk, m, n), g0float tk) -< !refwrt >
Real_Matrix (tk, m, n)
 
extern fn {tk : tkind}
Real_Matrix_scalar_product_2 :
{m, n : pos}
(g0float tk, Real_Matrix (tk, m, n)) -< !refwrt >
Real_Matrix (tk, m, n)
 
extern fn {tk : tkind}
Real_Matrix_scalar_product_to :
{m, n : pos}
(Real_Matrix (tk, m, n), (* destination*)
Real_Matrix (tk, m, n), g0float tk) -< !refwrt > void
 
extern fn {tk : tkind} (* Useful for debugging. *)
Real_Matrix_fprint :
{m, n : pos}
(FILEref, Real_Matrix (tk, m, n)) -<1> void
 
overload copy with Real_Matrix_copy
overload copy_to with Real_Matrix_copy_to
overload fill_with_elt with Real_Matrix_fill_with_elt
overload dimension with Real_Matrix_dimension
overload [] with Real_Matrix_get_at
overload [] with Real_Matrix_set_at
overload apply_index_map with Real_Matrix_apply_index_map
overload transpose with Real_Matrix_transpose
overload block with Real_Matrix_block
overload unit_matrix with Real_Matrix_unit_matrix
overload unit_matrix_to with Real_Matrix_unit_matrix_to
overload matrix_sum with Real_Matrix_matrix_sum
overload matrix_sum_to with Real_Matrix_matrix_sum_to
overload matrix_difference with Real_Matrix_matrix_difference
overload matrix_difference_to with Real_Matrix_matrix_difference_to
overload matrix_product with Real_Matrix_matrix_product
overload matrix_product_to with Real_Matrix_matrix_product_to
overload scalar_product with Real_Matrix_scalar_product
overload scalar_product with Real_Matrix_scalar_product_2
overload scalar_product_to with Real_Matrix_scalar_product_to
overload + with matrix_sum
overload - with matrix_difference
overload * with matrix_product
overload * with scalar_product
 
(*------------------------------------------------------------------*)
(* Implementation of the "little matrix library" *)
 
implement {tk}
Real_Matrix_make_elt (m0, n0, elt) =
Real_Matrix (matrixref_make_elt<g0float tk> (i2sz m0, i2sz n0, elt),
m0, n0, m0, n0, lam (i1, j1) => @(i1, j1))
 
implement {}
Real_Matrix_dimension A =
case+ A of Real_Matrix (_, m1, n1, _, _, _) => @(m1, n1)
 
implement {tk}
Real_Matrix_get_at (A, i1, j1) =
let
val+ Real_Matrix (storage, _, _, _, n0, index_map) = A
val @(i0, j0) = index_map (i1, j1)
in
matrixref_get_at<g0float tk> (storage, pred i0, n0, pred j0)
end
 
implement {tk}
Real_Matrix_set_at (A, i1, j1, x) =
let
val+ Real_Matrix (storage, _, _, _, n0, index_map) = A
val @(i0, j0) = index_map (i1, j1)
in
matrixref_set_at<g0float tk> (storage, pred i0, n0, pred j0, x)
end
 
implement {}
Real_Matrix_apply_index_map (A, m1, n1, index_map) =
(* This is not the most efficient way to acquire new indexing, but
it will work. It requires three closures, instead of the two
needed by our implementations of "transpose" and "block". *)
let
val+ Real_Matrix (storage, m1a, n1a, m0, n0, index_map_1a) = A
in
Real_Matrix (storage, m1, n1, m0, n0,
lam (i1, j1) =>
index_map_1a (i1a, j1a) where
{ val @(i1a, j1a) = index_map (i1, j1) })
end
 
implement {}
Real_Matrix_transpose A =
let
val+ Real_Matrix (storage, m1, n1, m0, n0, index_map) = A
in
Real_Matrix (storage, n1, m1, m0, n0,
lam (i1, j1) => index_map (j1, i1))
end
 
implement {}
Real_Matrix_block (A, p0, p1, q0, q1) =
let
val+ Real_Matrix (storage, m1, n1, m0, n0, index_map) = A
in
Real_Matrix (storage, succ (p1 - p0), succ (q1 - q0), m0, n0,
lam (i1, j1) =>
index_map (p0 + pred i1, q0 + pred j1))
end
 
implement {tk}
Real_Matrix_copy A =
let
val @(m1, n1) = dimension A
val C = Real_Matrix_make_elt<tk> (m1, n1, A[1, 1])
val () = copy_to<tk> (C, A)
in
C
end
 
implement {tk}
Real_Matrix_copy_to (Dst, Src) =
let
val @(m1, n1) = dimension Src
prval [m1 : int] EQINT () = eqint_make_gint m1
prval [n1 : int] EQINT () = eqint_make_gint n1
 
var i : intGte 1
in
for* {i : pos | i <= m1 + 1} .<(m1 + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m1; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n1 + 1} .<(n1 + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n1; j := succ j)
Dst[i, j] := Src[i, j]
end
end
 
implement {tk}
Real_Matrix_fill_with_elt (A, elt) =
let
val @(m1, n1) = dimension A
prval [m1 : int] EQINT () = eqint_make_gint m1
prval [n1 : int] EQINT () = eqint_make_gint n1
 
var i : intGte 1
in
for* {i : pos | i <= m1 + 1} .<(m1 + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m1; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n1 + 1} .<(n1 + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n1; j := succ j)
A[i, j] := elt
end
end
 
implement {tk}
Real_Matrix_unit_matrix {m} m =
let
val A = Real_Matrix_make_elt<tk> (m, m, Zero)
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
A[i, i] := One;
A
end
 
implement {tk}
Real_Matrix_unit_matrix_to A =
let
val @(m, _) = dimension A
prval [m : int] EQINT () = eqint_make_gint m
 
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= m + 1} .<(m + 1) - j>.
(j : int j) =>
(j := 1; j <> succ m; j := succ j)
A[i, j] := (if i = j then One else Zero)
end
end
 
implement {tk}
Real_Matrix_matrix_sum (A, B) =
let
val @(m, n) = dimension A
val C = Real_Matrix_make_elt<tk> (m, n, NAN)
val () = matrix_sum_to<tk> (C, A, B)
in
C
end
 
implement {tk}
Real_Matrix_matrix_sum_to (C, A, B) =
let
val @(m, n) = dimension A
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
 
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n; j := succ j)
C[i, j] := A[i, j] + B[i, j]
end
end
 
implement {tk}
Real_Matrix_matrix_difference (A, B) =
let
val @(m, n) = dimension A
val C = Real_Matrix_make_elt<tk> (m, n, NAN)
val () = matrix_difference_to<tk> (C, A, B)
in
C
end
 
implement {tk}
Real_Matrix_matrix_difference_to (C, A, B) =
let
val @(m, n) = dimension A
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
 
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n; j := succ j)
C[i, j] := A[i, j] - B[i, j]
end
end
 
implement {tk}
Real_Matrix_matrix_product (A, B) =
let
val @(m, n) = dimension A and @(_, p) = dimension B
val C = Real_Matrix_make_elt<tk> (m, p, NAN)
val () = matrix_product_to<tk> (C, A, B)
in
C
end
 
implement {tk}
Real_Matrix_matrix_product_to (C, A, B) =
let
val @(m, n) = dimension A and @(_, p) = dimension B
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
prval [p : int] EQINT () = eqint_make_gint p
 
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var k : intGte 1
in
for* {k : pos | k <= p + 1} .<(p + 1) - k>.
(k : int k) =>
(k := 1; k <> succ p; k := succ k)
let
var j : intGte 1
in
C[i, k] := A[i, 1] * B[1, k];
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 2; j <> succ n; j := succ j)
C[i, k] :=
multiply_and_add (A[i, j], B[j, k], C[i, k])
end
end
end
 
implement {tk}
Real_Matrix_scalar_product (A, r) =
let
val @(m, n) = dimension A
val C = Real_Matrix_make_elt<tk> (m, n, NAN)
val () = scalar_product_to<tk> (C, A, r)
in
C
end
 
implement {tk}
Real_Matrix_scalar_product_2 (r, A) =
Real_Matrix_scalar_product<tk> (A, r)
 
implement {tk}
Real_Matrix_scalar_product_to (C, A, r) =
let
val @(m, n) = dimension A
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
 
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n; j := succ j)
C[i, j] := A[i, j] * r
end
end
 
implement {tk}
Real_Matrix_fprint {m, n} (outf, A) =
let
val @(m, n) = dimension A
var i : intGte 1
in
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 1; i <> succ m; i := succ i)
let
var j : intGte 1
in
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 1; j <> succ n; j := succ j)
let
typedef FILEstar = $extype"FILE *"
extern castfn FILEref2star : FILEref -<> FILEstar
val _ = $extfcall (int, "fprintf", FILEref2star outf,
"%16.6g", A[i, j])
in
end;
fprintln! (outf)
end
end
 
(*------------------------------------------------------------------*)
(* Reduced row echelon form, by Gauss-Jordan elimination *)
 
extern fn {tk : tkind}
Real_Matrix_reduced_row_echelon_form :
{m, n : pos}
Real_Matrix (tk, m, n) -< !refwrt > Real_Matrix (tk, m, n)
 
implement {tk}
Real_Matrix_reduced_row_echelon_form {m, n} A =
let
val @(m, n) = dimension A
typedef one_to_m = intBtwe (1, m)
typedef one_to_n = intBtwe (1, n)
 
(* Partial pivoting, to improve the numerical stability. *)
implement
array_tabulate$fopr<one_to_m> i =
let
val i = g1ofg0 (sz2i (succ i))
val () = assertloc ((1 <= i) * (i <= m))
in
i
end
val rows_permutation =
$effmask_all arrayref_tabulate<one_to_m> (i2sz m)
fn
index_map : Matrix_Index_Map (m, n, m, n) =
lam (i1, j1) => $effmask_ref
(@(i0, j1) where { val i0 = rows_permutation[i1 - 1] })
 
val A = apply_index_map (copy<tk> A, m, n, index_map)
 
fn {}
exchange_rows (i1 : one_to_m,
i2 : one_to_m) :<!refwrt> void =
if i1 <> i2 then
let
val k1 = rows_permutation[pred i1]
and k2 = rows_permutation[pred i2]
in
rows_permutation[pred i1] := k2;
rows_permutation[pred i2] := k1
end
 
fn {}
normalize_pivot_row (i : one_to_m,
j : one_to_n) :<!refwrt> void =
let
prval [j : int] EQINT () = eqint_make_gint j
val pivot_val = A[i, j]
var k : intGte 1
in
A[i, j] := One;
for* {k : int | j + 1 <= k; k <= n + 1} .<(n + 1) - k>.
(k : int k) =>
(k := succ j; k <> succ n; k := succ k)
A[i, k] := A[i, k] / pivot_val
end
 
fn
subtract_normalized_pivot_row (ipiv : one_to_m,
i : one_to_m,
j : one_to_n) :<!refwrt> void =
let
prval [j : int] EQINT () = eqint_make_gint j
val factor = ~A[i, j]
var k : intGte 1
in
A[i, j] := Zero;
for* {k : int | j + 1 <= k; k <= n + 1} .<(n + 1) - k>.
(k : int k) =>
(k := succ j; k <> succ n; k := succ k)
A[i, k] := multiply_and_add (A[ipiv, k], factor, A[i, k])
end
 
fun
main_loop {i, j : pos | i <= m; i <= j; j <= n + 1}
.<(n + 1) - j>.
(i : int i, j : int j) :<!refwrt> void =
if j <> succ n then
let
fun
select_pivot {k : int | i <= k; k <= m + 1}
.<(m + 1) - k>.
(k : int k,
max_abs : g0float tk,
k_max_abs : intBtwe (i - 1, m))
:<!ref> intBtwe (i - 1, m) =
if k = succ m then
k_max_abs
else
let
val abs_akj = abs A[k, j]
in
if abs_akj > max_abs then
select_pivot (succ k, abs_akj, k)
else
select_pivot (succ k, max_abs, k_max_abs)
end
 
val i_pivot = select_pivot (i, Zero, pred i)
prval [i_pivot : int] EQINT () = eqint_make_gint i_pivot
in
if i_pivot = pred i then
(* There is no pivot in this column. *)
main_loop (i, succ j)
else
let
var k : intGte 1
in
exchange_rows (i_pivot, i);
normalize_pivot_row (i, j);
for* {k : int | 1 <= k; k <= i} .<i - k>.
(k : int k) =>
(k := 1; k <> i; k := succ k)
subtract_normalized_pivot_row (i, k, j);
for* {k : int | i + 1 <= k; k <= m + 1} .<(m + 1) - k>.
(k : int k) =>
(k := succ i; k <> succ m; k := succ k)
subtract_normalized_pivot_row (i, k, j);
if i <> m then
main_loop (succ i, succ j)
end
end
in
main_loop (1, 1);
A
end
 
overload reduced_row_echelon_form with
Real_Matrix_reduced_row_echelon_form
 
(*------------------------------------------------------------------*)
 
implement
main0 () =
let
val () = println! ()
val () = println! ("Here is the requested solution:")
val () = println! ()
val A = Real_Matrix_make_elt (3, 4, NAN)
val () =
(A[1,1] := 1.0; A[1,2] := 2.0; A[1,3] := ~1.0; A[1,4] := ~4.0;
A[2,1] := 2.0; A[2,2] := 3.0; A[2,3] := ~1.0; A[2,4] := ~11.0;
A[3,1] := ~2.0; A[3,2] := 0.0; A[3,3] := ~3.0; A[3,4] := 22.0)
val B = reduced_row_echelon_form A
val () = Real_Matrix_fprint (stdout_ref, B)
 
val () = println! ()
val () = println! ("Here is a RREF with a more interesting shape:")
val () = println! ()
val A = Real_Matrix_make_elt (3, 5, NAN)
val () =
(A[1,1] := 0.0; A[1,2] := 0.0; A[1,3] := ~1.0; A[1,4] := 2.0; A[1,5] := 0.0;
A[2,1] := 0.0; A[2,2] := 0.0; A[2,3] := ~1.0; A[2,4] := 1.0; A[2,5] := 1.0;
A[3,1] := 2.0; A[3,2] := 8.0; A[3,3] := 1.0; A[3,4] := ~4.0; A[3,5] := 2.0)
val B = reduced_row_echelon_form A
val () = Real_Matrix_fprint (stdout_ref, B)
 
val () = println! ()
val () = println! ("It is the RREF of this matrix:")
val () = println! ()
val () = Real_Matrix_fprint (stdout_ref, A)
 
val () = println! ()
in
end
 
(*------------------------------------------------------------------*)
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_GCBDW reduced_row_echelon_task.dats -lgc && ./a.out
 
Here is the requested solution:
 
1 0 0 -8
0 1 0 1
0 0 1 -2
 
Here is a RREF with a more interesting shape:
 
1 4 0 0 0
0 0 1 0 -2
0 0 0 1 -1
 
It is the RREF of this matrix:
 
0 0 -1 2 0
0 0 -1 1 1
2 8 1 -4 2
 
</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">ToReducedRowEchelonForm(M){
rowCount := M.Count() ; the number of rows in M
columnCount := M.1.Count() ; the number of columns in M
r := lead := 1
while (r <= rowCount) {
if (columnCount < lead)
return M
i := r
while (M[i, lead] = 0) {
i++
if (rowCount+1 = i) {
i := r, lead++
if (columnCount+1 = lead)
return M
}
}
if (i<>r)
for col, v in M[i] ; Swap rows i and r
tempVal := M[i, col], M[i, col] := M[r, col], M[r, col] := tempVal
num := M[r, lead]
if (M[r, lead] <> 0)
for col, val in M[r]
M[r, col] /= num ; If M[r, lead] is not 0 divide row r by M[r, lead]
i := 2
while (i <= rowCount) {
num := M[i, lead]
if (i <> r)
for col, val in M[i] ; Subtract M[i, lead] multiplied by row r from row i
M[i, col] -= num * M[r, col]
i++
}
lead++, r++
}
return M
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">M := [[1 , 2, -1, -4 ]
, [2 , 3, -1, -11]
, [-2, 0, -3, 22]]
M := ToReducedRowEchelonForm(M)
for row, obj in M
{
for col, v in obj
output .= RegExReplace(v, "\.0+$|0+$") "`t"
output .= "`n"
}
MsgBox % output
return</syntaxhighlight>
{{out}}
<pre>1 0 0 -8
-0 1 0 1
-0 -0 1 -2
</pre>
 
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">
<lang AutoIt>
Global $ivMatrix[3][4] = [[1, 2, -1, -4],[2, 3, -1, -11],[-2, 0, -3, 22]]
ToReducedRowEchelonForm($ivMatrix)
Line 421 ⟶ 1,482:
Return $matrix
EndFunc ;==>ToReducedRowEchelonForm
</syntaxhighlight>
</lang>
{{out}}
'''Output:'''
<pre>[1,0,0,-8]
[-0,1,0,1]
[-0,-0,1,-2]</pre>
 
=={{header|BBC BASIC}}==
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256">arraybase 1
global matrix
dim matrix = {{1, 2, -1, -4}, {2, 3, -1, -11}, { -2, 0, -3, 22}}
 
call RREF (matrix)
 
for row = 1 to 3
for col = 1 to 4
if matrix[row, col] = 0 then
print "0"; chr(9);
else
print matrix[row, col]; chr(9);
end if
next
print
next
end
 
subroutine RREF(m)
nrows = matrix[?,]
ncols = matrix[,?]
lead = 1
for r = 1 to nrows
if lead >= ncols then exit for
i = r
while matrix[i, lead] = 0
i += 1
if i = nrows then
i = r
lead += 1
if lead = ncols then exit for
end if
end while
for j = 1 to ncols
temp = matrix[i, j]
matrix[i, j] = matrix[r, j]
matrix[r, j] = temp
next
n = matrix[r, lead]
if n <> 1 then
for j = 0 to ncols
matrix[r, j] /= n
next
end if
for i = 1 to nrows
if i <> r then
n = matrix[i, lead]
for j = 1 to ncols
matrix[i, j] -= matrix[r, j] * n
next
end if
next
lead += 1
next
end subroutine</syntaxhighlight>
 
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> DIM matrix(2,3)
matrix() = 1, 2, -1, -4, \
\ 2, 3, -1, -11, \
Line 470 ⟶ 1,589:
lead% += 1
NEXT r%
ENDPROC</langsyntaxhighlight>
{{out}}
'''Output:'''
<pre>
1 0 0 -8
Line 479 ⟶ 1,598:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#define TALLOC(n,typ) malloc(n*sizeof(typ))
 
Line 634 ⟶ 1,753:
MtxDisplay(m1);
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
namespace rref
{
class Program
{
static void Main(string[] args)
{
int[,] matrix = new int[3, 4]{
{ 1, 2, -1, -4 },
{ 2, 3, -1, -11 },
{ -2, 0, -3, 22 }
};
matrix = rref(matrix);
}
 
private static int[,] rref(int[,] matrix)
{
int lead = 0, rowCount = matrix.GetLength(0), columnCount = matrix.GetLength(1);
for (int r = 0; r < rowCount; r++)
{
if (columnCount <= lead) break;
int i = r;
while (matrix[i, lead] == 0)
{
i++;
if (i == rowCount)
{
i = r;
lead++;
if (columnCount == lead)
{
lead--;
break;
}
}
}
for (int j = 0; j < columnCount; j++)
{
int temp = matrix[r, j];
matrix[r, j] = matrix[i, j];
matrix[i, j] = temp;
}
int div = matrix[r, lead];
if(div != 0)
for (int j = 0; j < columnCount; j++) matrix[r, j] /= div;
for (int j = 0; j < rowCount; j++)
{
if (j != r)
{
int sub = matrix[j, lead];
for (int k = 0; k < columnCount; k++) matrix[j, k] -= (sub * matrix[r, k]);
}
}
lead++;
}
return matrix;
}
}
}</syntaxhighlight>
 
=={{header|C++}}==
Line 642 ⟶ 1,823:
 
{{works with|g++|4.1.2 20061115 (prerelease) (Debian 4.1.1-21)}}
<langsyntaxhighlight lang="cpp">#include <algorithm> // for std::swap
#include <cstddef>
#include <cassert>
Line 649 ⟶ 1,830:
// externalizing this information into a traits class, the same code
// can be used both with native arrays and matrix classes. To use the
// dfaultdefault implementation of the traits class, a matrix type has to
// provide the following definitions as members:
//
Line 676 ⟶ 1,857:
{
typedef typename MatrixType::index_type index_type;
typedef typename MatrixType::value_typvalue_type value_type;
static index_type min_row(MatrixType const& A)
{ return A.min_row(); }
Line 827 ⟶ 2,008:
 
return EXIT_SUCCESS;
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
1 0 0 -8
Line 834 ⟶ 2,015:
-0 -0 1 -2
</pre>
 
=={{header|C sharp|C#}}==
<lang csharp>using System;
 
namespace rref
{
class Program
{
static void Main(string[] args)
{
int[,] matrix = new int[3, 4]{
{ 1, 2, -1, -4 },
{ 2, 3, -1, -11 },
{ -2, 0, -3, 22 }
};
matrix = rref(matrix);
}
 
private static int[,] rref(int[,] matrix)
{
int lead = 0, rowCount = matrix.GetLength(0), columnCount = matrix.GetLength(1);
for (int r = 0; r < rowCount; r++)
{
if (columnCount <= lead) break;
int i = r;
while (matrix[i, lead] == 0)
{
i++;
if (i == rowCount)
{
i = r;
lead++;
if (columnCount == lead)
{
lead--;
break;
}
}
}
for (int j = 0; j < columnCount; j++)
{
int temp = matrix[r, j];
matrix[r, j] = matrix[i, j];
matrix[i, j] = temp;
}
int div = matrix[r, lead];
for (int j = 0; j < columnCount; j++) matrix[r, j] /= div;
for (int j = 0; j < rowCount; j++)
{
if (j != r)
{
int sub = matrix[j, lead];
for (int k = 0; k < columnCount; k++) matrix[j, k] -= (sub * matrix[r, k]);
}
}
lead++;
}
return matrix;
}
}
}</lang>
 
=={{header|Common Lisp}}==
Direct implementation of the pseudo-code given.
<langsyntaxhighlight lang="lisp">(defun convert-to-row-echelon-form (matrix)
(let* ((dimensions (array-dimensions matrix))
(row-count (first dimensions))
Line 941 ⟶ 2,061:
(* scale (aref matrix r c))))))
(incf lead))
:finally (return matrix)))))</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array, std.conv;
 
void toReducedRowEchelonForm(T)(T[][] M) pure nothrow @nogc {
Line 985 ⟶ 2,105:
A.toReducedRowEchelonForm;
writefln("%(%(%2d %)\n%)", A);
}</langsyntaxhighlight>
{{out}}
<pre> 1 0 0 -8
0 1 0 1
0 0 1 -2</pre>
 
=={{header|EasyLang}}==
{{trans|Go}}
<syntaxhighlight>
proc rref . m[][] .
nrow = len m[][]
ncol = len m[1][]
lead = 1
for r to nrow
if lead > ncol
return
.
i = r
while m[i][lead] = 0
i += 1
if i > nrow
i = r
lead += 1
if lead > ncol
return
.
.
.
swap m[i][] m[r][]
m = m[r][lead]
for k to ncol
m[r][k] /= m
.
for i to nrow
if i <> r
m = m[i][lead]
for k to ncol
m[i][k] -= m * m[r][k]
.
.
.
lead += 1
.
.
test[][] = [ [ 1 2 -1 -4 ] [ 2 3 -1 -11 ] [ -2 0 -3 22 ] ]
rref test[][]
print test[][]
</syntaxhighlight>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function ToReducedRowEchelonForm(sequence M)
integer lead,rowCount,columnCount,i
sequence temp
Line 1,030 ⟶ 2,193:
{ { 1, 2, -1, -4 },
{ 2, 3, -1, -11 },
{ -2, 0, -3, 22 } })</langsyntaxhighlight>
 
{{out}}
Output:
<pre>{
{1,0,0,-8},
Line 1,038 ⟶ 2,201:
{0,0,1,-2}
}</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USE: math.matrices.elimination
{ { 1 2 -1 -4 } { 2 3 -1 -11 } { -2 0 -3 22 } } solution .</syntaxhighlight>
{{out}}
<pre>
{ { 1 0 0 -8 } { 0 1 0 1 } { 0 0 1 -2 } }
</pre>
 
=={{header|Fortran}}==
<langsyntaxhighlight lang="fortran">module Rref
implicit none
contains
Line 1,078 ⟶ 2,249:
deallocate(trow)
end subroutine to_rref
end module Rref</langsyntaxhighlight>
 
<langsyntaxhighlight lang="fortran">program prg_test
use rref
implicit none
Line 1,102 ⟶ 2,273:
end do
 
end program prg_test</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
Include the code from [[Matrix multiplication#FreeBASIC]] because this function uses the matrix type defined there and I don't want to reproduce it all here.
 
<syntaxhighlight lang="freebasic">#include once "matmult.bas"
 
sub rowswap( byval M as Matrix, i as uinteger, j as uinteger )
dim as integer k
for k = 0 to ubound(M.m, 2)
swap M.m(j, k), M.m(i, k)
next k
end sub
 
function rowech(byval M as Matrix) as Matrix
dim as uinteger lead = 0, rowCount = 1+ubound(M.m, 1), colCount = 1+ubound(M.m, 2)
dim as uinteger r, i, j
dim as double K
for r = 0 to rowCount-1
if lead >= colCount then exit for
i = r
while M.m(i, lead) = 0
i += 1
if i = rowCount then
i = r
lead += 1
if lead = colCount then exit for
endif
wend
rowswap M, r, i
K = M.m(r,lead)
if K <> 0 then
for j = 0 to colCount-1
M.m(r,j) /= K
next j
endif
for i = 0 to rowCount-1
if i <> r then
K = M.m(i, lead)
for j = 0 to colCount-1
M.m(i,j) -= M.m(r,j) * K
next j
endif
next i
lead += 1
next r
return M
end function
 
 
dim as Matrix M = Matrix (3, 4)
dim as Matrix N
 
M.m(0,0) = 1 : M.m(0,1) = 2 : M.m(0,2) = -1 : M.M(0,3) = -4
M.m(1,0) = 2 : M.m(1,1) = 3 : M.m(1,2) = -1 : M.m(1,3) = -11
M.m(2,0) = -2: M.m(2,1) = 0 : M.m(2,2) = -3 : M.m(2,3) = 22
 
dim as integer i, j
 
N = rowech(M)
for i=0 to 2
for j = 0 to 3
print N.m(i, j),
next j
print
next i</syntaxhighlight>
{{out}}
<pre>
1 0 0 -8
-0 1 0 1
-0 -0 1 -2
</pre>
 
=={{header|Go}}==
===2D representation===
From WP pseudocode:
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,165 ⟶ 2,407:
lead++
}
}</langsyntaxhighlight>
Output{{out}} (not so pretty, sorry)
<pre>
[1 2 -1 -4]
Line 1,176 ⟶ 2,418:
[-0 -0 1 -2]
</pre>
 
===Flat representation===
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,259 ⟶ 2,502:
m.rref()
m.print("Reduced:")
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
Input:
Line 1,274 ⟶ 2,517:
 
=={{header|Groovy}}==
This solution implements the transformation to reduced row echelon form with optional pivoting. Options are provided for both ''partial pivoting'' and ''scaled partial pivoting''. The default option is no pivoting at all.
with optional pivoting.
<lang groovy>enum Pivoting {
Options are provided for both ''partial pivoting'' and ''scaled partial pivoting''.
The default option is no pivoting at all.
<syntaxhighlight lang="groovy">enum Pivoting {
NONE({ i, it -> 1 }),
PARTIAL({ i, it -> - (it[i].abs()) }),
Line 1,306 ⟶ 2,552:
}
matrix
}</langsyntaxhighlight>
 
This test first demonstrates the test case provided, and then demonstrates another test case designed to show the dangers of not using pivoting on an otherwise solvable matrix. Both test cases exercise all three pivoting options.
<langsyntaxhighlight lang="groovy">def matrixCopy = { matrix -> matrix.collect { row -> row.collect { it } } }
 
println "Tests for matrix A:"
Line 1,354 ⟶ 2,600:
println "pivoting == Pivoting.SCALED"
reducedRowEchelonForm(matrixCopy(b), Pivoting.SCALED).each { println it }
println()</langsyntaxhighlight>
 
{{out}}
Output:
<pre>Tests for matrix A:
[1, 2, -1, -4]
Line 1,398 ⟶ 2,644:
This program was produced by translating from the Python and gradually refactoring the result into a more functional style.
 
<langsyntaxhighlight lang="haskell">import Data.List (find)
 
rref :: Fractional a => [[a]] -> [[a]]
Line 1,429 ⟶ 2,675:
{- Replaces the element at the given index. -}
replace n e l = a ++ e : b
where (a, _ : b) = splitAt n l</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
 
Works in both languages:
<langsyntaxhighlight lang="unicon">procedure main(A)
tM := [[ 1, 2, -1, -4],
[ 2, 3, -1,-11],
Line 1,466 ⟶ 2,712:
procedure showMat(M)
every r := !M do every writes(right(!r,5)||" " | "\n")
end</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
->rref
Line 1,478 ⟶ 2,724:
 
=={{header|J}}==
The reduced row echelon form of a matrix can be obtained using the <code>gauss_jordan</code> verb from the [httphttps://www.jsoftwaregithub.com/tracjsoftware/addonsmath_misc/browserblob/trunk/math/miscmaster/linear.ijs linear.ijs script], available as part of the <code>math/misc</code> addon. <code>gauss_jordan</code> and the verb <code>pivot</code> are shown below (in a mediawiki "[Expand]" region) for completeness:
 
<lang j> ]mymatrix=: _4]\ 1 2 _1 _4 2 3 _1 _11 _2 0 _3 22
'''Implementation:'''
<syntaxhighlight lang="j" class="mw-collapsible mw-collapsed">NB.*pivot v Pivot at row, column
NB. form: (row,col) pivot M
pivot=: dyad define
'r c'=. x
col=. c{"1 y
y - (col - r = i.#y) */ (r{y) % r{col
)
 
NB.*gauss_jordan v Gauss-Jordan elimination (full pivoting)
NB. y is: matrix
NB. x is: optional minimum tolerance, default 1e_15.
NB. If a column below the current pivot has numbers of magnitude all
NB. less then x, it is treated as all zeros.
gauss_jordan=: verb define
1e_15 gauss_jordan y
:
mtx=. y
'r c'=. $mtx
rows=. i.r
i=. j=. 0
max=. i.>./
while. (i<r) *. j<c do.
k=. max col=. | i}. j{"1 mtx
if. 0 < x-k{col do. NB. if all col < tol, set to 0:
mtx=. 0 (<(i}.rows);j) } mtx
else. NB. otherwise sort and pivot:
if. k do.
mtx=. (<i,i+k) C. mtx
end.
mtx=. (i,j) pivot mtx
i=. >:i
end.
j=. >:j
end.
mtx
)</syntaxhighlight>
 
<hr style="clear: both"/>
'''Usage:'''
<syntaxhighlight lang="j"> require 'math/misc/linear'
]A=: 1 2 _1 _4 , 2 3 _1 _11 ,: _2 0 _3 22
1 2 _1 _4
2 3 _1 _11
_2 0 _3 22
 
gauss_jordan A
require 'math/misc/linear'
gauss_jordan mymatrix
1 0 0 _8
0 1 0 1
0 0 1 _2</langsyntaxhighlight>
 
Additional examples, recommended on talk page:
 
<syntaxhighlight lang="j">
<lang j>
gauss_jordan 2 0 _1 0 0,1 0 0 _1 0,3 0 0 _2 _1,0 1 0 0 _2,:0 1 _1 0 0
1 0 0 0 _1
Line 1,508 ⟶ 2,795:
1 0
0 1
0 0</langsyntaxhighlight>
 
And:
 
<syntaxhighlight lang="j">mat=: 0 ". ];._2 noun define
1 0 0 0 0 0 1 0 0 0 0 _1 0 0 0 0 0 0
1 0 0 0 0 0 0 1 0 0 0 0 _1 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0 0 0 0 _1 0 0 0 0
0 1 0 0 0 0 1 0 0 0 0 0 0 0 _1 0 0 0
0 1 0 0 0 0 0 0 1 0 0 _1 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 _1 0
0 0 1 0 0 0 1 0 0 0 0 0 _1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 _1 0 0 0
0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 _1 0 0
0 0 0 1 0 0 0 0 0 1 0 0 _1 0 0 0 0 0
0 0 0 0 1 0 0 1 0 0 0 0 0 _1 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 _1 0
0 0 0 0 1 0 0 0 0 0 1 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 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 1 0 0 0 0 1 0 0 0 _1 0 0 0
)
gauss_jordan mat
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.435897
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.307692
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.512821
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0.717949
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0.487179
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0.205128
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0.282051
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0.333333
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0.512821
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0.641026
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0.717949
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0.769231
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0.512821
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.820513</syntaxhighlight>
 
=={{header|Java}}==
''This requires Apache Commons 2.2+''
<langsyntaxhighlight lang="java">import java.util.*;
import java.lang.Math;
import org.apache.commons.math.fraction.Fraction;
Line 1,771 ⟶ 3,098:
System.out.println("after\n" + a.toString() + "\n");
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{works with|SpiderMonkey}} for the <code>print()</code> function.
Extends the Matrix class defined at [[Matrix Transpose#JavaScript]]
<langsyntaxhighlight lang="javascript">// modifies the matrix in-place
Matrix.prototype.toReducedRowEchelonForm = function() {
var lead = 0;
Line 1,829 ⟶ 3,156:
[ 3, 3, 0, 7]
]);
print(m.toReducedRowEchelonForm());</langsyntaxhighlight>
{{out}}
output
<pre>1,0,0,-8
0,1,0,1
Line 1,839 ⟶ 3,166:
0,0,1,1</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq, and with fq.'''
 
'''Generic Functions'''
<syntaxhighlight lang=jq>
# swap .[$i] and .[$j]
def array_swap($i; $j):
if $i == $j then .
elif $i < $j then array_swap($j; $i)
else .[$i] as $t | .[:$j] + [$t] + .[$j:$i] + .[$i + 1:]
end ;
 
# element-wise subtraction: $a - $b
def array_subtract($a; $b):
$a | [range(0;length) as $i | .[$i] - $b[$i]];
 
def lpad($len):
tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
# Ensure -0 prints as 0
def matrix_print:
([.[][] | tostring | length] | max) as $max
| .[] | map(if . == 0 then 0 else . end | lpad($max))
| join(" ");
</syntaxhighlight>
'''The Task'''
<syntaxhighlight lang=jq>
# RREF
# assume input is a rectangular numeric matrix
def toReducedRowEchelonForm:
length as $nr
| (.[0]|length) as $nc
| { lead: 0, r: -1, a: .}
| until ($nc == .lead or .r == $nr;
.r += 1
| .r as $r
| .i = $r
| until ($nc == .lead or .a[.i][.lead] != 0;
.i += 1
| if $nr == .i
then .i = $r
| .lead += 1
else .
end )
| if $nc > .lead and $nr > $r
then .i as $i
| .a |= array_swap($i; $r)
| .a[$r][.lead] as $div
| if $div != 0
then .a[$r] |= map(. / $div)
else .
end
| reduce range(0; $nr) as $k (.;
if $k != $r
then .a[$k][.lead] as $mult
| .a[$k] = array_subtract(.a[$k]; (.a[$r] | map(. * $mult)))
else .
end )
| .lead += 1
else .
end )
| .a;
 
[ [ 1, 2, -1, -4],
[ 2, 3, -1, -11],
[-2, 0, -3, 22] ],
[ [1, 2, -1, -4],
[2, 4, -1, -11],
[-2, 0, -6, 24] ]
| "Original:", matrix_print, "",
"RREF:", (toReducedRowEchelonForm|matrix_print), "\n"
</syntaxhighlight>
{{output}}
'''Invocation:''' jq -nrc -f reduced-row-echelon-form.jq
<pre>
Original:
1 2 -1 -4
2 3 -1 -11
-2 0 -3 22
 
RREF:
1 0 0 -8
0 1 0 1
0 0 1 -2
 
 
Original:
1 2 -1 -4
2 4 -1 -11
-2 0 -6 24
 
RREF:
1 0 0 -3
0 1 0 -2
0 0 1 -3
</pre>
 
=={{header|Julia}}==
JuliaRowEchelon.jl comesoffers with a built-inthe function <code>rref</code> to compute the reduced-row echelon form:
<pre>
julia> matrix = [1 2 -1 -4 ; 2 3 -1 -11 ; -2 0 -3 22]
Line 1,855 ⟶ 3,280:
0.0 0.0 1.0 -2.0
 
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.51
 
typealias Matrix = Array<DoubleArray>
 
/* changes the matrix to RREF 'in place' */
fun Matrix.toReducedRowEchelonForm() {
var lead = 0
val rowCount = this.size
val colCount = this[0].size
for (r in 0 until rowCount) {
if (colCount <= lead) return
var i = r
 
while (this[i][lead] == 0.0) {
i++
if (rowCount == i) {
i = r
lead++
if (colCount == lead) return
}
}
 
val temp = this[i]
this[i] = this[r]
this[r] = temp
 
if (this[r][lead] != 0.0) {
val div = this[r][lead]
for (j in 0 until colCount) this[r][j] /= div
}
 
for (k in 0 until rowCount) {
if (k != r) {
val mult = this[k][lead]
for (j in 0 until colCount) this[k][j] -= this[r][j] * mult
}
}
 
lead++
}
}
 
fun Matrix.printf(title: String) {
println(title)
val rowCount = this.size
val colCount = this[0].size
 
for (r in 0 until rowCount) {
for (c in 0 until colCount) {
if (this[r][c] == -0.0) this[r][c] = 0.0 // get rid of negative zeros
print("${"% 6.2f".format(this[r][c])} ")
}
println()
}
 
println()
}
 
fun main(args: Array<String>) {
val matrices = listOf(
arrayOf(
doubleArrayOf( 1.0, 2.0, -1.0, -4.0),
doubleArrayOf( 2.0, 3.0, -1.0, -11.0),
doubleArrayOf(-2.0, 0.0, -3.0, 22.0)
),
arrayOf(
doubleArrayOf(1.0, 2.0, 3.0, 4.0, 3.0, 1.0),
doubleArrayOf(2.0, 4.0, 6.0, 2.0, 6.0, 2.0),
doubleArrayOf(3.0, 6.0, 18.0, 9.0, 9.0, -6.0),
doubleArrayOf(4.0, 8.0, 12.0, 10.0, 12.0, 4.0),
doubleArrayOf(5.0, 10.0, 24.0, 11.0, 15.0, -4.0)
)
)
 
for (m in matrices) {
m.printf("Original matrix:")
m.toReducedRowEchelonForm()
m.printf("Reduced row echelon form:")
}
}</syntaxhighlight>
 
{{out}}
<pre>
Original matrix:
1.00 2.00 -1.00 -4.00
2.00 3.00 -1.00 -11.00
-2.00 0.00 -3.00 22.00
 
Reduced row echelon form:
1.00 0.00 0.00 -8.00
0.00 1.00 0.00 1.00
0.00 0.00 1.00 -2.00
 
Original matrix:
1.00 2.00 3.00 4.00 3.00 1.00
2.00 4.00 6.00 2.00 6.00 2.00
3.00 6.00 18.00 9.00 9.00 -6.00
4.00 8.00 12.00 10.00 12.00 4.00
5.00 10.00 24.00 11.00 15.00 -4.00
 
Reduced row echelon form:
1.00 2.00 0.00 0.00 3.00 4.00
0.00 0.00 1.00 0.00 0.00 -1.00
0.00 0.00 0.00 1.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function ToReducedRowEchelonForm ( M )
local lead = 1
local n_rows, n_cols = #M, #M[1]
Line 1,903 ⟶ 3,437:
end
io.write( "\n" )
end</langsyntaxhighlight>
{{out}}
Output:
<pre>1 0 0 -8
0 1 0 1
0 0 1 -2 </pre>
 
=={{header|M2000 Interpreter}}==
low bound 1 for array
<syntaxhighlight lang="m2000 interpreter">
Module Base1 {
dim base 1, A(3, 4)
A(1, 1)= 1, 2, -1, -4, 2 , 3, -1, -11, -2 , 0 , -3, 22
lead=1
rowcount=3
columncount=4
gosub disp()
for r=1 to rowcount {
if columncount<lead then exit
i=r
while A(i,lead)=0 {
i++
if rowcount=i then i=r : lead++ : if columncount<lead then exit
}
for c =1 to columncount {
swap A(i, c), A(r, c)
}
if A(r, lead)<>0 then {
div1=A(r,lead)
For c =1 to columncount {
A( r, c)/=div1
}
}
for i=1 to rowcount {
if i<>r then {
mult=A(i,lead)
for j=1 to columncount {
A(i,j)-=A(r,j)*mult
}
}
}
lead=lead+1
}
disp()
sub disp()
local i, j
for i=1 to rowcount
for j=1 to columncount
Print A(i, j),
Next j
if pos>0 then print
Next i
End sub
}
Base1
</syntaxhighlight>
 
Low bound 0 for array
 
<syntaxhighlight lang="m2000 interpreter">
Module base0 {
dim base 0, A(3, 4)
A(0, 0)= 1, 2, -1, -4, 2 , 3, -1, -11, -2 , 0 , -3, 22
lead=0
rowcount=3
columncount=4
gosub disp()
for r=0 to rowcount-1 {
if columncount<=lead then exit
i=r
while A(i,lead)=0 {
i++
if rowcount=i then i=r : lead++ : if columncount<lead then exit
}
for c =0 to columncount-1 {
swap A(i, c), A(r, c)
}
if A(r, lead)<>0 then {
div1=A(r,lead)
For c =0 to columncount-1 {
A( r, c)/=div1
}
}
for i=0 to rowcount-1 {
if i<>r then {
mult=A(i,lead)
for j=0 to columncount-1 {
A(i,j)-=A(r,j)*mult
}
}
}
lead=lead+1
}
disp()
sub disp()
local i, j
for i=0 to rowcount-1
for j=0 to columncount-1
Print A(i, j),
Next j
if pos>0 then print
Next i
End sub
}
base0
</syntaxhighlight>
 
=={{header|Maple}}==
 
<syntaxhighlight lang="maple">
<lang Maple>
with(LinearAlgebra):
 
ReducedRowEchelonForm(<<1,2,-2>|<2,3,0>|<-1,-1,-3>|<-4,-11,22>>);
</syntaxhighlight>
</lang>
{{out}}
Output:
<pre>
[1 0 0 -8]
Line 1,926 ⟶ 3,559:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">RowReduce[{{1, 2, -1, -4}, {2, 3, -1, -11}, {-2, 0, -3, 22}}]</langsyntaxhighlight>
{{out}}
gives back:
<lang Mathematicapre>{{1, 0, 0, -8}, {0, 1, 0, 1}, {0, 0, 1, -2}}</langpre>
 
=={{header|MATLAB}}==
<langsyntaxhighlight MATLABlang="matlab">rref([1, 2, -1, -4; 2, 3, -1, -11; -2, 0, -3, 22])</langsyntaxhighlight>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">rref(a):=block([p,q,k],[p,q]:matrix_size(a),a:echelon(a),
k:min(p,q),
for i thru min(p,q) do (if a[i,i]=0 then (k:i-1,return())),
Line 1,948 ⟶ 3,581:
 
rref(a);
matrix([1,0,0,0,1/2],[0,1,0,0,-1],[0,0,1,0,-1/2],[0,0,0,1,1],[0,0,0,0,0])</langsyntaxhighlight>
 
=={{header|Nim}}==
===Using rationals===
To avoid rounding issues, we can use rationals and convert to floats only at the end.
<syntaxhighlight lang="nim">import rationals, strutils
 
type Fraction = Rational[int]
 
const Zero: Fraction = 0 // 1
 
type Matrix[M, N: static Positive] = array[M, array[N, Fraction]]
 
 
func toMatrix[M, N: static Positive](a: array[M, array[N, int]]): Matrix[M, N] =
## Convert a matrix of integers to a matrix of integer fractions.
 
for i in 0..<M:
for j in 0..<N:
result[i][j] = a[i][j] // 1
 
 
func transformToRref(mat: var Matrix) =
## Transform the given matrix to reduced row echelon form.
 
var lead = 0
 
for r in 0..<mat.M:
 
if lead >= mat.N: return
 
var i = r
while mat[i][lead] == Zero:
inc i
if i == mat.M:
i = r
inc lead
if lead == mat.N: return
swap mat[i], mat[r]
 
if (let d = mat[r][lead]; d) != Zero:
for item in mat[r].mitems:
item /= d
 
for i in 0..<mat.M:
if i != r:
let m = mat[i][lead]
for c in 0..<mat.N:
mat[i][c] -= mat[r][c] * m
 
inc lead
 
 
proc `$`(mat: Matrix): string =
## Display a matrix.
 
for row in mat:
var line = ""
for val in row:
line.addSep(" ", 0)
line.add val.toFloat.formatFloat(ffDecimal, 2).align(7)
echo line
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
template runTest(mat: Matrix) =
## Run a test using matrix "mat".
 
echo "Original matrix:"
echo mat
echo "Reduced row echelon form:"
mat.transformToRref()
echo mat
echo ""
 
 
var m1 = [[ 1, 2, -1, -4],
[ 2, 3, -1, -11],
[-2, 0, -3, 22]].toMatrix()
 
var m2 = [[2, 0, -1, 0, 0],
[1, 0, 0, -1, 0],
[3, 0, 0, -2, -1],
[0, 1, 0, 0, -2],
[0, 1, -1, 0, 0]].toMatrix()
 
var m3 = [[1, 2, 3, 4, 3, 1],
[2, 4, 6, 2, 6, 2],
[3, 6, 18, 9, 9, -6],
[4, 8, 12, 10, 12, 4],
[5, 10, 24, 11, 15, -4]].toMatrix()
 
var m4 = [[0, 1],
[1, 2],
[0, 5]].toMatrix()
 
runTest(m1)
runTest(m2)
runTest(m3)
runTest(m4)</syntaxhighlight>
 
{{out}}
<pre>Original matrix:
1.00 2.00 -1.00 -4.00
2.00 3.00 -1.00 -11.00
-2.00 0.00 -3.00 22.00
 
Reduced row echelon form:
1.00 0.00 0.00 -8.00
0.00 1.00 0.00 1.00
0.00 0.00 1.00 -2.00
 
 
Original matrix:
2.00 0.00 -1.00 0.00 0.00
1.00 0.00 0.00 -1.00 0.00
3.00 0.00 0.00 -2.00 -1.00
0.00 1.00 0.00 0.00 -2.00
0.00 1.00 -1.00 0.00 0.00
 
Reduced row echelon form:
1.00 0.00 0.00 0.00 -1.00
0.00 1.00 0.00 0.00 -2.00
0.00 0.00 1.00 0.00 -2.00
0.00 0.00 0.00 1.00 -1.00
0.00 0.00 0.00 0.00 0.00
 
 
Original matrix:
1.00 2.00 3.00 4.00 3.00 1.00
2.00 4.00 6.00 2.00 6.00 2.00
3.00 6.00 18.00 9.00 9.00 -6.00
4.00 8.00 12.00 10.00 12.00 4.00
5.00 10.00 24.00 11.00 15.00 -4.00
 
Reduced row echelon form:
1.00 2.00 0.00 0.00 3.00 4.00
0.00 0.00 1.00 0.00 0.00 -1.00
0.00 0.00 0.00 1.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00
 
 
Original matrix:
0.00 1.00
1.00 2.00
0.00 5.00
 
Reduced row echelon form:
1.00 0.00
0.00 1.00
0.00 0.00</pre>
 
===Using floats===
When using floats, we have to be careful when doing comparisons. The previous program adapted to use floats instead of rationals may give wrong results. This would be the case with the second matrix. To get the right result, we have to do a comparison to an epsilon rather than zero. Here is the program modified to work with floats:
<syntaxhighlight lang="nim">import strutils, strformat
 
const Eps = 1e-10
 
type Matrix[M, N: static Positive] = array[M, array[N, float]]
 
 
func toMatrix[M, N: static Positive](a: array[M, array[N, int]]): Matrix[M, N] =
## Convert a matrix of integers to a matrix of floats.
for i in 0..<M:
for j in 0..<N:
result[i][j] = a[i][j].toFloat
 
 
func transformToRref(mat: var Matrix) =
## Transform the given matrix to reduced row echelon form.
 
var lead = 0
 
for r in 0..<mat.M:
 
if lead >= mat.N: return
 
var i = r
while mat[i][lead] == 0:
inc i
if i == mat.M:
i = r
inc lead
if lead == mat.N: return
swap mat[i], mat[r]
 
let d = mat[r][lead]
if abs(d) > Eps: # Checking "d != 0" will give wrong results in some cases.
for item in mat[r].mitems:
item /= d
 
for i in 0..<mat.M:
if i != r:
let m = mat[i][lead]
for c in 0..<mat.N:
mat[i][c] -= mat[r][c] * m
 
inc lead
 
 
proc `$`(mat: Matrix): string =
## Display a matrix.
 
for row in mat:
var line = ""
for val in row:
line.addSep(" ", 0)
line.add &"{val:7.2f}"
echo line
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
template runTest(mat: Matrix) =
## Run a test using matrix "mat".
 
echo "Original matrix:"
echo mat
echo "Reduced row echelon form:"
mat.transformToRref()
echo mat
echo ""
 
 
var m1 = [[ 1, 2, -1, -4],
[ 2, 3, -1, -11],
[-2, 0, -3, 22]].toMatrix()
 
var m2 = [[2, 0, -1, 0, 0],
[1, 0, 0, -1, 0],
[3, 0, 0, -2, -1],
[0, 1, 0, 0, -2],
[0, 1, -1, 0, 0]].toMatrix()
 
var m3 = [[1, 2, 3, 4, 3, 1],
[2, 4, 6, 2, 6, 2],
[3, 6, 18, 9, 9, -6],
[4, 8, 12, 10, 12, 4],
[5, 10, 24, 11, 15, -4]].toMatrix()
 
var m4 = [[0, 1],
[1, 2],
[0, 5]].toMatrix()
 
runTest(m1)
runTest(m2)
runTest(m3)
runTest(m4)</syntaxhighlight>
 
{{Out}}
Same result as that of the program working with rationals (at least for the matrices used here).
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
class RowEchelon {
function : Main(args : String[]) ~ Nil {
Line 2,020 ⟶ 3,905:
}
}
</syntaxhighlight>
</lang>
 
=={{header|OCaml}}==
<langsyntaxhighlight OCamllang="ocaml">let swap_rows m i j =
let tmp = m.(i) in
m.(i) <- m.(j);
Line 2,073 ⟶ 3,958:
) row;
print_newline()
) m</langsyntaxhighlight>
 
Another implementation:
<langsyntaxhighlight OCamllang="ocaml">let rref m =
let nr, nc = Array.length m, Array.length m.(0) in
let add r s k =
Line 2,103 ⟶ 3,988:
print_newline();
rref mat;
show mat</langsyntaxhighlight>
 
=={{header|Octave}}==
<langsyntaxhighlight lang="octave">A = [ 1, 2, -1, -4; 2, 3, -1, -11; -2, 0, -3, 22];
refA = rref(A);
disp(refA);</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
PARI has a built-in matrix type, but no commands for row-echelon form. This Ais dimension-limiteda basic one canimplementing be constructed from the builtGauss-in <code>matsolve</code>Jordan command:reduction.
<langsyntaxhighlight lang="parigp">rrefmatrref(M)={
{
my(s=matsize(M),t=s[1]);
for(i=1,s[2],
if(M[t,i]==0, next);
M[t,] /= M[t,i];
for(j=1,t-1,
M[j,] -= M[j,i]*M[t,]
);
for(j=t+1,s[1],
M[j,] -= M[j,i]*M[t,]
);
if(t--<1,break)
);
M;
}
addhelp(matrref, "matrref(M): Returns the reduced row-echelon form of the matrix M.");</syntaxhighlight>
 
A faster, dimension-limited one can be constructed from the built-in <code>matsolve</code> command:
<syntaxhighlight lang="parigp">rref(M)={
my(d=matsize(M));
if(d[1]+1 != d[2], error("Bad size in rref"), d=d[1]);
concat(matid(d), matsolve(matrix(d,d,x,y,M[x,y]), M[,d+1]))
};</langsyntaxhighlight>
Example:
<langsyntaxhighlight lang="parigp">rref([1,2,-1,-4;2,3,-1,-11;-2,0,-3,22])</langsyntaxhighlight>
{{out}}
Output:
<pre>%1 =
[1 0 0 -8]
Line 2,129 ⟶ 4,033:
=={{header|Perl}}==
{{trans|Python}}
Note that the function defined here takes an array reference, notwhich anis arraymodified in place.
<langsyntaxhighlight lang="perl">sub rref
{our @m; local *m = shift;
@m or return;
Line 2,154 ⟶ 4,058:
$_ -= $lv * $mr[++$n] foreach @{ $m[$i] };}
 
++$lead;}}</lang>
 
sub display { join("\n" => map join(" " => map(sprintf("%4d", $_), @$_)), @{+shift})."\n" }
=={{header|Perl 6}}==
{{trans|Perl}}
{{works with|Rakudo|2010.12}}
<lang perl6>sub rref (@m is rw) {
@m or return;
my ($lead, $rows, $cols) = 0, +@m, +@m[0];
for ^$rows -> $r {
$lead < $cols or return @m;
my $i = $r;
until @m[$i][$lead] {
++$i == $rows or next;
$i = $r;
++$lead == $cols and return @m;
}
 
@m =
@m[$i, $r] = @m[$r, $i];
(
 
[ 1, 2, my $lv-1, = @m[$r][$lead-4 ];,
[ 2, 3, @m[$r] »/=»-1, $lv;-11 ],
[ -2, 0, -3, 22 ]
 
for ^$rows -> $n {
next if $n == $r;
@m[$n] »-=» @m[$r] »*» @m[$n][$lead];
}
++$lead;
}
@m;
}
 
sub rat_or_int ($num is rw) {
return $num unless $num ~~ Rat;
return $num.Int if $num.denominator == 1;
return $num.perl;
}
sub say_it ($message, @array) {
say "\n$message";
$_».&rat_or_int.fmt(" %5s").say for @array;
}
 
my @M = (
[ # base test case
[ 1, 2, -1, -4 ],
[ 2, 3, -1, -11 ],
[ -2, 0, -3, 22 ],
],
[ # mix of number styles
[ 3, 0, -3, 1 ],
[ .5, 3/2, -3, -2 ],
[ .2, 4/5, -1.6, .3 ],
],
[ # degenerate case
[ 1, 2, 3, 4, 3, 1],
[ 2, 4, 6, 2, 6, 2],
[ 3, 6, 18, 9, 9, -6],
[ 4, 8, 12, 10, 12, 4],
[ 5, 10, 24, 11, 15, -4],
],
[ # larger matrix
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0],
]
);
 
rref(\@m);
for @M -> @matrix {
print display(\@m);</syntaxhighlight>
say_it( 'Original Matrix', @matrix );
{{out}}
say_it( 'Reduced Row Echelon Form Matrix', rref(@matrix) );
<pre> 1 0 0 -8
say "\n";
0 1 0 1
}</lang>
0 0 1 -2</pre>
 
Perl 6 handles rational numbers internally as a ratio of two integers to maintain precision. For some situations it is useful to return the ratio rather than the floating point result.
 
Output:<pre>
Original Matrix
1 2 -1 -4
2 3 -1 -11
-2 0 -3 22
 
Reduced Row Echelon Form Matrix
1 0 0 -8
0 1 0 1
0 0 1 -2
 
 
 
Original Matrix
3 0 -3 1
1/2 3/2 -3 -2
1/5 4/5 -8/5 3/10
 
Reduced Row Echelon Form Matrix
1 0 0 -41/2
0 1 0 -217/6
0 0 1 -125/6
 
 
 
Original Matrix
1 2 3 4 3 1
2 4 6 2 6 2
3 6 18 9 9 -6
4 8 12 10 12 4
5 10 24 11 15 -4
 
Reduced Row Echelon Form Matrix
1 2 0 0 3 4
0 0 1 0 0 -1
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
 
=={{header|Phix}}==
 
{{Trans|Euphoria}}
 
<!--<syntaxhighlight lang="phix">(phixonline)-->
Original Matrix
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
1 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0 0
<span style="color: #008080;">function</span> <span style="color: #000000;">ToReducedRowEchelonForm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">)</span>
1 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">lead</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
1 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0
<span style="color: #000000;">rowCount</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M</span><span style="color: #0000FF;">),</span>
0 1 0 0 0 0 1 0 0 0 0 0 0 0 -1 0 0 0
<span style="color: #000000;">columnCount</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
0 1 0 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 0
<span style="color: #000000;">i</span>
0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1 0
<span style="color: #008080;">for</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">rowCount</span> <span style="color: #008080;">do</span>
0 0 1 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0
<span style="color: #008080;">if</span> <span style="color: #000000;">lead</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">columnCount</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
0 0 1 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 -1 0 0
<span style="color: #008080;">while</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">lead</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
0 0 0 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
0 0 0 0 1 0 0 1 0 0 0 0 0 -1 0 0 0 0
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">rowCount</span> <span style="color: #008080;">then</span>
0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 -1 0
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 -1 0 0
<span style="color: #000000;">lead</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
<span style="color: #008080;">if</span> <span style="color: #000000;">lead</span><span style="color: #0000FF;">=</span><span style="color: #000000;">columnCount</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
0 0 0 0 0 1 0 0 0 0 1 0 0 0 -1 0 0 0
<span style="color: #004080;">object</span> <span style="color: #000000;">mr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">lead</span><span style="color: #0000FF;">])</span>
 
<span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span>
Reduced Row Echelon Form Matrix
<span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mr</span>
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17/39
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">rowCount</span> <span style="color: #008080;">do</span>
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4/13
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">r</span> <span style="color: #008080;">then</span>
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20/39
<span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">lead</span><span style="color: #0000FF;">],</span><span style="color: #000000;">M</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]))</span>
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 28/39
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 19/39
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
<span style="color: #000000;">lead</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 8/39
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 11/39
<span style="color: #008080;">return</span> <span style="color: #000000;">M</span>
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1/3
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 20/39
<span style="color: #0000FF;">?</span> <span style="color: #000000;">ToReducedRowEchelonForm</span><span style="color: #0000FF;">(</span>
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 25/39
<span style="color: #0000FF;">{</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">4</span> <span style="color: #0000FF;">},</span>
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 28/39
<span style="color: #0000FF;">{</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">11</span> <span style="color: #0000FF;">},</span>
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 10/13
<span style="color: #0000FF;">{</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">22</span> <span style="color: #0000FF;">}</span> <span style="color: #0000FF;">})</span>
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 20/39
<!--</syntaxhighlight>-->
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
{{out}}
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 32/39
<pre>
{{1,0,0,-8},{0,1,0,1},{0,0,1,-2}}
</pre>
 
Re-implemented without the pseudocode, expressed as elementary matrix row operations. See
http://unapologetic.wordpress.com/2009/08/27/elementary-row-and-column-operations/
and
http://unapologetic.wordpress.com/2009/09/03/reduced-row-echelon-form/
 
First, a procedural version:
<lang perl6>sub swap_rows ( @M, $r1, $r2 ) { @M[ $r1, $r2 ] = @M[ $r2, $r1 ] };
sub scale_row ( @M, $scale, $r ) { @M[$r] = @M[$r] X* $scale };
sub shear_row ( @M, $scale, $r1, $r2 ) { @M[$r1] = @M[$r1] Z+ ( @M[$r2] X* $scale ) };
sub reduce_row ( @M, $r, $c ) { scale_row( @M, 1/@M[$r][$c], $r ) };
sub clear_column ( @M, $r, $c ) {
for @M.keys.grep( * != $r ) -> $row_num {
shear_row( @M, -1*@M[$row_num][$c], $row_num, $r );
}
}
 
my @M = (
[< 1 2 -1 -4 >],
[< 2 3 -1 -11 >],
[< -2 0 -3 22 >],
);
 
my $column_count = +@( @M[0] );
 
my $current_col = 0;
while all( @M».[$current_col] ) == 0 {
$current_col++;
return if $current_col == $column_count; # Matrix was all-zeros.
}
 
for @M.keys -> $current_row {
reduce_row( @M, $current_row, $current_col );
clear_column( @M, $current_row, $current_col );
$current_col++;
return if $current_col == $column_count;
}
 
say @($_)».fmt(' %4g') for @M;</lang>
 
And the same code, recast into OO. Also, scale and shear are recast as unscale and unshear, which fit the problem better.
<lang perl6>class Matrix is Array {
method unscale_row ( @M: $scale, $row ) {
@M[$row] = @M[$row] X/ $scale;
}
method unshear_row ( @M: $scale, $r1, $r2 ) {
@M[$r1] = @M[$r1] Z- ( @M[$r2] X* $scale );
}
method reduce_row ( @M: $row, $col ) {
@M.unscale_row( @M[$row][$col], $row );
}
method clear_column ( @M: $row, $col ) {
for @M.keys.grep( * != $row ) -> $scanning_row {
@M.unshear_row( @M[$scanning_row][$col], $scanning_row, $row );
}
}
method reduced_row_echelon_form ( @M: ) {
my $column_count = +@( @M[0] );
 
my $current_col = 0;
# Skip past all-zero columns.
while all( @M».[$current_col] ) == 0 {
$current_col++;
return if $current_col == $column_count; # Matrix was all-zeros.
}
 
for @M.keys -> $current_row {
@M.reduce_row( $current_row, $current_col );
@M.clear_column( $current_row, $current_col );
$current_col++;
return if $current_col == $column_count;
}
}
}
 
my $M = Matrix.new.push(
[< 1 2 -1 -4 >],
[< 2 3 -1 -11 >],
[< -2 0 -3 22 >],
);
 
$M.reduced_row_echelon_form;
 
say @($_)».fmt(' %4g') for @($M);</lang>
 
Note that both versions can be simplified using Z+=, Z-=, X*=, and X/= to scale and shear. Currently, Rakudo has a bug related to Xop= and Zop=.
 
Note that the negative zeros in the output are innocuous, and also occur in the Perl 5 version.
 
=={{header|PHP}}==
{{works with|PHP|5.x}}
{{trans|Java}}
<langsyntaxhighlight lang="php"><?php
 
function rref($matrix)
Line 2,462 ⟶ 4,168:
return $matrix;
}
?></langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de reducedRowEchelonForm (Mat)
(let (Lead 1 Cols (length (car Mat)))
(for (X Mat X (cdr X))
Line 2,487 ⟶ 4,193:
(car X) ) ) ) )
(T (> (inc 'Lead) Cols)) ) )
Mat )</langsyntaxhighlight>
{{out}}
Output:
<pre>(reducedRowEchelonForm
'(( 1 2 -1 -4) ( 2 3 -1 -11) (-2 0 -3 22)) )
Line 2,495 ⟶ 4,201:
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">def ToReducedRowEchelonForm( M):
if not M: return
lead = 0
Line 2,529 ⟶ 4,235:
 
for rw in mtx:
print ', '.join( (str(rv) for rv in rw) )</langsyntaxhighlight>
 
=={{header|R}}==
{{trans|Fortran}}
<langsyntaxhighlight lang="rsplus">rref <- function(m) {
pivot <- 1
norow <- nrow(m)
Line 2,565 ⟶ 4,271:
-2, 0, -3, 22), 3, 4, byrow=TRUE)
print(m)
print(rref(m))</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require math)
Line 2,578 ⟶ 4,284:
[2 3 -1 -11]
[-2 0 -3 22]]))
</syntaxhighlight>
</lang>
{{out}}
Output:
<pre>
(mutable-array
Line 2,587 ⟶ 4,293:
</pre>
 
=={{header|REXXRaku}}==
(formerly Perl 6)
Reduced Row Rchelon Form on a matrix, with optimization added.
<lang rexx>/*REXX program to perform Reduced Row Echelon Form (RREF) on a matrix. */
cols=0 /*maximum columns in any row. */
maxW=0 /*maximum width of any element. */
@.= /*matrix to be constructed. */
mat.=
mat.1 = ' 1 2 -1 -4 '
mat.2 = ' 2 3 -1 -11 '
mat.3 = ' -2 0 -3 22 '
 
=== Following pseudocode ===
do r=1 until mat.r==''; _=mat.r /*build @.row.col from mat.n */
{{trans|Perl}}
do c=1 until _=''; parse var _ @.r.c _
<syntaxhighlight lang="raku" line>sub rref (@m) {
maxW = max(maxW, length(@.r.c))
my ($lead, $rows, $cols) = 0, @m, @m[0];
end /*c*/
for ^$rows -> $r {
cols = max(cols,c)
return @m unless $lead < $cols;
end
my $i = $r;
until @m[$i;$lead] {
next unless ++$i == $rows;
$i = $r;
return @m if ++$lead == $cols;
}
@m[$i, $r] = @m[$r, $i] if $r != $i;
@m[$r] »/=» $ = @m[$r;$lead];
 
for ^$rows -> $n {
rows = r - 1 /*adjust the row count. */
next if $n == $r;
maxW = maxW + 1 /*bump the max width, better view*/
@m[$n] »-=» @m[$r] »×» (@m[$n;$lead] // 0);
call showMat 'original matrix' /*show the original matrix. */
}
! = 1 /*set the pointer to one. */
++$lead;
/*═══════════════════════════════════Reduced Row Echelon Form on matrix.*/
}
do r=1 for rows while cols>! /*start to do the heavy lifting. */
j=r @m
}
do while @.j.!==0; j = j+1
if j==rows then do
j = r
! = ! + 1; if cols==! then leave r
end
end /*while*/
 
sub rat-or-int ($num) {
do w=1 for cols while j\==r /*swap rows J,R (but not if same)*/
return $num unless $num ~~ Rat;
parse value @.r.w @.j.w with @.j.w @.w.w
return $num.narrow if $num.narrow ~~ Int;
end /*w*/
$num.nude.join: '/';
?=@.r.!
}
do d=1 for cols while ?\=1 /*divide row J by @.r.p--unless 1*/
@.r.d = @.r.d / ?
end /*d*/
 
sub say_it ($message, @array) {
do k=1 for rows /*sub (row K) *@.r.s from row K */
say "\n$message";
if k==r then iterate /*skip if row k is the same as R */
$_».&rat-or-int.fmt(" %5s").say for @array;
?=@.k.!
}
do s=1 for cols while ?\=0 /*but not if @.r.! is 0*/
@.k.s = @.k.s - ? * @.r.s
end /*s*/
end /*k*/
!=!+1
end /*r*/
 
my @M = (
call showMat 'matrix RREF' /*show reduced row echelon form. */
[ # base test case
exit /*stick a fork in it, we're done.*/
[ 1, 2, -1, -4 ],
/*──────────────────────────────────SHOWMAT subroutine──────────────────*/
[ 2, 3, -1, -11 ],
showMat: parse arg title; say
[ -2, 0, -3, 22 ],
say center(title,3+(cols+1)*maxW,'─'); say /*build a pretty title.*/
],
[ # mix of number styles
[ 3, 0, -3, 1 ],
[ .5, 3/2, -3, -2 ],
[ .2, 4/5, -1.6, .3 ],
],
[ # degenerate case
[ 1, 2, 3, 4, 3, 1],
[ 2, 4, 6, 2, 6, 2],
[ 3, 6, 18, 9, 9, -6],
[ 4, 8, 12, 10, 12, 4],
[ 5, 10, 24, 11, 15, -4],
],
[ # larger matrix
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0],
]
);
 
for @M -> @matrix {
say_it( 'Original Matrix', @matrix );
say_it( 'Reduced Row Echelon Form Matrix', rref(@matrix) );
say "\n";
}</syntaxhighlight>
 
Raku handles rational numbers internally as a ratio of two integers
to maintain precision.
For some situations it is useful to return the ratio
rather than the floating point result.
 
{{out}}
<pre style="height:70ex">
Original Matrix
1 2 -1 -4
2 3 -1 -11
-2 0 -3 22
 
Reduced Row Echelon Form Matrix
1 0 0 -8
0 1 0 1
0 0 1 -2
 
Original Matrix
3 0 -3 1
1/2 3/2 -3 -2
1/5 4/5 -8/5 3/10
 
Reduced Row Echelon Form Matrix
1 0 0 -41/2
0 1 0 -217/6
0 0 1 -125/6
 
Original Matrix
1 2 3 4 3 1
2 4 6 2 6 2
3 6 18 9 9 -6
4 8 12 10 12 4
5 10 24 11 15 -4
 
Reduced Row Echelon Form Matrix
1 2 0 0 3 4
0 0 1 0 0 -1
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
 
Original Matrix
1 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0 0
1 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0
0 1 0 0 0 0 1 0 0 0 0 0 0 0 -1 0 0 0
0 1 0 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1 0
0 0 1 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0
0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 -1 0 0
0 0 0 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0
0 0 0 0 1 0 0 1 0 0 0 0 0 -1 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 -1 0
0 0 0 0 1 0 0 0 0 0 1 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 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 1 0 0 0 0 1 0 0 0 -1 0 0 0
 
Reduced Row Echelon Form Matrix
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17/39
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4/13
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20/39
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 28/39
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 19/39
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 8/39
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 11/39
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1/3
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 20/39
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 25/39
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 28/39
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 10/13
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 20/39
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 32/39
</pre>
 
=== Row operations, procedural code ===
Re-implemented as elementary matrix row operations. Follow links for background on
[http://unapologetic.wordpress.com/2009/08/27/elementary-row-and-column-operations/ row operations]
and
[http://unapologetic.wordpress.com/2009/09/03/reduced-row-echelon-form/ reduced row echelon form]
 
<syntaxhighlight lang="raku" line>sub scale-row ( @M, \scale, \r ) { @M[r] = @M[r] »×» scale }
sub shear-row ( @M, \scale, \r1, \r2 ) { @M[r1] = @M[r1] »+» ( @M[r2] »×» scale ) }
sub reduce-row ( @M, \r, \c ) { scale-row @M, 1/@M[r;c], r }
sub clear-column ( @M, \r, \c ) { shear-row @M, -@M[$_;c], $_, r for @M.keys.grep: * != r }
 
my @M = (
[< 1 2 -1 -4 >],
[< 2 3 -1 -11 >],
[< -2 0 -3 22 >],
);
 
my $column-count = @M[0];
my $col = 0;
for @M.keys -> $row {
reduce-row( @M, $row, $col );
clear-column( @M, $row, $col );
last if ++$col == $column-count;
}
 
say @$_».fmt(' %4g') for @M;</syntaxhighlight>
{{out}}
<pre>[ 1 0 0 -8]
[ 0 1 0 1]
[ 0 0 1 -2]</pre>
 
=== Row operations, object-oriented code ===
The same code as previous section, recast into OO. Also, scale and shear are recast as unscale and unshear, which fit the problem better.
<syntaxhighlight lang="raku" line>class Matrix is Array {
method unscale-row ( @M: \scale, \row ) { @M[row] = @M[row] »/» scale }
method unshear-row ( @M: \scale, \r1, \r2 ) { @M[r1] = @M[r1] »-» @M[r2] »×» scale }
method reduce-row ( @M: \row, \col ) { @M.unscale-row( @M[row;col], row ) }
method clear-column ( @M: \row, \col ) { @M.unshear-row( @M[$_;col], $_, row ) for @M.keys.grep: * != row }
 
method reduced-row-echelon-form ( @M: ) {
my $column-count = @M[0];
my $col = 0;
for @M.keys -> $row {
@M.reduce-row( $row, $col );
@M.clear-column( $row, $col );
return if ++$col == $column-count;
}
}
}
 
my $M = Matrix.new(
[< 1 2 -1 -4 >],
[< 2 3 -1 -11 >],
[< -2 0 -3 22 >],
);
 
$M.reduced-row-echelon-form;
say @$_».fmt(' %4g') for @$M;</syntaxhighlight>
{{out}}
<pre>[ 1 0 0 -8]
[ 0 1 0 1]
[ 0 0 1 -2]</pre>
 
=={{header|REXX}}==
''Reduced Row Echelon Form'' &nbsp; (a.k.a. &nbsp; ''row canonical form'') &nbsp; of a matrix, with optimization added.
<syntaxhighlight lang="rexx">/*REXX pgm performs Reduced Row Echelon Form (RREF), AKA row canonical form on a matrix)*/
cols= 0; w= 0; @. =0 /*max cols in a row; max width; matrix.*/
mat.=; mat.1= ' 1 2 -1 -4 '
mat.2= ' 2 3 -1 -11 '
mat.3= ' -2 0 -3 22 '
do r=1 until mat.r==''; _=mat.r /*build @.row.col from (matrix) mat.X*/
do c=1 until _=''; parse var _ @.r.c _
w= max(w, length(@.r.c) + 1) /*find the maximum width of an element.*/
end /*c*/
cols= max(cols, c) /*save the maximum number of columns. */
end /*r*/
rows= r-1 /*adjust the row count (from DO loop). */
call showMat 'original matrix' /*display the original matrix──►screen.*/
!= 1 /*set the working column pointer to 1.*/
/* ┌──────────────────────◄────────────────◄──── Reduced Row Echelon Form on matrix.*/
do r=1 for rows while cols>! /*begin to perform the heavy lifting. */
j= r /*use a subsitute index for the DO loop*/
do while @.j.!==0; j= j + 1
if j==rows then do; j= r; != ! + 1; if cols==! then leave r; end
end /*while*/
/* [↓] swap rows J,R (but not if same)*/
do _=1 for cols while j\==r; parse value @.r._ @.j._ with @.j._ @._._
end /*_*/
?= @.r.!
do d=1 for cols while ?\=1; @.r.d= @.r.d / ?
end /*d*/ /* [↑] divide row J by @.r.p ──unless≡1*/
do k=1 for rows; ?= @.k.! /*subtract (row K) @.r.s from row K.*/
if k==r | ?=0 then iterate /*skip if row K is the same as row R.*/
do s=1 for cols; @.k.s= @.k.s - ? * @.r.s
end /*s*/
end /*k*/ /* [↑] for the rest of numbers in row.*/
!= !+1 /*bump the working column pointer. */
end /*r*/
 
call showMat 'matrix RREF' do r =1 for rows; _=/*display the reduced row echelon form.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
showMat: parse arg title; say; say center(title, 3 + (cols+1) * w, '─'); say
do r=1 for rows; _=
do c=1 for cols
if @.r.c=='' then do; say; say '"*** error! ***'; matrix element sayisn't defined:"
say 'row' r"matrix, element isncolumn" c't.'; defined:" exit 13
say 'row' row", column" c'.'; say
exit 13
end
_ = _ right(@.r.c,maxW w)
end /*c*/
say _ /*display a matrix row to the terminal.*/
say _
end /*r*/; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default (internal) input:}}
return</lang>
'''output'''
<pre>
────original matrix────
Line 2,668 ⟶ 4,581:
0 1 0 1
0 0 1 -2
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Reduced row echelon form
 
matrix = [[1, 2, -1, -4],
[2, 3, -1, -11],
[ -2, 0, -3, 22]]
ref(matrix)
for row = 1 to 3
for col = 1 to 4
if matrix[row][col] = -0
see "0 "
else
see "" + matrix[row][col] + " "
ok
next
see nl
next
func ref(m)
nrows = 3
ncols = 4
lead = 1
for r = 1 to nrows
if lead >= ncols
exit
ok
i = r
while m[i][lead] = 0
i = i + 1
if i = nrows
i = r
lead = lead + 1
if lead = ncols
exit 2
ok
ok
end
for j = 1 to ncols
temp = m[i][j]
m[i][j] = m[r][j]
m[r][j] = temp
next
n = m[r][lead]
if n != 0
for j = 1 to ncols
m[r][j] = m[r][j] / n
next
ok
for i = 1 to nrows
if i != r
n = m[i][lead]
for j = 1 to ncols
m[i][j] = m[i][j] - m[r][j] * n
next
ok
next
lead = lead + 1
next
</syntaxhighlight>
Output:
<pre>
1 0 0 -8
0 1 0 1
0 0 1 -2
</pre>
 
=={{header|RPL}}==
The <code>RREF</code> built-in intruction is available for HP-48G and newer models.
[[1 2 -1 -4] [2 3 -1 -11] [-2 0 -3 22]] RREF
{{out}}
<pre>
1: [[ 1 0 0 -8 ]
[ 0 1 0 1 ]
[ 0 0 1 -2 ]]
</pre>
 
=={{header|Ruby}}==
{{works with|Ruby|1.9.3}}
<langsyntaxhighlight lang="ruby"># returns an 2-D array where each element is a Rational
def reduced_row_echelon_form(ary)
lead = 0
Line 2,742 ⟶ 4,732:
reduced = reduced_row_echelon_form(mtx)
print_matrix reduced
print_matrix convert_to(reduced, :to_f)</langsyntaxhighlight>
 
{{out}}
Line 2,756 ⟶ 4,746:
0.0 1.0 0.0 1.6666666666666667
0.0 0.0 1.0 1.0
</pre>
 
=={{header|Rust}}==
{{trans|FORTRAN}}
I have tried to avoid state mutation with respect to the input matrix and adopt as functional a style as possible in this translation, so for larger matrices one may want to consider memory usage implications.
<syntaxhighlight lang="rust">
fn main() {
let mut matrix_to_reduce: Vec<Vec<f64>> = vec![vec![1.0, 2.0 , -1.0, -4.0],
vec![2.0, 3.0, -1.0, -11.0],
vec![-2.0, 0.0, -3.0, 22.0]];
let mut r_mat_to_red = &mut matrix_to_reduce;
let rr_mat_to_red = &mut r_mat_to_red;
 
println!("Matrix to reduce:\n{:?}", rr_mat_to_red);
let reduced_matrix = reduced_row_echelon_form(rr_mat_to_red);
println!("Reduced matrix:\n{:?}", reduced_matrix);
}
 
fn reduced_row_echelon_form(matrix: &mut Vec<Vec<f64>>) -> Vec<Vec<f64>> {
let mut matrix_out: Vec<Vec<f64>> = matrix.to_vec();
let mut pivot = 0;
let row_count = matrix_out.len();
let column_count = matrix_out[0].len();
'outer: for r in 0..row_count {
if column_count <= pivot {
break;
}
let mut i = r;
while matrix_out[i][pivot] == 0.0 {
i = i+1;
if i == row_count {
i = r;
pivot = pivot + 1;
if column_count == pivot {
pivot = pivot - 1;
break 'outer;
}
}
}
for j in 0..row_count {
let temp = matrix_out[r][j];
matrix_out[r][j] = matrix_out[i][j];
matrix_out[i][j] = temp;
}
let divisor = matrix_out[r][pivot];
if divisor != 0.0 {
for j in 0..column_count {
matrix_out[r][j] = matrix_out[r][j] / divisor;
}
}
for j in 0..row_count {
if j != r {
let hold = matrix_out[j][pivot];
for k in 0..column_count {
matrix_out[j][k] = matrix_out[j][k] - ( hold * matrix_out[r][k]);
}
}
}
pivot = pivot + 1;
}
matrix_out
}
</syntaxhighlight>
Output:
<pre>
Matrix to reduce:
[[1.0, 2.0, -1.0, -4.0], [2.0, 3.0, -1.0, -11.0], [-2.0, 0.0, -3.0, 22.0]]
Reduced matrix:
[[1.0, 0.0, 0.0, -8.0], [-0.0, 1.0, 0.0, 1.0], [-0.0, -0.0, 1.0, -2.0]]
</pre>
 
=={{header|Sage}}==
{{works with|Sage|4.6.2}}
<langsyntaxhighlight lang="sage">sage: m = matrix(ZZ, [[1,2,-1,-4],[2,3,-1,-11],[-2,0,-3,22]])
sage: m.rref()
[ 1 0 0 -8]
[ 0 1 0 1]
[ 0 0 1 -2] </langsyntaxhighlight>
 
=={{header|Scheme}}==
{{Works with|Scheme|R<math>^5</math>RS}}
<langsyntaxhighlight lang="scheme">(define (reduced-row-echelon-form matrix)
(define (clean-down matrix from-row column)
(cons (car matrix)
Line 2,815 ⟶ 4,875:
indices)
indices)
indices)))</langsyntaxhighlight>
Example:
<langsyntaxhighlight lang="scheme">(define matrix
(list (list 1 2 -1 -4) (list 2 3 -1 -11) (list -2 0 -3 22)))
 
(display (reduced-row-echelon-form matrix))
(newline)</langsyntaxhighlight>
{{out}}
Output:
<syntaxhighlight lang="text">((1 0 0 -8) (0 1 0 1) (0 0 1 -2))</langsyntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">const type: matrix is array array float;
 
const proc: toReducedRowEchelonForm (inout matrix: mat) is func
Line 2,879 ⟶ 4,939:
end for;
end for;
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/math.htm#toReducedRowEchelonForm]
 
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby">func rref (M) {
var (j, rows, cols) = (0, M.len, M[0].len)
for r in (^rows) {
j < cols || return M
var i = r
while (!M[i][j]) {
++i == rows || next
i = r
++j == cols && return M
}
M[i, r] = M[r, i] if (r != i)
M[r] = (M[r] »/» M[r][j])
for n in (^rows) {
next if (n == r)
M[n] = (M[n] »-« (M[r] »*» M[n][j]))
}
++j
}
return M
}
 
func say_it (message, array) {
say "\n#{message}";
array.each { |row|
say row.map { |n| " %5s" % n.as_rat }.join
}
}
 
var M = [
[ # base test case
[ 1, 2, -1, -4 ],
[ 2, 3, -1, -11 ],
[ -2, 0, -3, 22 ],
],
[ # mix of number styles
[ 3, 0, -3, 1 ],
[ .5, 3/2, -3, -2 ],
[ .2, 4/5, -1.6, .3 ],
],
[ # degenerate case
[ 1, 2, 3, 4, 3, 1],
[ 2, 4, 6, 2, 6, 2],
[ 3, 6, 18, 9, 9, -6],
[ 4, 8, 12, 10, 12, 4],
[ 5, 10, 24, 11, 15, -4],
],
];
 
M.each { |matrix|
say_it('Original Matrix', matrix);
say_it('Reduced Row Echelon Form Matrix', rref(matrix));
say '';
}</syntaxhighlight>
{{out}}
<pre>
Original Matrix
1 2 -1 -4
2 3 -1 -11
-2 0 -3 22
 
Reduced Row Echelon Form Matrix
1 0 0 -8
0 1 0 1
0 0 1 -2
 
 
Original Matrix
3 0 -3 1
1/2 3/2 -3 -2
1/5 4/5 -8/5 3/10
 
Reduced Row Echelon Form Matrix
1 0 0 -41/2
0 1 0 -217/6
0 0 1 -125/6
 
 
Original Matrix
1 2 3 4 3 1
2 4 6 2 6 2
3 6 18 9 9 -6
4 8 12 10 12 4
5 10 24 11 15 -4
 
Reduced Row Echelon Form Matrix
1 2 0 0 3 4
0 0 1 0 0 -1
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
</pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">
var lead = 0
for r in 0..<rows {
if (cols <= lead) { break }
var i = r
while (m[i][lead] == 0) {
i += 1
if (i == rows) {
i = r
lead += 1
if (cols == lead) {
lead -= 1
break
}
}
}
for j in 0..<cols {
let temp = m[r][j]
m[r][j] = m[i][j]
m[i][j] = temp
}
let div = m[r][lead]
if (div != 0) {
for j in 0..<cols {
m[r][j] /= div
}
}
for j in 0..<rows {
if (j != r) {
let sub = m[j][lead]
for k in 0..<cols {
m[j][k] -= (sub * m[r][k])
}
}
}
lead += 1
}
</syntaxhighlight>
 
=={{header|Tcl}}==
Using utility procs defined at [[Matrix Transpose#Tcl]]
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace path {::tcl::mathop ::tcl::mathfunc}
 
Line 2,933 ⟶ 5,132:
set m {{1 2 -1 -4} {2 3 -1 -11} {-2 0 -3 22}}
print_matrix $m
print_matrix [toRREF $m]</langsyntaxhighlight>
{{out}}
outputs
<pre> 1 2 -1 -4
2 3 -1 -11
Line 2,941 ⟶ 5,140:
-0.0 1.0 0.0 1.0
-0.0 -0.0 1.0 -2.0 </pre>
 
=={{header|TI-83 BASIC}}==
Builtin function: rref()
<syntaxhighlight lang="ti83">rref([[1,2,-1,-4][2,3,-1,-11][-2,0,-3,22]])</syntaxhighlight>
{{out}}
<pre>
[[1 0 0 -8]
[0 1 0 1]
[0 0 1 -2]]
</pre>
 
=={{header|TI-89 BASIC}}==
<langsyntaxhighlight lang="ti89b">rref([1,2,–1,–4; 2,3,–1,–11; –2,0,–3,22])</langsyntaxhighlight>
 
Output (in prettyprint mode): <math>\begin{bmatrix} 1&0&0&-8 \\ 0&1&0&1 \\ 0&0&1&-2 \end{bmatrix}</math>
 
Matrices can also be stored in variables, and entered interactively using the Data/Matrix Editor.
using the Data/Matrix Editor.
 
=={{header|Ursala}}==
The most convenient representation for a matrix in Ursala is as a list of lists.
Several auxiliary functions are defined to make this task more manageable.
The pivot function reorders the rows to position the first column entry with maximum
with maximum magnitude in the first row.
The descending function is a second order function abstracting the pattern
of recursion down the major diagonal of a matrix. The reflect function allows
The reflect function allows the code for the first phase in the reduction to be reused during the upward
to be reused during the upward traversal by appropriately permuting
traversal by appropriately permuting the rows and columns. The row_reduce function
the rows and columns.
adds a multiple of the top row to each subsequent row so as to cancel the
The row_reduce function adds a multiple of the top row to each
first column. These are all combined in the main rref function.
subsequent row so as to cancel the first column.
These are all combined in the main rref function.
 
<langsyntaxhighlight Ursalalang="ursala">#import std
#import flo
 
Line 2,977 ⟶ 5,189:
<1.,2.,-1.,-4.>,
<2.,3.,-1.,-11.>,
<-2.,0.,-3.,22.>></langsyntaxhighlight>
{{out}}
output:
<pre>
1.0000 0.0000 0.0000 -8.0000
0.0000 1.0000 0.0000 1.0000
0.0000 0.0000 1.0000 -2.0000</pre>
An alternative and more efficient solution is to use the
to use the msolve library function as shown, which interfaces with the lapack library if
which interfaces with the lapack library if available.
available. This solution is applicable only if the input is a non-singular
This solution is applicable only if the input
augmented square matrix.
is a non-singular augmented square matrix.
<lang Ursala>#import lin
<syntaxhighlight lang="ursala">#import lin
 
rref = @ySzSX msolve; ^plrNCTS\~& ~&iiDlSzyCK9+ :/1.+ 0.!*t</langsyntaxhighlight>
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Private Function ToReducedRowEchelonForm(M As Variant) As Variant
Dim lead As Integer: lead = 0
Dim rowCount As Integer: rowCount = UBound(M)
Dim columnCount As Integer: columnCount = UBound(M(0))
Dim i As Integer
For r = 0 To rowCount
If lead >= columnCount Then
Exit For
End If
i = r
Do While M(i)(lead) = 0
i = i + 1
If i = rowCount Then
i = r
lead = lead + 1
If lead = columnCount Then
Exit For
End If
End If
Loop
Dim tmp As Variant
tmp = M(r)
M(r) = M(i)
M(i) = tmp
If M(r)(lead) <> 0 Then
div = M(r)(lead)
For t = LBound(M(r)) To UBound(M(r))
M(r)(t) = M(r)(t) / div
Next t
End If
For j = 0 To rowCount
If j <> r Then
subt = M(j)(lead)
For t = LBound(M(j)) To UBound(M(j))
M(j)(t) = M(j)(t) - subt * M(r)(t)
Next t
End If
Next j
lead = lead + 1
Next r
ToReducedRowEchelonForm = M
End Function
Public Sub main()
r = ToReducedRowEchelonForm(Array( _
Array(1, 2, -1, -4), _
Array(2, 3, -1, -11), _
Array(-2, 0, -3, 22)))
For i = LBound(r) To UBound(r)
Debug.Print Join(r(i), vbTab)
Next i
End Sub</syntaxhighlight>{{out}}
<pre>1 0 0 -8
0 1 0 1
0 0 1 -2</pre>
 
=={{header|Visual FoxPro}}==
Translation of Fortran.
<syntaxhighlight lang="vfp">
CLOSE DATABASES ALL
LOCAL lnRows As Integer, lnCols As Integer, lcSafety As String
LOCAL ARRAY matrix[1]
lcSafety = SET("Safety")
SET SAFETY OFF
CLEAR
CREATE CURSOR results (c1 B(6), c2 B(6), c3 B(6), c4 B(6))
CREATE CURSOR curs1(c1 I, c2 I, c3 I, c4 I)
INSERT INTO curs1 VALUES (1,2,-1,-4)
INSERT INTO curs1 VALUES (2,3,-1,-11)
INSERT INTO curs1 VALUES (-2,0,-3,22)
lnRows = RECCOUNT() && 3
lnCols = FCOUNT() && 4
SELECT * FROM curs1 INTO ARRAY matrix
IF RREF(@matrix, lnRows, lnCols)
SELECT results
APPEND FROM ARRAY matrix
BROWSE NORMAL IN SCREEN
ENDIF
SET SAFETY &lcSafety
 
FUNCTION RREF(mat, tnRows As Integer, tnCols As Integer) As Boolean
LOCAL lnPivot As Integer, i As Integer, r As Integer, j As Integer, ;
p As Double. llResult As Boolean, llExit As Boolean
llResult = .T.
llExit = .F.
lnPivot = 1
FOR r = 1 TO tnRows
IF lnPivot > tnCols
EXIT
ENDIF
i = r
DO WHILE mat[i,lnPivot] = 0
i = i + 1
IF i = tnRows
i = r
lnPivot = lnPivot + 1
IF lnPivot > tnCols
llExit = .T.
EXIT
ENDIF
ENDIF
ENDDO
IF llExit
EXIT
ENDIF
ASwapRows(@mat, i, r)
p = mat[r,lnPivot]
IF p # 0
FOR j = 1 TO tnCols
mat[r,j] = mat[r,j]/p
ENDFOR
ELSE
? "Divison by zero."
llResult = .F.
EXIT
ENDIF
FOR i = 1 TO tnRows
IF i # r
p = mat[i,lnPivot]
FOR j = 1 TO tnCols
mat[i,j] = mat[i,j] - mat[r,j]*p
ENDFOR
ENDIF
ENDFOR
lnPivot = lnPivot + 1
ENDFOR
RETURN llResult
ENDFUNC
 
PROCEDURE ASwapRows(arr, tnRow1 As Integer, tnRow2 As Integer)
*!* Interchange rows tnRow1 and tnRow2 of array arr.
LOCAL n As Integer
n = ALEN(arr,2)
LOCAL ARRAY tmp[1,n]
STORE 0 TO tmp
ACPY2(@arr, @tmp, tnRow1, 1)
ACPY2(@arr, @arr, tnRow2, tnRow1)
ACPY2(@tmp, @arr, 1, tnRow2)
ENDPROC
 
PROCEDURE ACPY2(m1, m2, tnSrcRow As Integer, tnDestRow As Integer)
*!* Copy m1[tnSrcRow,*] to m2[tnDestRow,*]
*!* m1 and m2 must have the same number of columns.
LOCAL n As Integer, e1 As Integer, e2 As Integer
n = ALEN(m1,2)
e1 = AELEMENT(m1,tnSrcRow,1)
e2 = AELEMENT(m2,tnDestRow,1)
ACOPY(m1, m2, e1, n, e2)
ENDPROC
</syntaxhighlight>
{{out}}
<pre>
C1 C2 C3 C4
1.000000 0.000000 0.000000 -8.000000
0.000000 1.000000 0.000000 1.000000
0.000000 0.000000 1.000000 -2.000000
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-matrix}}
The above module has a method for this built in as it's needed to implement matrix inversion using the Gauss-Jordan method. However, as in the example here, it's not just restricted to square matrices.
<syntaxhighlight lang="wren">import "./matrix" for Matrix
import "./fmt" for Fmt
 
var m = Matrix.new([
[ 1, 2, -1, -4],
[ 2, 3, -1, -11],
[-2, 0, -3, 22]
])
 
System.print("Original:\n")
Fmt.mprint(m, 3, 0)
System.print("\nRREF:\n")
m.toReducedRowEchelonForm
Fmt.mprint(m, 3, 0)</syntaxhighlight>
 
{{out}}
<pre>
Original:
 
| 1 2 -1 -4|
| 2 3 -1 -11|
| -2 0 -3 22|
 
RREF:
 
| 1 0 0 -8|
| 0 1 0 1|
| 0 0 1 -2|
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">proc ReducedRowEchelonForm(M, Rows, Cols);
\Replace M with its reduced row echelon form
real M; int Rows, Cols;
int Lead, R, C, I;
real RLead, ILead, T;
[Lead:= 0;
for R:= 0 to Rows-1 do
[if Lead >= Cols then return;
I:= R;
while M(I, Lead) = 0. do
[I:= I+1;
if I = Rows-1 then
[I:= R;
Lead:= Lead+1;
if Lead = Cols-1 then return;
];
];
\Swap rows I and R
T:= M(I); M(I):= M(R); M(R):= T;
 
if M(R, Lead) # 0. then
\Divide row R by M[R, Lead]
[RLead:= M(R, Lead);
for C:= 0 to Cols-1 do
M(R, C):= M(R, C) / RLead;
];
 
for I:= 0 to Rows-1 do
[if I # R then
\Subtract M[I, Lead] multiplied by row R from row I
[ILead:= M(I, Lead);
for C:= 0 to Cols-1 do
M(I, C):= M(I, C) - ILead * M(R, C);
];
];
Lead:= Lead+1;
];
];
 
real M;
int R, C;
[M:= [ [ 1., 2., -1., -4.],
[ 2., 3., -1.,-11.],
[-2., 0., -3., 22.] ];
ReducedRowEchelonForm(M, 3, 4);
Format(4,1);
for R:= 0 to 3-1 do
[for C:= 0 to 4-1 do
RlOut(0, M(R,C));
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
1.0 0.0 0.0 -8.0
0.0 1.0 0.0 1.0
0.0 0.0 1.0 -2.0
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: https://rosettacode.org/wiki/Reduced_row_echelon_form
// by Jjuanhdez, 06/2022
 
dim matrix (3, 4)
matrix(1, 1) = 1 : matrix(1, 2) = 2 : matrix(1, 3) = -1 : matrix(1, 4) = -4
matrix(2, 1) = 2 : matrix(2, 2) = 3 : matrix(2, 3) = -1 : matrix(2, 4) = -11
matrix(3, 1) = -2 : matrix(3, 2) = 0 : matrix(3, 3) = -3 : matrix(3, 4) = 22
 
RREF (matrix())
 
for row = 1 to 3
for col = 1 to 4
if matrix(row, col) = 0 then
print "0", chr$(9);
else
print matrix(row, col), chr$(9);
end if
next
print
next
end
 
sub RREF(x())
local nrows, ncols, lead, r, i, j, n
nrows = arraysize(matrix(), 1) //3
ncols = arraysize(matrix(), 2) //4
lead = 1
for r = 1 to nrows
if lead >= ncols break
i = r
while matrix(i, lead) = 0
i = i + 1
if i = nrows then
i = r
lead = lead + 1
if lead = ncols break 2
end if
wend
for j = 1 to ncols
temp = matrix(i, j)
matrix(i, j) = matrix(r, j)
matrix(r, j) = temp
next
n = matrix(r, lead)
if n <> 0 then
for j = 1 to ncols
matrix(r, j) = matrix(r, j) / n
next
end if
for i = 1 to nrows
if i <> r then
n = matrix(i, lead)
for j = 1 to ncols
matrix(i, j) = matrix(i, j) - matrix(r, j) * n
next
end if
next
lead = lead + 1
next
end sub</syntaxhighlight>
 
=={{header|zkl}}==
The "best" way is to use the GNU Scientific Library:
Direct implementation of the pseudo-code given, lots of generating new rows rather than modifying the rows themselves.
<syntaxhighlight lang="zkl">var [const] GSL=Import("zklGSL"); // libGSL (GNU Scientific Library)
<lang zkl>fcn toReducedRowEchelonForm(m){ // m is modified, the rows are not
fcn toReducedRowEchelonForm(M){ // in place
lead,rows,columns := 0,M.rows,M.cols;
foreach r in (rows){
if (columns<=lead) return(M);
i:=r;
while(M[i,lead]==0){ // not a great check to use with real numbers
i+=1;
if(i==rows){
i=r; lead+=1;
if(lead==columns) return(M);
}
}
M.swapRows(i,r);
if(x:=M[r,lead]) M[r]/=x;
foreach i in (rows){ if(i!=r) M[i]-=M[r]*M[i,lead] }
lead+=1;
}
M
}</syntaxhighlight>
<syntaxhighlight lang="zkl">A:=GSL.Matrix(3,4).set( 1, 2, -1, -4,
2, 3, -1, -11,
-2, 0, -3, 22);
toReducedRowEchelonForm(A).format(5,1).println();</syntaxhighlight>
{{out}}
<pre>
1.0, 0.0, 0.0, -8.0
0.0, 1.0, 0.0, 1.0
0.0, 0.0, 1.0, -2.0
</pre>
Or, using lists of lists and direct implementation of the pseudo-code given,
lots of generating new rows rather than modifying the rows themselves.
<syntaxhighlight lang="zkl">fcn toReducedRowEchelonForm(m){ // m is modified, the rows are not
lead,rowCount,columnCount := 0,m.len(),m[1].len();
foreach r in (rowCount){
Line 3,014 ⟶ 5,574:
}//foreach
m
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">m:=List( T( 1, 2, -1, -4,), // T is read only list
T( 2, 3, -1, -11,),
T(-2, 0, -3, 22,));
Line 3,023 ⟶ 5,583:
 
fcn printM(m){ m.pump(Console.println,rowFmt) }
fcn rowFmt(row){ ("%4d "*row.len()).fmt(row.xplode()) }</langsyntaxhighlight>
{{out}}
<pre>
Line 3,034 ⟶ 5,594:
0 0 1 -2
</pre>
 
{{omit from|GUISS}}
 
== References ==
2,078

edits