QR decomposition: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(40 intermediate revisions by 18 users not shown)
Line 11:
-4 & 24 & -41 \end{pmatrix}</math>
 
and the usage for linear least squares problems on the example from [[Polynomial_regressionPolynomial regression]]. The method of [[wp: Householder transformation|Householder reflections]] should be used:
 
'''Method'''
Line 98:
=={{header|Ada}}==
Output matches that of Matlab solution, not tested with other matrices.
<syntaxhighlight lang="ada">
<lang Ada>
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
Line 193:
Put_Line ("Q:"); Show (Q);
Put_Line ("R:"); Show (R);
end QR;</langsyntaxhighlight>
{{out}}
<pre>Q:
Line 203:
-0.0000 175.0000 -70.0000
-0.0000 0.0000 35.0000</pre>
 
=={{header|ATS}}==
 
Perhaps not every template function that was written below is actually used. Much of what is below amounts to a little library for working with matrices. To treat blocks and transposes as matrices themselves, I use a trick employed in some Scheme implementations of matrices: indices are mapped by closures, and the closures can nested.
 
<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
 
(* g0float_sqrt is available in the ats2-xprelude package, but let us
quickly add it here, with implementations for the g0float types
included in the prelude. *)
extern fn {tk : tkind} g0float_sqrt : g0float tk -<> g0float tk
overload sqrt with g0float_sqrt
implement g0float_sqrt<fltknd> x = $extfcall (float, "sqrtf", x)
implement g0float_sqrt<dblknd> x = $extfcall (double, "sqrt", x)
implement g0float_sqrt<ldblknd> x = $extfcall (ldouble, "sqrtl", x)
 
(* Similarly for g0float_copysign. *)
extern fn {tk : tkind}
g0float_copysign : (g0float tk, g0float tk) -<> g0float tk
overload copysign with g0float_copysign
implement
g0float_copysign<fltknd> (x, y) =
$extfcall (float, "copysignf", x, y)
implement
g0float_copysign<dblknd> (x, y) =
$extfcall (double, "copysign", x, y)
implement
g0float_copysign<ldblknd> (x, y) =
$extfcall (ldouble, "copysignl", x, y)
 
(*------------------------------------------------------------------*)
 
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_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}
Real_Vector_l2norm_squared :
{m, n : pos}
Real_Vector (tk, m, n) -< !ref > g0float tk
 
extern fn {tk : tkind}
Real_Matrix_QR_decomposition :
{m, n : pos}
Real_Matrix (tk, m, n) -< !refwrt >
@(Real_Matrix (tk, m, m), Real_Matrix (tk, m, n))
 
extern fn {tk : tkind}
Real_Matrix_least_squares_solution :
(* This can solve p problems at once. Use p=1 to solve just Ax=b. *)
{m, n, p : pos | n <= m}
(Real_Matrix (tk, m, n), Real_Matrix (tk, m, p)) -< !refwrt >
Real_Matrix (tk, n, p)
 
extern fn {tk : tkind}
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 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
 
(* Overload for a Real_Matrix_l2norm_squared, if we decided to have
one, would be given precedence 0. *)
overload l2norm_squared with Real_Vector_l2norm_squared of 1
 
overload QR_decomposition with Real_Matrix_QR_decomposition
overload least_squares_solution with
Real_Matrix_least_squares_solution
 
(*------------------------------------------------------------------*)
 
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_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] :=
C[i, k] + (A[i, j] * B[j, 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_Vector_l2norm_squared v =
$effmask_wrt
let
val @(m, n) = dimension v
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
in
if n = 1 then
let
var sum : g0float tk
var i : intGte 1
val v11 = v[1, 1]
in
sum := v11 * v11;
for* {i : pos | i <= m + 1} .<(m + 1) - i>.
(i : int i) =>
(i := 2; i <> succ m; i := succ i)
let
val vi1 = v[i, 1]
in
sum := sum + (vi1 * vi1)
end;
sum
end
else
let
var sum : g0float tk
var j : intGte 1
val v11 = v[1, 1]
in
sum := v11 * v11;
for* {j : pos | j <= n + 1} .<(n + 1) - j>.
(j : int j) =>
(j := 2; j <> succ n; j := succ j)
let
val v1j = v[1, j]
in
sum := sum + (v1j * v1j)
end;
sum
end
end
 
implement {tk}
Real_Matrix_QR_decomposition A =
(* Some of what follows does needless allocation and work, but
making this code more efficient would be a project of its own!
Also, one would likely want to implement pivot selection. See,
for instance, Businger, P., Golub, G.H. Linear least squares
solutions by householder transformations. Numer. Math. 7, 269–276
(1965). https://doi.org/10.1007/BF01436084
(https://web.archive.org/web/20230514003458/https://pages.stat.wisc.edu/~bwu62/771/businger1965.pdf)
 
Note that I follow
https://en.wikipedia.org/w/index.php?title=QR_decomposition&oldid=1152640697#Using_Householder_reflections
more closely than I do what is stated in the task description at
the time of this writing (13 May 2023). The presentation there
seems simpler to me, and I prefer seeing a norm used to normalize
the u vector. *)
let
val @(m, n) = dimension A
prval [m : int] EQINT () = eqint_make_gint m
prval [n : int] EQINT () = eqint_make_gint n
 
stadef min_mn = min (m, n)
val min_mn : int min_mn = min (m, n)
 
var Q : Real_Matrix (tk, m, m) = unit_matrix<tk> m
val R : Real_Matrix (tk, m, n) = copy A
 
(* I_mm is a unit matrix of the maximum size used. Smaller unit
matrices will be had by the "identity" function, and unit
column vectors by the "unit_column" function. *)
val I_mm : Real_Matrix (tk, m, m) = unit_matrix<tk> m
fn
identity {p : pos | p <= m}
(p : int p) :<> Real_Matrix (tk, p, p) =
block (I_mm, 1, p, 1, p)
fn
unit_column {p, j : pos | j <= p; p <= m}
(p : int p,
j : int j) :<> Real_Column (tk, p) =
block (I_mm, 1, p, j, j)
 
var k : intGte 1
in
for* {k : pos | k <= min_mn} .<min_mn - k>.
(k : int k) =>
(k := 1; k <> min_mn; k := succ k)
let
val x = block (R, k, m, k, k)
val sigma = l2norm_squared x
 
(* Choose the sign of alpha to increase the magnitude of the
pivot. *)
val alpha = copysign (sqrt sigma, ~x[1, 1])
 
val e1 = unit_column (succ (m - k), 1)
val u = x - (alpha * e1)
val v = u * (One / sqrt (l2norm_squared u))
val I = identity (succ (m - k))
val H = I - (Two * v * transpose v)
 
(* Update R, using block operations. *)
val () = fill_with_elt<tk> (x, Zero)
val () = x[1, 1] := alpha
val R_ = block (R, k, m, succ k, n)
val Tmp = H * R_
val () = copy_to (R_, Tmp)
 
(* Update Q. *)
val Tmp = unit_matrix m
val Tmp_ = block (Tmp, k, m, k, m)
val () = copy_to (Tmp_, H)
val () = Q := Q * Tmp
in
end;
@(Q, R)
end
 
implement {tk}
Real_Matrix_least_squares_solution (A, B) =
let
(* I use this algorithm for the back substitutions:
https://algowiki-project.org/algowiki/en/index.php?title=Backward_substitution&oldid=10412#Approaches_and_features_of_implementing_the_back_substitution_algorithm_in_parallel
*)
 
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
 
val @(Q, R) = QR_decomposition<tk> A
 
(* X is initialized for back substitutions. *)
val X = block (transpose Q * B, 1, n, 1, p)
and R = block (R, 1, n, 1, n)
 
var k : intGte 1
in
(* Complete the back substitutions. *)
for* {k : pos | k <= p + 1} .<(p + 1) - k>.
(k : int k) =>
(k := 1; k <> succ p; k := succ k)
let
val x = block (X, 1, n, k, k)
var j : intGte 0
in
for* {j : nat | 0 <= j; j <= n} .<j>.
(j : int j) =>
(j := n; j <> 0; j := pred j)
let
var i : intGte 1
in
x[j, 1] := x[j, 1] / R[j, j];
for* {i : pos | i <= j} .<j - i>.
(i : int i) =>
(i := 1; i <> j; i := succ i)
x[i, 1] := x[i, 1] - (R[i, j] * x[j, 1])
end
end;
X
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
 
(*------------------------------------------------------------------*)
 
implement
main0 () =
let
stadef fltknd = dblknd
macdef i2flt = g0int2float<intknd,dblknd>
 
val A = Real_Matrix_make_elt<fltknd> (3, 3, NAN)
val () =
begin
A[1, 1] := i2flt 12;
A[2, 1] := i2flt 6;
A[3, 1] := i2flt ~4;
 
A[1, 2] := i2flt ~51;
A[2, 2] := i2flt 167;
A[3, 2] := i2flt 24;
 
A[1, 3] := i2flt 4;
A[2, 3] := i2flt ~68;
A[3, 3] := i2flt ~41
end
 
val @(Q, R) = QR_decomposition<fltknd> A
 
(* Example of least-squares solution. (Copied from the BBC BASIC
or Common Lisp entry, whichever you prefer to think it copied
from.) *)
val x = $list (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
and y = $list (1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321)
val X = Real_Matrix_make_elt<fltknd> (11, 3, NAN)
and Y = Real_Matrix_make_elt<fltknd> (11, 1, NAN)
val () =
let
var i : intGte 1
in
for* {i : pos | i <= 12} .<12 - i>.
(i : int i) =>
(i := 1; i <> 12; i := succ i)
let
val xi = x[pred i] : int
and yi = y[pred i] : int
in
X[i, 1] := g0i2f (xi ** 0);
X[i, 2] := g0i2f (xi ** 1);
X[i, 3] := g0i2f (xi ** 2);
Y[i, 1] := g0i2f yi
end
end
val solution = least_squares_solution (X, Y)
in
println! ("A :");
Real_Matrix_fprint (stdout_ref, A);
println! ();
println! ("Q :");
Real_Matrix_fprint (stdout_ref, Q);
println! ();
println! ("R :");
Real_Matrix_fprint (stdout_ref, R);
println! ();
println! ("Q * R :");
Real_Matrix_fprint (stdout_ref, Q * R);
println! ();
println! ("least squares A in Ax=b :");
Real_Matrix_fprint (stdout_ref, X);
println! ();
println! ("least squares b in Ax=b :");
Real_Matrix_fprint (stdout_ref, Y);
println! ();
println! ("least squares solution :");
Real_Matrix_fprint (stdout_ref, solution)
end
 
(*------------------------------------------------------------------*)
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_GCBDW qr_decomposition_task.dats -lgc -lm && ./a.out
A :
12 -51 4
6 167 -68
-4 24 -41
 
Q :
-0.857143 0.394286 0.331429
-0.428571 -0.902857 -0.0342857
0.285714 -0.171429 0.942857
 
R :
-14 -21 14
0 -175 70
0 0 -35
 
Q * R :
12 -51 4
6 167 -68
-4 24 -41
 
least squares A in Ax=b :
1 0 0
1 1 1
1 2 4
1 3 9
1 4 16
1 5 25
1 6 36
1 7 49
1 8 64
1 9 81
1 10 100
 
least squares b in Ax=b :
1
6
17
34
57
86
121
162
209
262
321
 
least squares solution :
1
2
3
</pre>
 
=={{header|Axiom}}==
The following provides a generic QR decomposition for arbitrary precision floats, double floats and exact calculations:
<langsyntaxhighlight Axiomlang="axiom">)abbrev package TESTP TestPackage
TestPackage(R:Join(Field,RadicalCategory)): with
unitVector: NonNegativeInteger -> Vector(R)
Line 260 ⟶ 1,109:
for j in 0..n repeat
setColumn!(a,j+1,x^j)
lsqr(a,y)</langsyntaxhighlight>
This can be called using:
<langsyntaxhighlight Axiomlang="axiom">m := matrix [[12, -51, 4], [6, 167, -68], [-4, 24, -41]];
qr m
x := vector [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
y := vector [1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321];
polyfit(x, y, 2)</langsyntaxhighlight>
With output in exact form:
<langsyntaxhighlight Axiomlang="axiom">qr m
 
+ 6 69 58 +
Line 287 ⟶ 1,136:
 
[1,2,3]
Type: Vector(AlgebraicNumber)</langsyntaxhighlight>
The calculations are comparable to those from the default QR decomposition in R.
 
Line 293 ⟶ 1,142:
{{works with|BBC BASIC for Windows}}
Makes heavy use of BBC BASIC's matrix arithmetic.
<langsyntaxhighlight lang="bbcbasic"> *FLOAT 64
@% = &2040A
INSTALL @lib$+"ARRAYLIB"
Line 389 ⟶ 1,238:
REM Create the Householder matrix H() = I - 2/vt()v() v()vt():
vvt() *= 2 / d(0) : H() = I() - vvt()
ENDPROC</langsyntaxhighlight>
'''Output:'''
<pre>
Line 406 ⟶ 1,255:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 597 ⟶ 1,446:
matrix_delete(m);
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 621 ⟶ 1,470:
2.000 -0.000 3.000
</pre>
 
=={{header|C sharp|C#}}==
 
{{libheader|Math.Net}}
 
<syntaxhighlight lang="csharp">using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
 
 
class Program
{
 
static void Main(string[] args)
{
Matrix<double> A = DenseMatrix.OfArray(new double[,]
{
{ 12, -51, 4 },
{ 6, 167, -68 },
{ -4, 24, -41 }
});
Console.WriteLine("A:");
Console.WriteLine(A);
var qr = A.QR();
Console.WriteLine();
Console.WriteLine("Q:");
Console.WriteLine(qr.Q);
Console.WriteLine();
Console.WriteLine("R:");
Console.WriteLine(qr.R);
}
}</syntaxhighlight>
 
{{out}}
 
<pre>A:
DenseMatrix 3x3-Double
12 -51 4
6 167 -68
-4 24 -41
 
 
Q:
DenseMatrix 3x3-Double
-0.857143 0.394286 -0.331429
-0.428571 -0.902857 0.0342857
0.285714 -0.171429 -0.942857
 
 
R:
DenseMatrix 3x3-Double
-14 -21 14
0 -175 70
0 0 35</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">/*
* g++ -O3 -Wall --std=c++11 qr_standalone.cpp -o qr_standalone
*/
Line 1,018 ⟶ 1,921:
return EXIT_SUCCESS;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,050 ⟶ 1,953:
</pre>
 
===With Polynomial Fitting===
=={{header|C sharp|C#}}==
<syntaxhighlight lang="c++">
#include <cmath>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
 
class Matrix {
{{libheader|Math.Net}}
public:
Matrix(const std::vector<std::vector<double>>& data) : data(data) {
initialise();
}
 
Matrix(const Matrix& matrix) : data(matrix.data) {
<lang csharp>using System;
initialise();
using MathNet.Numerics.LinearAlgebra;
}
using MathNet.Numerics.LinearAlgebra.Double;
 
Matrix(const uint64_t& row_count, const uint64_t& column_count) {
data.assign(row_count, std::vector<double>(column_count, 0.0));
initialise();
}
 
Matrix add(const Matrix& other) {
class Program
if ( other.row_count != row_count || other.column_count != column_count ) {
{
throw std::invalid_argument("Incompatible matrix dimensions.");
}
 
Matrix result(data);
static void Main(string[] args)
for ( int32_t i = 0; i < row_count; ++i ) {
{
for ( int32_t j = 0; j < column_count; ++j ) {
Matrix<double> A = DenseMatrix.OfArray(new double[,]
result.data[i][j] = data[i][j] + other.data[i][j];
{
}
{ 12, -51, 4 },
}
{ 6, 167, -68 },
return result;
{ -4, 24, -41 }
}
});
Console.WriteLine("A:");
Console.WriteLine(A);
var qr = A.QR();
Console.WriteLine();
Console.WriteLine("Q:");
Console.WriteLine(qr.Q);
Console.WriteLine();
Console.WriteLine("R:");
Console.WriteLine(qr.R);
}
}</lang>
 
Matrix multiply(const Matrix& other) {
{{out}}
if ( column_count != other.row_count ) {
throw std::invalid_argument("Incompatible matrix dimensions.");
}
 
Matrix result(row_count, other.column_count);
<pre>A:
for ( int32_t i = 0; i < row_count; ++i ) {
DenseMatrix 3x3-Double
for ( int32_t j = 0; j < other.column_count; ++j ) {
12 -51 4
for ( int32_t k = 0; k < row_count; k++ ) {
6 167 -68
result.data[i][j] += data[i][k] * other.data[k][j];
-4 24 -41
}
}
}
return result;
}
 
Matrix transpose() {
Matrix result(column_count, row_count);
for ( int32_t i = 0; i < row_count; ++i ) {
for ( int32_t j = 0; j < column_count; ++j ) {
result.data[j][i] = data[i][j];
}
}
return result;
}
 
Matrix minor(const int32_t& index) {
Q:
Matrix result(row_count, column_count);
DenseMatrix 3x3-Double
for ( int32_t i = 0; i < index; ++i ) {
-0.857143 0.394286 -0.331429
result.set_entry(i, i, 1.0);
-0.428571 -0.902857 0.0342857
}
0.285714 -0.171429 -0.942857
 
for ( int32_t i = index; i < row_count; ++i ) {
for ( int32_t j = index; j < column_count; ++j ) {
result.set_entry(i, j, data[i][j]);
}
}
return result;
}
 
Matrix column(const int32_t& index) {
R:
Matrix result(row_count, 1);
DenseMatrix 3x3-Double
for ( int32_t i = 0; i < row_count; ++i ) {
-14 -21 14
result.set_entry(i, 0, data[i][index]);
0 -175 70
}
0 0 35</pre>
return result;
}
 
Matrix scalarMultiply(const double& value) {
if ( column_count != 1 ) {
throw std::invalid_argument("Incompatible matrix dimension.");
}
 
Matrix result(row_count, column_count);
for ( int32_t i = 0; i < row_count; ++i ) {
result.data[i][0] = data[i][0] * value;
}
return result;
}
 
Matrix unit() {
if ( column_count != 1 ) {
throw std::invalid_argument("Incompatible matrix dimensions.");
}
 
const double the_magnitude = magnitude();
Matrix result(row_count, column_count);
for ( int32_t i = 0; i < row_count; ++i ) {
result.data[i][0] = data[i][0] / the_magnitude;
}
return result;
}
 
double magnitude() {
if ( column_count != 1 ) {
throw std::invalid_argument("Incompatible matrix dimensions.");
}
 
double norm = 0.0;
for ( int32_t i = 0; i < row_count; ++i ) {
norm += data[i][0] * data[i][0];
}
return std::sqrt(norm);
}
 
int32_t size() {
if ( column_count != 1 ) {
throw std::invalid_argument("Incompatible matrix dimensions.");
}
return row_count;
}
 
void display(const std::string& title) {
std::cout << title << std::endl;
for ( int32_t i = 0; i < row_count; ++i ) {
for ( int32_t j = 0; j < column_count; ++j ) {
std::cout << std::setw(9) << std::fixed << std::setprecision(4) << data[i][j];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
 
double get_entry(const int32_t& row, const int32_t& col) {
return data[row][col];
}
 
void set_entry(const int32_t& row, const int32_t& col, const double& value) {
data[row][col] = value;
}
 
int32_t get_row_count() {
return row_count;
}
 
int32_t get_column_count() {
return column_count;
}
 
private:
void initialise() {
row_count = data.size();
column_count = data[0].size();
}
 
int32_t row_count;
int32_t column_count;
std::vector<std::vector<double>> data;
};
 
typedef std::pair<Matrix, Matrix> matrix_pair;
 
Matrix householder_factor(Matrix vector) {
if ( vector.get_column_count() != 1 ) {
throw std::invalid_argument("Incompatible matrix dimensions.");
}
 
const int32_t size = vector.size();
Matrix result(size, size);
for ( int32_t i = 0; i < size; ++i ) {
for ( int32_t j = 0; j < size; ++j ) {
result.set_entry(i, j, -2 * vector.get_entry(i, 0) * vector.get_entry(j, 0));
}
}
 
for ( int32_t i = 0; i < size; ++i ) {
result.set_entry(i, i, result.get_entry(i, i) + 1.0);
}
return result;
}
 
matrix_pair householder(Matrix matrix) {
const int32_t row_count = matrix.get_row_count();
const int32_t column_count = matrix.get_column_count();
std::vector<Matrix> versions_of_Q;
Matrix z(matrix);
Matrix z1(row_count, column_count);
 
for ( int32_t k = 0; k < column_count && k < row_count - 1; ++k ) {
Matrix vectorE(row_count, 1);
z1 = z.minor(k);
Matrix vectorX = z1.column(k);
double magnitudeX = vectorX.magnitude();
if ( matrix.get_entry(k, k) > 0 ) {
magnitudeX = -magnitudeX;
}
 
for ( int32_t i = 0; i < vectorE.size(); ++i ) {
vectorE.set_entry(i, 0, ( i == k ) ? 1 : 0);
}
vectorE = vectorE.scalarMultiply(magnitudeX).add(vectorX).unit();
versions_of_Q.emplace_back(householder_factor(vectorE));
z = versions_of_Q[k].multiply(z1);
}
 
Matrix Q = versions_of_Q[0];
for ( int32_t i = 1; i < column_count && i < row_count - 1; ++i ) {
Q = versions_of_Q[i].multiply(Q);
}
 
Matrix R = Q.multiply(matrix);
Q = Q.transpose();
return matrix_pair(R, Q);
}
 
Matrix solve_upper_triangular(Matrix r, Matrix b) {
const int32_t column_count = r.get_column_count();
Matrix result(column_count, 1);
 
for ( int32_t k = column_count - 1; k >= 0; --k ) {
double total = 0.0;
for ( int32_t j = k + 1; j < column_count; ++j ) {
total += r.get_entry(k, j) * result.get_entry(j, 0);
}
result.set_entry(k, 0, ( b.get_entry(k, 0) - total ) / r.get_entry(k, k));
}
return result;
}
 
Matrix least_squares(Matrix vandermonde, Matrix b) {
matrix_pair pair = householder(vandermonde);
return solve_upper_triangular(pair.first, pair.second.transpose().multiply(b));
}
 
Matrix fit_polynomial(Matrix x, Matrix y, const int32_t& polynomial_degree) {
Matrix vandermonde(x.get_column_count(), polynomial_degree + 1);
for ( int32_t i = 0; i < x.get_column_count(); ++i ) {
for ( int32_t j = 0; j < polynomial_degree + 1; ++j ) {
vandermonde.set_entry(i, j, std::pow(x.get_entry(0, i), j));
}
}
return least_squares(vandermonde, y.transpose());
}
 
int main() {
const std::vector<std::vector<double>> data = { { 12.0, -51.0, 4.0 },
{ 6.0, 167.0, -68.0 },
{ -4.0, 24.0, -41.0 },
{ -1.0, 1.0, 0.0 },
{ 2.0, 0.0, 3.0 } };
 
// Task 1
Matrix A(data);
A.display("Initial matrix A:");
 
matrix_pair pair = householder(A);
Matrix Q = pair.second;
Matrix R = pair.first;
 
Q.display("Matrix Q:");
R.display("Matrix R:");
 
Matrix result = Q.multiply(R);
result.display("Matrix Q * R:");
 
// Task 2
Matrix x( std::vector<std::vector<double>>{ { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 } } );
Matrix y( std::vector<std::vector<double>>{
{ 1.0, 6.0, 17.0, 34.0, 57.0, 86.0, 121.0, 162.0, 209.0, 262.0, 321.0 } } );
 
result = fit_polynomial(x, y, 2);
result.display("Result of fitting polynomial:");
}
</syntaxhighlight>
{{ out }}
<pre>
Initial matrix A:
12.0000 -51.0000 4.0000
6.0000 167.0000 -68.0000
-4.0000 24.0000 -41.0000
-1.0000 1.0000 0.0000
2.0000 0.0000 3.0000
 
Matrix Q:
0.8464 -0.3913 0.3431 0.0815 0.0781
0.4232 0.9041 -0.0293 0.0258 0.0447
-0.2821 0.1704 0.9329 -0.0474 -0.1374
-0.0705 0.0140 -0.0011 0.9804 -0.1836
0.1411 -0.0167 -0.1058 -0.1713 -0.9692
 
Matrix R:
14.1774 20.6666 -13.4016
-0.0000 175.0425 -70.0803
0.0000 0.0000 -35.2015
-0.0000 -0.0000 -0.0000
0.0000 0.0000 -0.0000
 
Matrix Q * R:
12.0000 -51.0000 4.0000
6.0000 167.0000 -68.0000
-4.0000 24.0000 -41.0000
-1.0000 1.0000 -0.0000
2.0000 -0.0000 3.0000
 
Result of fitting polynomial:
1.0000
2.0000
3.0000
</pre>
 
=={{header|Common Lisp}}==
Line 1,109 ⟶ 2,276:
 
Helper functions:
<langsyntaxhighlight lang="lisp">(defun sign (x)
(if (zerop x)
x
Line 1,163 ⟶ 2,330:
 
C))
</syntaxhighlight>
</lang>
 
Main routines:
<langsyntaxhighlight lang="lisp">
(defun make-householder (a)
(let* ((m (car (array-dimensions a)))
Line 1,201 ⟶ 2,368:
;; Return Q and R.
(values Q A)))
</syntaxhighlight>
</lang>
 
Example 1:
 
<langsyntaxhighlight lang="lisp">(qr #2A((12 -51 4) (6 167 -68) (-4 24 -41)))
 
#2A((-0.85 0.39 0.33)
Line 1,213 ⟶ 2,380:
#2A((-14.0 -21.0 14.0)
( 0.0 -175.0 70.0)
( 0.0 0.0 -35.0))</langsyntaxhighlight>
 
Example 2, [[Polynomial regression]]:
 
<langsyntaxhighlight lang="lisp">(defun polyfit (x y n)
(let* ((m (cadr (array-dimensions x)))
(A (make-array `(,m ,(+ n 1)) :initial-element 0)))
Line 1,245 ⟶ 2,412:
(aref x j 0))))
(aref R k k))))
x))</langsyntaxhighlight>
 
<langsyntaxhighlight lang="lisp">;; Finally use the data:
(let ((x #2A((0 1 2 3 4 5 6 7 8 9 10)))
(y #2A((1 6 17 34 57 86 121 162 209 262 321))))
(polyfit x y 2))
 
#2A((0.999999966345088) (2.000000015144699) (2.99999999879804))</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|Common Lisp}}
Uses the functions copied from [[Element-wise_operations]], [[Matrix multiplication]], and [[Matrix transposition]].
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.algorithm, std.traits,
std.typecons, std.numeric, std.range, std.conv;
 
Line 1,458 ⟶ 2,625:
immutable y = [[1.0, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321]];
polyFit(x, y, 2).writeln;
}</langsyntaxhighlight>
{{out}}
<pre>[[-0.857, 0.394, 0.331],
Line 1,469 ⟶ 2,636:
 
[[1], [2], [3]]</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// QR decomposition. Nigel Galloway: January 11th., 2022
let n=[[12.0;-51.0;4.0];[6.0;167.0;-68.0];[-4.0;24.0;-41.0]]|>MathNet.Numerics.LinearAlgebra.MatrixExtensions.matrix
let g=n|>MathNet.Numerics.LinearAlgebra.Matrix.qr
printfn $"Matrix\n------\n%A{n}\nQ\n-\n%A{g.Q}\nR\n-\n%A{g.R}"
</syntaxhighlight>
{{out}}
<pre>
Matrix
------
DenseMatrix 3x3-Double
12 -51 4
6 167 -68
-4 24 -41
 
Q
-
DenseMatrix 3x3-Double
-0.857143 0.394286 -0.331429
-0.428571 -0.902857 0.0342857
0.285714 -0.171429 -0.942857
 
R
-
DenseMatrix 3x3-Double
-14 -21 14
0 -175 70
0 0 35
</pre>
=={{header|Fortran}}==
 
{{libheader|LAPACK}}
 
See the documentation for the [http://www.netlib.org/lapack/lapack-3.1.1/html/dgeqrf.f.html DGEQRF] and [http://www.netlib.org/lapack/lapack-3.1.1/html/dorgqr.f.html DORGQR] routines. Here the example matrix is the magic square from Albrecht Dürer's ''[https://en.wikipedia.org/wiki/Melencolia_I Melencolia I]''.
 
<syntaxhighlight lang="fortran">program qrtask
implicit none
integer, parameter :: n = 4
real(8) :: durer(n, n) = reshape(dble([ &
16, 5, 9, 4, &
3, 10, 6, 15, &
2, 11, 7, 14, &
13, 8, 12, 1 &
]), [n, n])
real(8) :: q(n, n), r(n, n), qr(n, n), id(n, n), tau(n)
integer, parameter :: lwork = 1024
real(8) :: work(lwork)
integer :: info, i, j
q = durer
call dgeqrf(n, n, q, n, tau, work, lwork, info)
r = 0d0
forall (i = 1:n, j = 1:n, j >= i) r(i, j) = q(i, j)
call dorgqr(n, n, n, q, n, tau, work, lwork, info)
qr = matmul(q, r)
id = matmul(q, transpose(q))
call show(4, durer, "A")
call show(4, q, "Q")
call show(4, r, "R")
call show(4, qr, "Q*R")
call show(4, id, "Q*Q'")
contains
subroutine show(n, a, s)
character(*) :: s
integer :: n, i
real(8) :: a(n, n)
print *, s
do i = 1, n
print 1, a(i, :)
1 format (*(f12.6,:,' '))
end do
end subroutine
end program</syntaxhighlight>
 
{{out}}
 
<pre> A
16.000000 3.000000 2.000000 13.000000
5.000000 10.000000 11.000000 8.000000
9.000000 6.000000 7.000000 12.000000
4.000000 15.000000 14.000000 1.000000
Q
-0.822951 0.376971 0.361447 -0.223607
-0.257172 -0.454102 -0.526929 -0.670820
-0.462910 -0.060102 -0.576283 0.670820
-0.205738 -0.805029 0.509510 0.223607
R
-19.442222 -10.904103 -10.595497 -18.516402
0.000000 -15.846152 -15.932298 -0.258437
0.000000 0.000000 -1.974168 -5.922505
0.000000 0.000000 0.000000 -0.000000
Q*R
16.000000 3.000000 2.000000 13.000000
5.000000 10.000000 11.000000 8.000000
9.000000 6.000000 7.000000 12.000000
4.000000 15.000000 14.000000 1.000000
Q*Q'
1.000000 -0.000000 -0.000000 0.000000
-0.000000 1.000000 0.000000 0.000000
-0.000000 0.000000 1.000000 -0.000000
0.000000 0.000000 -0.000000 1.000000</pre>
 
=={{header|Futhark}}==
<syntaxhighlight lang="futhark">
import "lib/github.com/diku-dk/linalg/linalg"
 
module linalg_f64 = mk_linalg f64
 
let eye (n: i32): [n][n]f64 =
let arr = map (\ind -> let (i,j) = (ind/n,ind%n) in if (i==j) then 1.0 else 0.0) (iota (n*n))
in unflatten n n arr
 
let norm v = linalg_f64.dotprod v v |> f64.sqrt
 
let qr [n] [m] (a: [m][n]f64): ([m][m]f64, [m][n]f64) =
 
let make_householder [d] (x: [d]f64): [d][d]f64 =
let div = if x[0] > 0 then x[0] + norm x else x[0] - norm x
let v = map (/div) x
let v[0] = 1
let fac = 2.0 / linalg_f64.dotprod v v
in map2 (map2 (-)) (eye d) (map (map (*fac)) (linalg_f64.outer v v))
 
let step ((x,y):([m][m]f64,[m][n]f64)) (i:i32): ([m][m]f64,[m][n]f64) =
let h = eye m
let h[i:m,i:m] = make_householder y[i:m,i]
let q': [m][m]f64 = linalg_f64.matmul x h
let a': [m][n]f64 = linalg_f64.matmul h y
in (q',a')
 
let q = eye m
in foldl step (q,a) (iota n)
 
entry main = qr [[12.0, -51.0, 4.0],[6.0, 167.0, -68.0],[-4.0, 24.0, -41.0]]
</syntaxhighlight>
{{out}}
<pre>
$ ./qr
[[-0.857143f64, 0.394286f64, -0.331429f64], [-0.428571f64, -0.902857f64, 0.034286f64], [0.285714f64, -0.171429f64, -0.942857f64]]
[[-14.000000f64, -21.000000f64, 14.000000f64], [0.000000f64, -175.000000f64, 70.000000f64], [-0.000000f64, 0.000000f64, 35.000000f64]]
</pre>
 
=={{header|Go}}==
Line 1,474 ⟶ 2,789:
{{trans|Common Lisp}}
A fairly close port of the Common Lisp solution, this solution uses the [http://github.com/skelterjohn/go.matrix go.matrix library] for supporting functions. Note though, that go.matrix has QR decomposition, as shown in the [[Polynomial_regression#Go|Go solution]] to Polynomial regression. The solution there is coded more directly than by following the CL example here. Similarly, examination of the go.matrix QR source shows that it computes the decomposition more directly.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,580 ⟶ 2,895:
}
return x
}</langsyntaxhighlight>
Output:
<pre>
Line 1,599 ⟶ 2,914:
 
===Library QR, gonum/matrix===
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,642 ⟶ 2,957:
}
return x
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,656 ⟶ 2,971:
⎢2.000⎥
⎣3.000⎦
</pre>
 
=={{header|Haskell}}==
Square matrices only; decompose A and solve Rx = q by back substitution
<syntaxhighlight lang="haskell">
import Data.List
import Text.Printf (printf)
 
eps = 1e-6 :: Double
 
-- a matrix is represented as a list of columns
mmult :: Num a => [[a]] -> [[a]] -> [[a]]
nth :: Num a => [[a]] -> Int -> Int -> a
mmult_num :: Num a => [[a]] -> a -> [[a]]
madd :: Num a => [[a]] -> [[a]] -> [[a]]
idMatrix :: Num a => Int -> Int -> [[a]]
 
adjustWithE :: [[Double]] -> Int -> [[Double]]
 
mmult a b = [ [ sum $ zipWith (*) ak bj | ak <- (transpose a) ] | bj <- b ]
nth mA i j = (mA !! j) !! i
mmult_num mA n = map (\c -> map (*n) c) mA
madd mA mB = zipWith (\c1 c2 -> zipWith (+) c1 c2) mA mB
idMatrix n m = [ [if (i==j) then 1 else 0 | i <- [1..n]] | j <- [1..m]]
 
adjustWithE mA n = let lA = length mA in
(idMatrix n (n - lA)) ++ (map (\c -> (take (n - lA) (repeat 0.0)) ++ c ) mA)
 
-- auxiliary functions
sqsum :: Floating a => [a] -> a
norm :: Floating a => [a] -> a
epsilonize :: [[Double]] -> [[Double]]
 
sqsum a = foldl (\x y -> x + y*y) 0 a
norm a = sqrt $! sqsum a
epsilonize mA = map (\c -> map (\x -> if abs x <= eps then 0 else x) c) mA
 
-- Householder transformation; householder A = (Q, R)
uTransform :: [Double] -> [Double]
hMatrix :: [Double] -> Int -> Int -> [[Double]]
householder :: [[Double]] -> ([[Double]], [[Double]])
 
-- householder_rec Q R A
householder_rec :: [[Double]] -> [[Double]] -> Int -> ([[Double]], [[Double]])
 
uTransform a = let t = (head a) + (signum (head a))*(norm a) in
1 : map (\x -> x/t) (tail a)
 
hMatrix a n i = let u = uTransform (drop i a) in
madd
(idMatrix (n-i) (n-i))
(mmult_num
(mmult [u] (transpose [u]))
((/) (-2) (sqsum u)))
 
householder_rec mQ mR 0 = (mQ, mR)
householder_rec mQ mR n = let mSize = length mR in
let mH = adjustWithE (hMatrix (mR!!(mSize - n)) mSize (mSize - n)) mSize in
householder_rec (mmult mQ mH) (mmult mH mR) (n - 1)
 
householder mA = let mSize = length mA in
let (mQ, mR) = householder_rec (idMatrix mSize mSize) mA mSize in
(epsilonize mQ, epsilonize mR)
 
backSubstitution :: [[Double]] -> [Double] -> [Double] -> [Double]
backSubstitution mR [] res = res
backSubstitution mR@(hR:tR) q@(h:t) res =
let x = (h / (head hR)) in
backSubstitution
(map tail tR)
(tail (zipWith (-) q (map (*x) hR)))
(x : res)
 
showMatrix :: [[Double]] -> String
showMatrix mA =
concat $ intersperse "\n"
(map (\x -> unwords $ printf "%10.4f" <$> (x::[Double])) (transpose mA))
 
mY = [[12, 6, -4], [-51, 167, 24], [4, -68, -41]] :: [[Double]]
q = [21, 245, 35] :: [Double]
main = let (mQ, mR) = householder mY in
putStrLn ("Q: \n" ++ showMatrix mQ) >>
putStrLn ("R: \n" ++ showMatrix mR) >>
putStrLn ("q: \n" ++ show q) >>
putStrLn ("x: \n" ++ show (backSubstitution (reverse (map reverse mR)) (reverse q) []))
</syntaxhighlight>
{{out}}
<pre>
Q:
-0.8571 0.3943 -0.3314
-0.4286 -0.9029 0.0343
0.2857 -0.1714 -0.9429
R:
-14.0000 -21.0000 14.0000
0.0000 -175.0000 70.0000
0.0000 0.0000 35.0000
q:
[21.0,245.0,35.0]
x:
[1.0000000000000004,-0.9999999999999999,1.0]
</pre>
 
===QR decomposition with Numeric.LinearAlgebra===
<syntaxhighlight lang="haskell">import Numeric.LinearAlgebra
 
a :: Matrix R
a = (3><3)
[ 12, -51, 4
, 6, 167, -68
, -4, 24, -41]
 
main = do
print $ qr a
</syntaxhighlight>
{{out}}
<pre>((3><3)
[ -0.8571428571428572, 0.3942857142857143, 0.33142857142857146
, -0.4285714285714286, -0.9028571428571428, -3.428571428571427e-2
, 0.28571428571428575, -0.17142857142857137, 0.9428571428571428 ],(3><3)
[ -14.0, -21.0, 14.000000000000002
, 0.0, -175.00000000000003, 70.00000000000001
, 0.0,
</pre>
 
=={{header|J}}==
 
'''Solution''' (built-in):<langsyntaxhighlight lang="j"> QR =: 128!:0</langsyntaxhighlight>
'''Solution''' (custom implementation): <langsyntaxhighlight lang="j"> mp=: +/ . * NB. matrix product
h =: +@|: NB. conjugate transpose
 
Line 1,676 ⟶ 3,113:
(Q0,.Q1);(R0,.T),(-n){."1 R1
end.
)</langsyntaxhighlight>
 
'''Example''': <langsyntaxhighlight lang="j"> QR 12 _51 4,6 167 _68,:_4 24 _41
+-----------------------------+----------+
| 0.857143 _0.394286 _0.331429|14 21 _14|
| 0.428571 0.902857 0.0342857| 0 175 _70|
|_0.285714 0.171429 _0.942857| 0 0 35|
+-----------------------------+----------+</langsyntaxhighlight>
 
'''Example''' (polynomial fitting using QR reduction):<langsyntaxhighlight lang="j"> X=:i.# Y=:1 6 17 34 57 86 121 162 209 262 321
'Q R'=: QR X ^/ i.3
R %.~(|:Q)+/ .* Y
1 2 3</langsyntaxhighlight>
'''Notes''':J offers a built-in QR decomposition function, <tt>128!:0</tt>. If J did not offer this function as a built-in, it could be written in J along the lines of the second version, which is covered in [[j:Essays/QR Decomposition|an essay on the J wiki]].
 
=={{header|Java}}==
=== JAMA ===
Note: uses the [https://math.nist.gov/javanumerics/jama/ JAMA Java Matrix Package].
Using the [https://math.nist.gov/javanumerics/jama/ JAMA] library. Compile with: '''javac -cp Jama-1.0.3.jar Decompose.java'''.
 
<syntaxhighlight lang="java">import Jama.Matrix;
Compile with: '''javac -cp Jama-1.0.3.jar Decompose.java'''.
 
<lang java>import Jama.Matrix;
import Jama.QRDecomposition;
 
public class Decompose {
import java.io.StringWriter;
public static void main(String[] args) {
import java.io.PrintWriter;
var matrix = new Matrix(new double[][] {
{12, -51, 4},
{ 6, 167, -68},
{-4, 24, -41},
});
 
var qr = new QRDecomposition(matrix);
qr.getQ().print(10, 4);
qr.getR().print(10, 4);
}
}</syntaxhighlight>
 
{{out}}
<pre> -0.8571 0.3943 -0.3314
-0.4286 -0.9029 0.0343
0.2857 -0.1714 -0.9429
 
 
-14.0000 -21.0000 14.0000
0.0000 -175.0000 70.0000
0.0000 0.0000 35.0000</pre>
 
=== Colt ===
 
Using the [https://dst.lbl.gov/ACSSoftware/colt/ Colt] library. Compile with: '''javac -cp colt.jar Decompose.java'''.
 
<syntaxhighlight lang="java">import cern.colt.matrix.impl.DenseDoubleMatrix2D;
import cern.colt.matrix.linalg.QRDecomposition;
 
public class Decompose {
public static void main(String[] args) {
Matrixvar matrixa = new MatrixDenseDoubleMatrix2D(new double[][] {
{ 12, -51, 4 },
{ 6, 167, -68 },
{ -4, 24, -41 },
});
var qr = new QRDecomposition(a);
System.out.println(qr.getQ());
System.out.println();
System.out.println(qr.getR());
}
}</syntaxhighlight>
 
{{out}}
QRDecomposition d = new QRDecomposition(matrix);
 
System.out.print(toString(d.getQ()));
<pre>3 x 3 matrix
System.out.print(toString(d.getR()));
-0.857143 0.394286 -0.331429
-0.428571 -0.902857 0.034286
0.285714 -0.171429 -0.942857
 
3 x 3 matrix
-14 -21 14
0 -175 70
0 0 35</pre>
 
=== Apache Commons Math ===
 
Using the Apache Commons [http://commons.apache.org/proper/commons-math/ Math] library.
 
Compile with: '''javac -cp commons-math3-3.6.1.jar Decompose.java'''.
 
<syntaxhighlight lang="java">import java.util.Locale;
 
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.QRDecomposition;
import org.apache.commons.math3.linear.RealMatrix;
 
public class Decompose {
public static void main(String[] args) {
var a = new Array2DRowRealMatrix(new double[][] {
{12, -51, 4},
{ 6, 167, -68},
{-4, 24, -41}
});
var qr = new QRDecomposition(a);
print(qr.getQ());
System.out.println();
print(qr.getR());
}
public static void print(RealMatrix a) {
for (double[] u: a.getData()) {
System.out.print("[ ");
for (double x: u) {
System.out.printf(Locale.ROOT, "%10.4f ", x);
}
System.out.println("]");
}
}
}</syntaxhighlight>
 
{{out}}
public static String toString(Matrix m) {
 
StringWriter sw = new StringWriter();
<pre>[ -0.8571 0.3943 -0.3314 ]
m.print(new PrintWriter(sw, true), 8, 6);
[ -0.4286 return-0.9029 sw 0.toString();0343 ]
[ 0.2857 -0.1714 -0.9429 ]
 
[ -14.0000 -21.0000 14.0000 ]
[ 0.0000 -175.0000 70.0000 ]
[ 0.0000 0.0000 35.0000 ]</pre>
 
=== la4j ===
 
Using the [http://la4j.org/ la4j] library. Compile with: '''javac -cp la4j-0.6.0.jar Decompose.java'''.
 
<syntaxhighlight lang="java">import org.la4j.Matrix;
import org.la4j.decomposition.QRDecompositor;
 
public class Decompose {
public static void main(String[] args) {
var a = Matrix.from2DArray(new double[][] {
{12, -51, 4},
{ 6, 167, -68},
{-4, 24, -41},
});
Matrix[] qr = new QRDecompositor(a).decompose();
System.out.println(qr[0]);
System.out.println(qr[1]);
}
}</langsyntaxhighlight>
 
{{out}}
 
<pre>-0,857 0,394 -0,331
-0,429 -0,903 0,034
0,286 -0,171 -0,943
 
-14,000 -21,000 14,000
0,000 -175,000 70,000
0,000 0,000 35,000</pre>
 
===Without external libraries===
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.List;
 
public final class QRDecomposition {
 
public static void main(String[] aArgs) {
final double[][] data = new double [][] { { 12.0, -51.0, 4.0 },
{ 6.0, 167.0, -68.0 },
{ -4.0, 24.0, -41.0 },
{ -1.0, 1.0, 0.0 },
{ 2.0, 0.0, 3.0 } };
// Task 1
Matrix A = new Matrix(data);
A.display("Initial matrix A:");
MatrixPair pair = householder(A);
Matrix Q = pair.q;
Matrix R = pair.r;
Q.display("Matrix Q:");
R.display("Matrix R:");
Matrix result = Q.multiply(R);
result.display("Matrix Q * R:");
// Task 2
Matrix x = new Matrix ( new double[][] { { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 } } );
Matrix y = new Matrix(
new double[][] { { 1.0, 6.0, 17.0, 34.0, 57.0, 86.0, 121.0, 162.0, 209.0, 262.0, 321.0 } } );
result = fitPolynomial(x, y, 2);
result.display("Result of fitting polynomial:");
}
private static MatrixPair householder(Matrix aMatrix) {
final int rowCount = aMatrix.getRowCount();
final int columnCount = aMatrix.getColumnCount();
List<Matrix> versionsOfQ = new ArrayList<Matrix>(rowCount);
Matrix z = new Matrix(aMatrix);
Matrix z1 = new Matrix(rowCount, columnCount);
for ( int k = 0; k < columnCount && k < rowCount - 1; k++ ) {
Matrix vectorE = new Matrix(rowCount, 1);
z1 = z.minor(k);
Matrix vectorX = z1.column(k);
double magnitudeX = vectorX.magnitude();
if ( aMatrix.getEntry(k, k) > 0 ) {
magnitudeX = -magnitudeX;
}
 
for ( int i = 0; i < vectorE.size(); i++ ) {
vectorE.setEntry(i, 0, ( i == k ) ? 1 : 0);
}
vectorE = vectorE.scalarMultiply(magnitudeX).add(vectorX).unit();
versionsOfQ.add(householderFactor(vectorE));
z = versionsOfQ.get(k).multiply(z1);
}
Matrix Q = versionsOfQ.get(0);
for ( int i = 1; i < columnCount && i < rowCount - 1; i++ ) {
Q = versionsOfQ.get(i).multiply(Q);
}
 
Matrix R = Q.multiply(aMatrix);
Q = Q.transpose();
return new MatrixPair(R, Q);
}
public static Matrix householderFactor(Matrix aVector) {
if ( aVector.getColumnCount() != 1 ) {
throw new RuntimeException("Incompatible matrix dimensions.");
}
final int size = aVector.size();
Matrix result = new Matrix(size, size);
for ( int i = 0; i < size; i++ ) {
for ( int j = 0; j < size; j++ ) {
result.setEntry(i, j, -2 * aVector.getEntry(i, 0) * aVector.getEntry(j, 0));
}
}
for ( int i = 0; i < size; i++ ) {
result.setEntry(i, i, result.getEntry(i, i) + 1.0);
}
return result;
}
private static Matrix fitPolynomial(Matrix aX, Matrix aY, int aPolynomialDegree) {
Matrix vandermonde = new Matrix(aX.getColumnCount(), aPolynomialDegree + 1);
for ( int i = 0; i < aX.getColumnCount(); i++ ) {
for ( int j = 0; j < aPolynomialDegree + 1; j++ ) {
vandermonde.setEntry(i, j, Math.pow(aX.getEntry(0, i), j));
}
}
return leastSquares(vandermonde, aY.transpose());
}
private static Matrix leastSquares(Matrix aVandermonde, Matrix aB) {
MatrixPair pair = householder(aVandermonde);
return solveUpperTriangular(pair.r, pair.q.transpose().multiply(aB));
}
private static Matrix solveUpperTriangular(Matrix aR, Matrix aB) {
final int columnCount = aR.getColumnCount();
Matrix result = new Matrix(columnCount, 1);
 
for ( int k = columnCount - 1; k >= 0; k-- ) {
double total = 0.0;
for ( int j = k + 1; j < columnCount; j++ ) {
total += aR.getEntry(k, j) * result.getEntry(j, 0);
}
result.setEntry(k, 0, ( aB.getEntry(k, 0) - total ) / aR.getEntry(k, k));
}
return result;
}
private static record MatrixPair(Matrix r, Matrix q) {}
 
}
 
final class Matrix {
 
public Matrix(double[][] aData) {
rowCount = aData.length;
columnCount = aData[0].length;
data = new double[rowCount][columnCount];
for ( int i = 0; i < rowCount; i++ ) {
for ( int j = 0; j < columnCount; j++ ) {
data[i][j] = aData[i][j];
}
}
}
public Matrix(Matrix aMatrix) {
this(aMatrix.data);
}
public Matrix(int aRowCount, int aColumnCount) {
this( new double[aRowCount][aColumnCount] );
}
 
public Matrix add(Matrix aOther) {
if ( aOther.rowCount != rowCount || aOther.columnCount != columnCount ) {
throw new IllegalArgumentException("Incompatible matrix dimensions.");
}
Matrix result = new Matrix(data);
for ( int i = 0; i < rowCount; i++ ) {
for ( int j = 0; j < columnCount; j++ ) {
result.data[i][j] = data[i][j] + aOther.data[i][j];
}
}
return result;
}
 
public Matrix multiply(Matrix aOther) {
if ( columnCount != aOther.rowCount ) {
throw new IllegalArgumentException("Incompatible matrix dimensions.");
}
Matrix result = new Matrix(rowCount, aOther.columnCount);
for ( int i = 0; i < rowCount; i++ ) {
for ( int j = 0; j < aOther.columnCount; j++ ) {
for ( int k = 0; k < rowCount; k++ ) {
result.data[i][j] += data[i][k] * aOther.data[k][j];
}
}
}
return result;
}
public Matrix transpose() {
Matrix result = new Matrix(columnCount, rowCount);
for ( int i = 0; i < rowCount; i++ ) {
for ( int j = 0; j < columnCount; j++ ) {
result.data[j][i] = data[i][j];
}
}
return result;
}
public Matrix minor(int aIndex) {
Matrix result = new Matrix(rowCount, columnCount);
for ( int i = 0; i < aIndex; i++ ) {
result.setEntry(i, i, 1.0);
}
for ( int i = aIndex; i < rowCount; i++ ) {
for ( int j = aIndex; j < columnCount; j++ ) {
result.setEntry(i, j, data[i][j]);
}
}
return result;
}
public Matrix column(int aIndex) {
Matrix result = new Matrix(rowCount, 1);
for ( int i = 0; i < rowCount; i++ ) {
result.setEntry(i, 0, data[i][aIndex]);
}
return result;
}
public Matrix scalarMultiply(double aValue) {
if ( columnCount != 1 ) {
throw new IllegalArgumentException("Incompatible matrix dimension.");
}
Matrix result = new Matrix(rowCount, columnCount);
for ( int i = 0; i < rowCount; i++ ) {
result.data[i][0] = data[i][0] * aValue;
}
return result;
}
public Matrix unit() {
if ( columnCount != 1 ) {
throw new IllegalArgumentException("Incompatible matrix dimensions.");
}
final double magnitude = magnitude();
Matrix result = new Matrix(rowCount, columnCount);
for ( int i = 0; i < rowCount; i++ ) {
result.data[i][0] = data[i][0] / magnitude;
}
return result;
}
public double magnitude() {
if ( columnCount != 1 ) {
throw new IllegalArgumentException("Incompatible matrix dimensions.");
}
double norm = 0.0;
for ( int i = 0; i < data.length; i++ ) {
norm += data[i][0] * data[i][0];
}
return Math.sqrt(norm);
}
public int size() {
if ( columnCount != 1 ) {
throw new IllegalArgumentException("Incompatible matrix dimensions.");
}
return rowCount;
}
public void display(String aTitle) {
System.out.println(aTitle);
for ( int i = 0; i < rowCount; i++ ) {
for ( int j = 0; j < columnCount; j++ ) {
System.out.print(String.format("%9.4f", data[i][j]));
}
System.out.println();
}
System.out.println();
}
public double getEntry(int aRow, int aColumn) {
return data[aRow][aColumn];
}
public void setEntry(int aRow, int aColumn, double aValue) {
data[aRow][aColumn] = aValue;
}
public int getRowCount() {
return rowCount;
}
public int getColumnCount() {
return columnCount;
}
private final int rowCount;
private final int columnCount;
private final double[][] data;
}
</syntaxhighlight>
{{ out }}
<pre>
Initial matrix A:
12.0000 -51.0000 4.0000
6.0000 167.0000 -68.0000
-4.0000 24.0000 -41.0000
-1.0000 1.0000 0.0000
2.0000 0.0000 3.0000
 
Matrix Q:
-0.857143 0.394286 -0.331429
- 0.4285718464 -0.9028573913 0.3431 0.0815 0.0342860781
0.2857144232 -0.1714299041 -0.9428570293 0.0258 0.0447
-0.2821 0.1704 0.9329 -0.0474 -0.1374
-0.0705 0.0140 -0.0011 0.9804 -0.1836
0.1411 -0.0167 -0.1058 -0.1713 -0.9692
 
Matrix R:
14.1774 20.6666 -13.4016
-0.0000 175.0425 -70.0803
0.0000 0.0000 -35.2015
-0.0000 -0.0000 -0.0000
0.0000 0.0000 -0.0000
 
Matrix Q * R:
-14.000000 -21.000000 14.000000
012.0000000000 -17551.0000000000 70 4.0000000000
6.0000 167.0000 -68.0000
0.000000 0.000000 35.000000
-4.0000 24.0000 -41.0000
-1.0000 1.0000 -0.0000
2.0000 -0.0000 3.0000
 
Result of fitting polynomial:
1.0000
2.0000
3.0000
</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq.'''
 
'''General utilities'''
<syntaxhighlight lang=jq>
def sum(s): reduce s as $_ (0; . + $_);
 
# Sum of squares
def ss(s): sum(s|.*.);
 
# Create an m x n matrix
def matrix(m; n; init):
if m == 0 then []
elif m == 1 then [range(0;n) | init]
elif m > 0 then
matrix(1;n;init) as $row
| [range(0;m) | $row ]
else error("matrix\(m);_;_) invalid")
end;
 
def dot_product(a; b):
reduce range(0;a|length) as $i (0; . + (a[$i] * b[$i]) );
 
# A and B should both be numeric matrices, A being m by n, and B being n by p.
def multiply($A; $B):
($B[0]|length) as $p
| ($B|transpose) as $BT
| reduce range(0; $A|length) as $i
([];
reduce range(0; $p) as $j
(.;
.[$i][$j] = dot_product( $A[$i]; $BT[$j] ) ));
 
# $ndec decimal places
def round($ndec):
def rpad: tostring | ($ndec - length) as $l | . + ("0" * $l);
def abs: if . < 0 then -. else . end;
pow(10; $ndec) as $p
| round as $round
| if $p * ((. - $round)|abs) < 0.1
then ($round|tostring) + "." + ($ndec * "0")
else . * $p | round / $p
| tostring
| capture("(?<left>[^.]*)[.](?<right>.*)")
| .left + "." + (.right|rpad)
end;
 
# pretty-print a 2-d matrix
def pp($ndec; $width):
def pad(n): tostring | (n - length) * " " + .;
def row: map(round($ndec) | pad($width)) | join(" ");
reduce .[] as $row (""; . + "\n\($row|row)");
</syntaxhighlight>
'''QR-Decomposition'''
<syntaxhighlight lang=jq>
def minor($x; $d):
($x|length) as $nr
| ($x[0]|length) as $nc
| reduce range(0; $d) as $i (matrix($nr;$nc;0); .[$i][$i] = 1)
| reduce range($d; $nr) as $i (.;
reduce range($d;$nc) as $j (.; .[$i][$j] = $x[$i][$j] ) );
 
def vmadd($a; $b; $s):
reduce range (0; $a|length) as $i ([];
.[$i] = $a[$i] + $s * $b[$i] );
 
def vmul($v):
($v|length) as $n
| reduce range(0;$n) as $i (null;
reduce range(0;$n) as $j (.; .[$i][$j] = -2 * $v[$i] * $v[$j] ))
| reduce range(0;$n) as $i (.; .[$i][$i] += 1 );
 
def vnorm($x):
sum($x[] | .*.) | sqrt;
 
def vdiv($x; $d):
[range (0;$x|length) | $x[.] / $d];
 
def mcol($m; $c):
[range (0;$m|length) | $m[.][$c]];
 
def householder($m):
($m|length) as $nr
| ($m[0]|length) as $nc
| { q: [], # $nr
z: $m,
k: 0 }
| until( .k >= $nc or .k >= $nr-1;
.z = minor(.z; .k)
| .x = mcol(.z; .k)
| .a = vnorm(.x)
| if ($m[.k][.k] > 0) then .a = -.a else . end
| .e = [range (0; $nr) as $i | if ($i == .k) then 1 else 0 end]
| .e = vmadd(.x; .e; .a)
| .e = vdiv(.e; vnorm(.e))
| .q[.k] = vmul(.e)
| .z = multiply(.q[.k]; .z)
| .k += 1 )
| .Q = .q[0]
| .R = multiply(.q[0]; $m)
| .i = 1
| until (.i >= $nc or .i >= $nr-1;
.Q = multiply(.q[.i]; .Q)
| .i += 1 )
| .R = multiply(.Q; $m)
| .Q |= transpose
| [.Q, .R] ;
 
def x: [
[12, -51, 4],
[ 6, 167, -68],
[-4, 24, -41],
[-1, 1, 0],
[ 2, 0, 3]
];
 
def task:
def pp: pp(3;8);
 
# Assume $a and $b are conformal
def ssd($a; $b):
[$a[][]] as $a
| [$b[][]] as $b
| ss( range(0;$a|length) | $a[.] - $b[.] );
 
householder(x) as [$Q, $R]
| multiply($Q; $R) as $m
| "Q:", ($Q|pp),
"\nR:", ($R|pp),
"\nQ * R:", ($m|pp),
"\nSum of squared discrepancies: \(ssd(x; $m))"
;
 
task
</syntaxhighlight>
{{output}}
<pre>
Q:
 
0.846 -0.391 0.343 0.082 0.078
0.423 0.904 -0.029 0.026 0.045
-0.282 0.170 0.933 -0.047 -0.137
-0.071 0.014 -0.001 0.980 -0.184
0.141 -0.017 -0.106 -0.171 -0.969
 
R:
 
14.177 20.667 -13.402
-0.000 175.043 -70.080
0.000 0.000 -35.202
-0.000 -0.000 -0.000
0.000 0.000 -0.000
 
Q * R:
 
12.000 -51.000 4.000
6.000 167.000 -68.000
-4.000 24.000 -41.000
-1.000 1.000 -0.000
2.000 -0.000 3.000
 
Sum of squared discrepancies: 1.1675699109208862e-26
</pre>
 
=={{header|Julia}}==
Built-in function
<langsyntaxhighlight lang="julia">Q, R = qr([12 -51 4; 6 167 -68; -4 24 -41])</langsyntaxhighlight>
{{out}}
<pre>
Line 1,754 ⟶ 3,774:
=={{header|Maple}}==
 
<syntaxhighlight lang="maple">with(LinearAlgebra):
<lang Maple>
A:=<12,-51,4;6,167,-68;-4,24,-41>:
with(LinearAlgebra):
Q,R:=QRDecomposition(A):
Q;
R;</syntaxhighlight>
 
{{out}}
Q,R := QRDecomposition( evalf( <<12|-51|4>,<6|167|-68>,<-4|24|-41>>) ):
 
<pre> [ -69 -58 ]
Q;
[6/7 --- --- ]
R;
[ 175 175 ]
</lang>
[ ]
Output:
[ 158 ]
<pre>
[3/7 [-0.857142857142857 --- 0.394285714285714 0.3314285714285716/175]
[ 175 ]
[ ]
[-0.428571428571429 -0.902857142857143 -0.0342857142857143]
[ -33 ]
[-2/7 [ 0.2857142857142866/35 -0.171428571428571 --- 0.942857142857143]
[ 35 ]
 
[-14. -21. 14.0000000000000]
[ ]
[ 0. -175.000000000000 70.0000000000000]
[ ]
[ 0. 0. -35.]
</pre>
 
[14 21 -14]
=={{header|Mathematica}}==
[ ]
<lang Mathematica>{q,r}=QRDecomposition[{{12, -51, 4}, {6, 167, -68}, {-4, 24, -41}}];
[ 0 175 -70]
[ ]
[ 0 0 35]</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">{q,r}=QRDecomposition[{{12, -51, 4}, {6, 167, -68}, {-4, 24, -41}}];
q//MatrixForm
 
Line 1,788 ⟶ 3,812:
-> 14 21 -14
0 175 -70
0 0 35</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight Matlablang="matlab"> A = [12 -51 4
6 167 -68
-4 24 -41];
[Q,R]=qr(A) </langsyntaxhighlight>
Output:
<pre>Q =
Line 1,809 ⟶ 3,833:
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">load(lapack)$ /* This may hang up in wxMaxima, if this happens, use xMaxima or plain MAximaMaxima in a terminal */
 
a: matrix([12, -51, 4],
Line 1,820 ⟶ 3,844:
4.2632564145606011E-14
 
/* Note: the lapack package is a lisp translation of the fortran lapack library */</langsyntaxhighlight>
For an exact or arbitrary precision solution:<langsyntaxhighlight lang="maxima">load("linearalgebra")$
load("eigen")$
unitVector(n) := ematrix(n,1,1,1,1);
Line 1,864 ⟶ 3,888:
a : genmatrix(lambda([i,j], if j=1 then 1.0b0 else bfloat(x[i,1]^(j-1))),
length(x),n+1),
lsqr(a,y));</langsyntaxhighlight>Then we have the examples:<syntaxhighlight lang ="maxima">(%i) [q,r] : qr(a);
 
[ 6 69 58 ]
Line 1,892 ⟶ 3,916:
(%o) [ 2.00000000000000000000000000002b0 ]
[ ]
[ 3.0b0 ]</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|Python}}
{{libheader|arraymancer}}
The library “arraymancer” provides a function “qr” to get the QR decomposition. Using the Tensor type of “arraymancer” we propose here an implementation of this decomposition adapted from the Python version.
<syntaxhighlight lang="nim">import math, strformat, strutils
import arraymancer
 
####################################################################################################
# First part: QR decomposition.
 
proc eye(n: Positive): Tensor[float] =
## Return the (n, n) identity matrix.
result = newTensor[float](n.int, n.int)
for i in 0..<n: result[i, i] = 1
 
proc norm(v: Tensor[float]): float =
## return the norm of a vector.
assert v.shape.len == 1
result = sqrt(dot(v, v)) * sgn(v[0]).toFloat
 
proc houseHolder(a: Tensor[float]): Tensor[float] =
## return the house holder of vector "a".
var v = a / (a[0] + norm(a))
v[0] = 1
result = eye(a.shape[0]) - (2 / dot(v, v)) * (v.unsqueeze(1) * v.unsqueeze(0))
 
proc qrDecomposition(a: Tensor): tuple[q, r: Tensor] =
## Return the QR decomposition of matrix "a".
assert a.shape.len == 2
let m = a.shape[0]
let n = a.shape[1]
result.q = eye(m)
result.r = a.clone
for i in 0..<(n - ord(m == n)):
var h = eye(m)
h[i..^1, i..^1] = houseHolder(result.r[i..^1, i].squeeze(1))
result.q = result.q * h
result.r = h * result.r
 
####################################################################################################
# Second part: polynomial regression example.
 
proc lsqr(a, b: Tensor[float]): Tensor[float] =
let (q, r) = a.qrDecomposition()
let n = r.shape[1]
result = solve(r[0..<n, _], (q.transpose() * b)[0..<n])
 
proc polyfit(x, y: Tensor[float]; n: int): Tensor[float] =
var z = newTensor[float](x.shape[0], n + 1)
var t = x.reshape(x.shape[0], 1)
for i in 0..n: z[_, i] = t^.i.toFloat
result = lsqr(z, y.transpose())
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
proc printMatrix(a: Tensor) =
var str: string
for i in 0..<a.shape[0]:
let start = str.len
for j in 0..<a.shape[1]:
str.addSep(" ", start)
str.add &"{a[i, j]:8.3f}"
str.add '\n'
stdout.write str
 
proc printVector(a: Tensor) =
var str: string
for i in 0..<a.shape[0]:
str.addSep(" ")
str.add &"{a[i]:4.1f}"
echo str
 
 
let mat = [[12, -51, 4],
[ 6, 167, -68],
[-4, 24, -41]].toTensor.astype(float)
 
let (q, r) = mat.qrDecomposition()
echo "Q:"
printMatrix q
echo "R:"
printMatrix r
echo()
 
let x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].toTensor.astype(float)
let y = [1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321].toTensor.astype(float)
echo "polyfit:"
printVector polyfit(x, y, 2)</syntaxhighlight>
 
{{out}}
<pre>Q:
-0.857 0.394 0.331
-0.429 -0.903 -0.034
0.286 -0.171 0.943
R:
-14.000 -21.000 14.000
0.000 -175.000 70.000
0.000 -0.000 -35.000
 
polyfit:
1.0 2.0 3.0</pre>
 
=={{header|PARI/GP}}==
{{works with|PARI/GP|2.6.0 and above}}
<syntaxhighlight lang ="parigp">matqr(M)</langsyntaxhighlight>
 
=={{header|Perl}}==
Letting the <code>PDL</code> module do all the work.
<syntaxhighlight lang="perl">use strict;
use warnings;
 
use PDL;
use PDL::LinearAlgebra qw(mqr);
 
my $a = pdl(
[12, -51, 4],
[ 6, 167, -68],
[-4, 24, -41],
[-1, 1, 0],
[ 2, 0, 3]
);
 
my ($q, $r) = mqr($a);
print $q, $r, $q x $r;</syntaxhighlight>
{{out}}
<pre>[
[ -0.84641474 0.39129081 -0.34312406]
[ -0.42320737 -0.90408727 0.029270162]
[ 0.28213825 -0.17042055 -0.93285599]
[ 0.070534562 -0.014040652 0.001099372]
[ -0.14106912 0.016655511 0.10577161]
]
 
[
[-14.177447 -20.666627 13.401567]
[ 0 -175.04254 70.080307]
[ 0 0 35.201543]
]
 
[
[ 12 -51 4]
[ 6 167 -68]
[ -4 24 -41]
[ -1 1 0]
[ 2 0 3]
]</pre>
 
=={{header|Phix}}==
using matrix_mul() from [[Matrix_multiplication#Phix]]
and matrix_transpose() from [[Matrix_transposition#Phix]]
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo/rosettacode/QRdecomposition.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">arows</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">~</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">acols</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">~</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">brows</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">~</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bcols</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">~</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">acols</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">brows</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bcols</span><span style="color: #0000FF;">),</span><span style="color: #000000;">arows</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">arows</span> <span style="color: #008080;">do</span>
<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;">bcols</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">acols</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</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: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">vtranspose</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- transpose a vector of length m into an mx1 matrix,
-- eg {1,2,3} -&gt; <nowiki>{{</nowiki>1},{2},{3<nowiki>}}</nowiki></span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span> <span style="color: #000000;">res</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: #0000FF;">{</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mat_col</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">la</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">la</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">col</span> <span style="color: #008080;">to</span> <span style="color: #000000;">la</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</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;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mat_norm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mat_ident</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</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;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">QRHouseholder</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">cols</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
<span style="color: #000000;">rows</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">I</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mat_ident</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">Q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">I</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span>
<span style="color: #000080;font-style:italic;">--
-- Programming note: The code of this main loop was not as easily
-- written as the first glance might suggest. Explicitly setting
-- to 0 any a[i,j] [etc] that should be 0 but have inadvertently
-- gotten set to +/-1e-15 or thereabouts may be advisable. The
-- commented-out code was retrieved from a backup and should be
-- treated as an example and not be trusted (iirc, it made no
-- difference to the test cases used, so I deleted it, and then
-- had second thoughts about it a few days later).
--</span>
<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: #7060A8;">min</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><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">u</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mat_col</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">u</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: #000000;">mat_norm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mat_norm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">I</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vtranspose</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">),{</span><span style="color: #000000;">v</span><span style="color: #0000FF;">})))</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- for row=j+1 to length(a) do
-- a[row][j] = 0
-- end for</span>
<span style="color: #000000;">Q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- Get the upper triangular matrix R.</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">R</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (logically 1 to m(&gt;=n), but no need)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">R</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</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: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">R</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">51</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">167</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">68</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">24</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">41</span><span style="color: #0000FF;">}}</span>
<span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">q</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;">QRHouseholder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">ppOpt</span><span style="color: #0000FF;">({</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4d"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_FltFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4g"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">})</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"A"</span> <span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"Q"</span> <span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"R"</span> <span style="color: #7060A8;">pp</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: #008000;">"Q * R"</span> <span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">matrix_transpose</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">mat</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">rows</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mat</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">cols</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mat</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">),</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">)</span>
<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;">rows</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">cols</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</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;">mat</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">][</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">--?"Q * Q'" pp(matrix_mul(q,matrix_transpose(q))) -- (~1e-16s)</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"Q * Q`"</span> <span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">matrix_transpose</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">)),</span><span style="color: #000000;">1e15</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">least_squares</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</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: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">y</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: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">34</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">57</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">86</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">121</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">162</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">209</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">262</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">321</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<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;">3</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</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;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">q</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;">QRHouseholder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">matrix_transpose</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">matrix_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vtranspose</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)),</span>
<span style="color: #000000;">z</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">z</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">z</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Least-squares solution:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- printf(1," %v\n",{z}) -- {1.0,2.0.3,0}
-- printf(1," %v\n",{sq_sub(z,{1,2,3})}) -- (+/- ~1e-14s)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">sq_round</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1e13</span><span style="color: #0000FF;">)})</span> <span style="color: #000080;font-style:italic;">-- {1,2,3}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">least_squares</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
"A"
{{  12, -51,   4},
 {   6, 167, -68},
 {  -4,  24, -41}}
"Q"
{{0.85714,-0.3943,0.33143},
 {0.42857,0.90286,-0.0343},
 {-0.2857,0.17143,0.94286}}
"R"
{{  14,  21, -14},
 {   0, 175, -70},
 {   0,   0, -35}}
"Q * R"
{{  12, -51,   4},
 {   6, 167, -68},
 {  -4,  24, -41}}
"Q * Q`"
{{   1,   0,   0},
 {   0,   1,   0},
 {   0,   0,   1}}
Least-squares solution:
 {1,2,3}
</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function qr([double[][]]$A) {
$m,$n = $A.count, $A[0].count
$pm,$pn = ($m-1), ($n-1)
[double[][]]$Q = 0..($m-1) | foreach{$row = @(0) * $m; $row[$_] = 1; ,$row}
[double[][]]$R = $A | foreach{$row = $_; ,@(0..$pn | foreach{$row[$_]})}
foreach ($h in 0..$pn) {
[double[]]$u = $R[$h..$pm] | foreach{$_[$h]}
[double]$nu = $u | foreach {[double]$sq = 0} {$sq += $_*$_} {[Math]::Sqrt($sq)}
$u[0] -= if ($u[0] -lt 0) {$nu} else {-$nu}
[double]$nu = $u | foreach {$sq = 0} {$sq += $_*$_} {[Math]::Sqrt($sq)}
[double[]]$u = $u | foreach { $_/$nu}
[double[][]]$v = 0..($u.Count - 1) | foreach{$i = $_; ,($u | foreach{2*$u[$i]*$_})}
[double[][]]$CR = $R | foreach{$row = $_; ,@(0..$pn | foreach{$row[$_]})}
[double[][]]$CQ = $Q | foreach{$row = $_; ,@(0..$pm | foreach{$row[$_]})}
foreach ($i in $h..$pm) {
foreach ($j in $h..$pn) {
$R[$i][$j] -= $h..$pm | foreach {[double]$sum = 0} {$sum += $v[$i-$h][$_-$h]*$CR[$_][$j]} {$sum}
}
}
if (0 -eq $h) {
foreach ($i in $h..$pm) {
foreach ($j in $h..$pm) {
$Q[$i][$j] -= $h..$pm | foreach {$sum = 0} {$sum += $v[$i][$_]*$CQ[$_][$j]} {$sum}
}
}
} else {
$p = $h-1
foreach ($i in $h..$pm) {
foreach ($j in 0..$p) {
$Q[$i][$j] -= $h..$pm | foreach {$sum = 0} {$sum += $v[$i-$h][$_-$h]*$CQ[$_][$j]} {$sum}
}
foreach ($j in $h..$pm) {
$Q[$i][$j] -= $h..$pm | foreach {$sum = 0} {$sum += $v[$i-$h][$_-$h]*$CQ[$_][$j]} {$sum}
}
}
}
}
foreach ($i in 0..$pm) {
foreach ($j in $i..$pm) {$Q[$i][$j],$Q[$j][$i] = $Q[$j][$i],$Q[$i][$j]}
}
[PSCustomObject]@{"Q" = $Q; "R" = $R}
}
 
function leastsquares([Double[][]]$A,[Double[]]$y) {
$QR = qr $A
[Double[][]]$Q = $QR.Q
[Double[][]]$R = $QR.R
$m,$n = $A.count, $A[0].count
[Double[]]$z = foreach ($j in 0..($m-1)) {
0..($m-1) | foreach {$sum = 0} {$sum += $Q[$_][$j]*$y[$_]} {$sum}
}
[Double[]]$x = @(0)*$n
for ($i = $n-1; $i -ge 0; $i--) {
for ($j = $i+1; $j -lt $n; $j++) {
$z[$i] -= $x[$j]*$R[$i][$j]
}
$x[$i] = $z[$i]/$R[$i][$i]
}
$x
}
 
function polyfit([Double[]]$x,[Double[]]$y,$n) {
$m = $x.Count
[Double[][]]$A = 0..($m-1) | foreach{$row = @(1) * ($n+1); ,$row}
for ($i = 0; $i -lt $m; $i++) {
for ($j = $n-1; 0 -le $j; $j--) {
$A[$i][$j] = $A[$i][$j+1]*$x[$i]
}
}
leastsquares $A $y
}
 
function show($m) {$m | foreach {write-host "$_"}}
 
$A = @(@(12,-51,4), @(6,167,-68), @(-4,24,-41))
$x = @(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
$y = @(1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321)
$QR = qr $A
$ps = (polyfit $x $y 2)
"Q = "
show $QR.Q
"R = "
show $QR.R
"polyfit "
"X^2 X constant"
"$(polyfit $x $y 2)"
</syntaxhighlight>
{{out}}
<pre>
Q =
-0.857142857142857 0.394285714285714 -0.331428571428571
-0.428571428571429 -0.902857142857143 0.0342857142857143
0.285714285714286 -0.171428571428571 -0.942857142857143
R =
-14 -21 14
8.88178419700125E-16 -175 70
-4.44089209850063E-16 0 35
polyfit
X^2 X constant
3 1.99999999999998 1.00000000000005
</pre>
 
=={{header|Python}}==
{{libheader|NumPy}}
Numpy has a qr function but here is a reimplementation to show construction and use of the Householder reflections.
<syntaxhighlight lang="python">#!/usr/bin/env python3
 
import numpy as np
 
def qr(A):
m, n = A.shape
Q = np.eye(m)
for i in range(n - (m == n)):
H = np.eye(m)
H[i:, i:] = make_householder(A[i:, i])
Q = np.dot(Q, H)
A = np.dot(H, A)
return Q, A
 
def make_householder(a):
v = a / (a[0] + np.copysign(np.linalg.norm(a), a[0]))
v[0] = 1
H = np.eye(a.shape[0])
H -= (2 / np.dot(v, v)) * np.dot(v[:, None], v[None, :])
return H
 
# task 1: show qr decomp of wp example
a = np.array(((
(12, -51, 4),
( 6, 167, -68),
(-4, 24, -41),
)))
 
q, r = qr(a)
print('q:\n', q.round(6))
print('r:\n', r.round(6))
 
# task 2: use qr decomp for polynomial regression example
def polyfit(x, y, n):
return lsqr(x[:, None]**np.arange(n + 1), y.T)
 
def lsqr(a, b):
q, r = qr(a)
_, n = r.shape
return np.linalg.solve(r[:n, :], np.dot(q.T, b)[:n])
 
x = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
y = np.array((1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321))
 
print('\npolyfit:\n', polyfit(x, y, 2))</syntaxhighlight>
{{out}}
<pre>
q:
[[-0.857143 0.394286 0.331429]
[-0.428571 -0.902857 -0.034286]
[ 0.285714 -0.171429 0.942857]]
r:
[[ -14. -21. 14.]
[ 0. -175. 70.]
[ 0. 0. -35.]]
 
polyfit:
[ 1. 2. 3.]
</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r"># R has QR decomposition built-in (using LAPACK or LINPACK)
 
a <- matrix(c(12, -51, 4, 6, 167, -68, -4, 24, -41), nrow=3, ncol=3, byrow=T)
d <- qr(a)
qr.Q(d)
qr.R(d)
 
# now fitting a polynomial
x <- 0:10
y <- 3*x^2 + 2*x + 1
 
# using QR decomposition directly
a <- cbind(1, x, x^2)
qr.coef(qr(a), y)
 
# using least squares
a <- cbind(x, x^2)
lsfit(a, y)$coefficients
 
# using a linear model
xx <- x*x
m <- lm(y ~ x + xx)
coef(m)</syntaxhighlight>
 
=={{header|Racket}}==
 
Racket has QR-decomposition builtin:
<syntaxhighlight lang="racket">
> (require math)
> (matrix-qr (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]]))
(array #[#[6/7 -69/175 -58/175] #[3/7 158/175 6/175] #[-2/7 6/35 -33/35]])
(array #[#[14 21 -14] #[0 175 -70] #[0 0 35]])
</syntaxhighlight>
 
The builtin QR-decomposition uses the Gram-Schmidt algorithm.
 
Here is an implementation of the Householder method:
<syntaxhighlight lang="racket">
#lang racket
(require math/matrix math/array)
(define-values (T I col size)
(values ; short names
matrix-transpose identity-matrix matrix-col matrix-num-rows))
 
(define (scale c A) (matrix-scale A c))
(define (unit n i) (build-matrix n 1 (λ (j _) (if (= j i) 1 0))))
 
(define (H u)
(matrix- (I (size u))
(scale (/ 2 (matrix-dot u u))
(matrix* u (T u)))))
 
(define (normal a)
(define a0 (matrix-ref a 0 0))
(matrix- a (scale (* (sgn a0) (matrix-2norm a))
(unit (size a) 0))))
 
(define (QR A)
(define n (size A))
(for/fold ([Q (I n)] [R A]) ([i (- n 1)])
(define Hi (H (normal (submatrix R (:: i n) (:: i (+ i 1))))))
(define Hi* (if (= i 0) Hi (block-diagonal-matrix (list (I i) Hi))))
(values (matrix* Q Hi*) (matrix* Hi* R))))
 
(QR (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]]))
</syntaxhighlight>
Output:
<syntaxhighlight lang="racket">
(array #[#[6/7 69/175 -58/175]
#[3/7 -158/175 6/175]
#[-2/7 -6/35 -33/35]])
(array #[#[14 21 -14]
#[0 -175 70]
#[0 0 35]])
</syntaxhighlight>
 
=={{header|Perl 6Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.06}}
<syntaxhighlight lang="raku" perl6line># sub householder translated from https://codereview.stackexchange.com/questions/120978/householder-transformation
 
use v6;
Line 2,079 ⟶ 4,673:
"\n",
@coef.fmt("%12.6f");
}</langsyntaxhighlight>
 
output:
Line 2,116 ⟶ 4,710:
 
</pre>
 
 
=={{header|Phix}}==
using matrix_mul from [[Matrix_multiplication#Phix]]
<lang Phix>-- demo/rosettacode/QRdecomposition.exw
function vtranspose(sequence v)
-- transpose a vector of length m into an mx1 matrix,
-- eg {1,2,3} -> {{1},{2},{3}}
for i=1 to length(v) do v[i] = {v[i]} end for
return v
end function
 
function mat_col(sequence a, integer col)
sequence res = repeat(0,length(a))
for i=col to length(a) do
res[i] = a[i,col]
end for
return res
end function
 
function mat_norm(sequence a)
atom res = 0
for i=1 to length(a) do
res += a[i]*a[i]
end for
res = sqrt(res)
return res
end function
 
function mat_ident(integer n)
sequence res = repeat(repeat(0,n),n)
for i=1 to n do
res[i,i] = 1
end for
return res
end function
 
function QRHouseholder(sequence a)
integer columns = length(a[1]),
rows = length(a),
m = max(columns,rows),
n = min(rows,columns)
sequence q, I = mat_ident(m), Q = I, u, v
 
for j=1 to min(m-1,n) do
u = mat_col(a,j)
u[j] -= mat_norm(u)
v = sq_div(u,mat_norm(u))
q = sq_sub(I,sq_mul(2,matrix_mul(vtranspose(v),{v})))
a = matrix_mul(q,a)
Q = matrix_mul(Q,q)
end for
 
-- Get the upper triangular matrix R.
sequence R = repeat(repeat(0,n),m)
for i=1 to n do
for j=i to n do
R[i,j] = a[i,j]
end for
end for
return {Q,R}
end function
 
sequence a = {{12, -51, 4},
{ 6, 167, -68},
{-4, 24, -41}},
{q,r} = QRHouseholder(a)
 
?"A" pp(a,{pp_Nest,1})
?"Q" pp(q,{pp_Nest,1})
?"R" pp(r,{pp_Nest,1})
?"Q * R" pp(matrix_mul(q,r),{pp_Nest,1})</lang>
{{out}}
<pre>
"A"
{{12,-51,4},
{6,167,-68},
{-4,24,-41}}
"Q"
{{0.8571428571,-0.3942857143,0.3314285714},
{0.4285714286,0.9028571429,-0.03428571429},
{-0.2857142857,0.1714285714,0.9428571429}}
"R"
{{14,21,-14},
{0,175,-70},
{0,0,-35}}
"Q * R"
{{12,-51,4},
{6,167,-68},
{-4,24,-41}}
</pre>
using matrix_transpose from [[Matrix_transposition#Phix]]
<lang Phix>procedure least_squares()
sequence x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
y = {1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321},
a = repeat(repeat(0,3),length(x))
for i=1 to length(x) do
for j=1 to 3 do
a[i,j] = power(x[i],j-1)
end for
end for
{q,r} = QRHouseholder(a)
sequence t = matrix_transpose(q),
b = matrix_mul(t,vtranspose(y)),
z = repeat(0,3)
for k=3 to 1 by -1 do
atom s = 0
if k<3 then
for j = k+1 to 3 do
s += r[k,j]*z[j]
end for
end if
z[k] = (b[k][1]-s)/r[k,k]
end for
?{"Least-squares solution:",z}
end procedure
least_squares()</lang>
{{out}}
<pre>
{"Least-squares solution:",{1.0,2.0,3.0}}
</pre>
 
=={{header|Python}}==
{{libheader|NumPy}}
Numpy has a qr function but here is a reimplementation to show construction and use of the Householder reflections.
<lang python>#!/usr/bin/env python3
 
import numpy as np
 
def qr(A):
m, n = A.shape
Q = np.eye(m)
for i in range(n - (m == n)):
H = np.eye(m)
H[i:, i:] = make_householder(A[i:, i])
Q = np.dot(Q, H)
A = np.dot(H, A)
return Q, A
 
def make_householder(a):
v = a / (a[0] + np.copysign(np.linalg.norm(a), a[0]))
v[0] = 1
H = np.eye(a.shape[0])
H -= (2 / np.dot(v, v)) * np.dot(v[:, None], v[None, :])
return H
 
# task 1: show qr decomp of wp example
a = np.array(((
(12, -51, 4),
( 6, 167, -68),
(-4, 24, -41),
)))
 
q, r = qr(a)
print('q:\n', q.round(6))
print('r:\n', r.round(6))
 
# task 2: use qr decomp for polynomial regression example
def polyfit(x, y, n):
return lsqr(x[:, None]**np.arange(n + 1), y.T)
 
def lsqr(a, b):
q, r = qr(a)
_, n = r.shape
return np.linalg.solve(r[:n, :], np.dot(q.T, b)[:n])
 
x = np.array((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
y = np.array((1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321))
 
print('\npolyfit:\n', polyfit(x, y, 2))</lang>
{{out}}
<pre>
q:
[[-0.857143 0.394286 0.331429]
[-0.428571 -0.902857 -0.034286]
[ 0.285714 -0.171429 0.942857]]
r:
[[ -14. -21. 14.]
[ 0. -175. 70.]
[ 0. 0. -35.]]
 
polyfit:
[ 1. 2. 3.]
</pre>
 
=={{header|R}}==
<lang r># R has QR decomposition built-in (using LAPACK or LINPACK)
 
a <- matrix(c(12, -51, 4, 6, 167, -68, -4, 24, -41), nrow=3, ncol=3, byrow=T)
d <- qr(a)
qr.Q(d)
qr.R(d)
 
# now fitting a polynomial
x <- 0:10
y <- 3*x^2 + 2*x + 1
 
# using QR decomposition directly
a <- cbind(1, x, x^2)
qr.coef(qr(a), y)
 
# using least squares
a <- cbind(x, x^2)
lsfit(a, y)$coefficients
 
# using a linear model
xx <- x*x
m <- lm(y ~ x + xx)
coef(m)</lang>
 
=={{header|Racket}}==
 
Racket has QR-decomposition builtin:
<lang racket>
> (require math)
> (matrix-qr (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]]))
(array #[#[6/7 -69/175 -58/175] #[3/7 158/175 6/175] #[-2/7 6/35 -33/35]])
(array #[#[14 21 -14] #[0 175 -70] #[0 0 35]])
</lang>
 
The builtin QR-decomposition uses the Gram-Schmidt algorithm.
 
Here is an implementation of the Householder method:
<lang racket>
#lang racket
(require math/matrix math/array)
(define-values (T I col size)
(values ; short names
matrix-transpose identity-matrix matrix-col matrix-num-rows))
 
(define (scale c A) (matrix-scale A c))
(define (unit n i) (build-matrix n 1 (λ (j _) (if (= j i) 1 0))))
 
(define (H u)
(matrix- (I (size u))
(scale (/ 2 (matrix-dot u u))
(matrix* u (T u)))))
 
(define (normal a)
(define a0 (matrix-ref a 0 0))
(matrix- a (scale (* (sgn a0) (matrix-2norm a))
(unit (size a) 0))))
 
(define (QR A)
(define n (size A))
(for/fold ([Q (I n)] [R A]) ([i (- n 1)])
(define Hi (H (normal (submatrix R (:: i n) (:: i (+ i 1))))))
(define Hi* (if (= i 0) Hi (block-diagonal-matrix (list (I i) Hi))))
(values (matrix* Q Hi*) (matrix* Hi* R))))
 
(QR (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]]))
</lang>
Output:
<lang racket>
(array #[#[6/7 69/175 -58/175]
#[3/7 -158/175 6/175]
#[-2/7 -6/35 -33/35]])
(array #[#[14 21 -14]
#[0 -175 70]
#[0 0 35]])
</lang>
 
=={{header|Rascal}}==
Line 2,387 ⟶ 4,715:
This function applies the Gram Schmidt algorithm. Q is printed in the console, R can be printed or visualized.
 
<langsyntaxhighlight Rascallang="rascal">import util::Math;
import Prelude;
import vis::Figure;
Line 2,479 ⟶ 4,807:
<1.0,0.0,-51.0>, <1.0,1.0,167.0>, <1.0,2.0,24.0>,
<2.0,0.0,4.0>, <2.0,1.0,-68.0>, <2.0,2.0,-41.0>
};</langsyntaxhighlight>
 
Example using visualization
Line 2,499 ⟶ 4,827:
 
=={{header|SAS}}==
<langsyntaxhighlight lang="sas">/* See http://support.sas.com/documentation/cdl/en/imlug/63541/HTML/default/viewer.htm#imlug_langref_sect229.htm */
 
proc iml;
Line 2,529 ⟶ 4,857:
0 -175 70
0 0 35
*/</langsyntaxhighlight>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser [https://scastie.scala-lang.org/NMueO16uQl6oivliBKZHew Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">import java.io.{PrintWriter, StringWriter}
 
import Jama.{Matrix, QRDecomposition}
Line 2,553 ⟶ 4,882:
print(toString(d.getR))
 
}</langsyntaxhighlight>
 
=={{header|SequenceL}}==
{{trans|Go}}
<langsyntaxhighlight lang="sequencel">import <Utilities/Math.sl>;
import <Utilities/Sequence.sl>;
import <Utilities/Conversion.sl>;
Line 2,645 ⟶ 4,974:
j within 1 ... n;
mm(A(2), B(2))[i,j] := sum( A[i] * transpose(B)[j] );</langsyntaxhighlight>
 
{{out}}
Line 2,667 ⟶ 4,996:
 
=={{header|Standard ML}}==
{{trans|Axiom}}
We first define a signature for a radical category joined with a field. We then define a functor with (a) structures to define operators and functions for Array and Array2, and (b) functions for the QR decomposition (adapted from Axiom):
We first define a signature for a radical category joined with a field. We then define a functor with (a) structures to define operators and functions for Array and Array2, and (b) functions for the QR decomposition:
<lang sml>signature RADCATFIELD = sig
<syntaxhighlight lang="sml">signature RADCATFIELD = sig
type real
val zero : real
Line 2,676 ⟶ 5,006:
val * : real * real -> real
val / : real * real -> real
val toString : real -> string
val sign : real -> real
val sqrt : real -> real
Line 2,731 ⟶ 5,060:
fun updateSubMatrix(h,i,j,s) =
tabulate RowMajor (nRows s, nCols s, fn (a,b) => update(h,Int.+(i,a),Int.+(j,b),sub(s,a,b)))
fun print a =
let
val (m,n) = dimensions a
fun loop(i,j,x) =
(if i=0 andalso j=0 then TextIO.print "Array2.fromList([" else ();
if j=0 andalso Int.>(i,0) then TextIO.print "," else ();
if j=0 then TextIO.print "[" else ();
if Int.>(j,0) then TextIO.print "," else ();
(TextIO.print o F.toString) x;
if j=Int.-(n,1) then TextIO.print "]" else ();
if i=Int.-(m,1) andalso j=Int.-(n,1) then TextIO.print "])\n" else ())
in
appi RowMajor loop {base=a,nrows=SOME m,ncols=SOME n,row=0,col=0}
end
end
end
fun toList a =
List.tabulate(Array2.nRows a, fn i => List.tabulate(Array2.nCols a, fn j => Array2.sub(a,i,j)))
fun householder a =
let open Array
Line 2,806 ⟶ 5,123:
lsqr(a,y)
end
end</langsyntaxhighlight>
We can then show the examples:<langsyntaxhighlight lang="sml">structure RealRadicalCategoryField : RADCATFIELD = struct
open Real
val one = 1.0
Line 2,814 ⟶ 5,131:
val sqrt = Real.Math.sqrt
end
 
val mat = Array2.fromList [[12.0, ~51.0, 4.0], [6.0, 167.0, ~68.0], [~4.0, 24.0, ~41.0]];
structure Q = QR(RealRadicalCategoryField);
 
structure M = Q.M;
let
let val {q,r} = Q.qr(mat) in (M.print q; M.print r) end;
val mat = Array2.fromList [[12.0, ~51.0, 4.0], [6.0, 167.0, ~68.0], [~4.0, 24.0, ~41.0]]
val fit =
letval open{q,r} Array= Q.qr(mat)
in
val x = fromList [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
{q=Q.toList q; r=Q.toList r}
val y = fromList [1.0, 6.0, 17.0, 34.0, 57.0, 86.0, 121.0, 162.0, 209.0, 262.0, 321.0]
end;
in
(* output *)
Q.polyfit(x, y, 2)
val it =
end
{q=[[~0.857142857143,0.394285714286,0.331428571429],
[~0.428571428571,~0.902857142857,~0.0342857142857],
[0.285714285714,~0.171428571429,0.942857142857]],
r=[[~14.0,~21.0,14.0],[5.97812397875E~18,~175.0,70.0],
[4.47505280695E~16,0.0,~35.0]]} : {q:real list list, r:real list list}
 
let open Array
val x = fromList [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
val y = fromList [1.0, 6.0, 17.0, 34.0, 57.0, 86.0, 121.0, 162.0, 209.0, 262.0, 321.0]
in
Q.polyfit(x, y, 2)
end;
 
(* output *)
val it = [|1.0,2.0,3.0|] : real array</syntaxhighlight>
Array2.fromList([[~0.857142857143,0.394285714286,0.331428571429],
[~0.428571428571,~0.902857142857,~0.0342857142857],
[0.285714285714,~0.171428571429,0.942857142857]])
Array2.fromList([[~14.0,~21.0,14.0],
[5.97812397875E~18,~175.0,70.0],
[4.47505280695E~16,0.0,~35.0]])
val fit = [|1.0,2.0,3.0|] : real array</lang>
 
=={{header|Stata}}==
See [http://www.stata.com/help.cgi?mf_qrd QR decomposition] in Stata help.
 
<langsyntaxhighlight lang="stata">mata
: qrd(a=(12,-51,4\6,167,-68\-4,24,-41),q=.,r=.)
 
Line 2,863 ⟶ 5,186:
2 | 0 -175 70 |
3 | 0 0 -35 |
+----------------------+</langsyntaxhighlight>
 
=={{header|Tcl}}==
Assuming the presence of the Tcl solutions to these tasks: [[Element-wise operations]], [[Matrix multiplication]], [[Matrix transposition]]
{{trans|Common Lisp}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace path {::tcl::mathfunc ::tcl::mathop}
proc sign x {expr {$x == 0 ? 0 : $x < 0 ? -1 : 1}}
Line 2,925 ⟶ 5,248:
}
return [list $Q $A]
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set demo [qrDecompose {{12 -51 4} {6 167 -68} {-4 24 -41}}]
puts "==Q=="
print_matrix [lindex $demo 0] "%f"
puts "==R=="
print_matrix [lindex $demo 1] "%.1f"</langsyntaxhighlight>
Output:
<pre>
Line 2,942 ⟶ 5,265:
0.0 -175.0 70.0
0.0 0.0 -35.0
</pre>
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Option Base 1
Private Function vtranspose(v As Variant) As Variant
'-- transpose a vector of length m into an mx1 matrix,
'-- eg {1,2,3} -> {1;2;3}
vtranspose = WorksheetFunction.Transpose(v)
End Function
Private Function mat_col(a As Variant, col As Integer) As Variant
Dim res() As Double
ReDim res(UBound(a))
For i = col To UBound(a)
res(i) = a(i, col)
Next i
mat_col = res
End Function
Private Function mat_norm(a As Variant) As Double
mat_norm = Sqr(WorksheetFunction.SumProduct(a, a))
End Function
Private Function mat_ident(n As Integer) As Variant
mat_ident = WorksheetFunction.Munit(n)
End Function
 
Private Function sq_div(a As Variant, p As Double) As Variant
Dim res() As Variant
ReDim res(UBound(a))
For i = 1 To UBound(a)
res(i) = a(i) / p
Next i
sq_div = res
End Function
 
Private Function sq_mul(p As Double, a As Variant) As Variant
Dim res() As Variant
ReDim res(UBound(a), UBound(a, 2))
For i = 1 To UBound(a)
For j = 1 To UBound(a, 2)
res(i, j) = p * a(i, j)
Next j
Next i
sq_mul = res
End Function
 
Private Function sq_sub(x As Variant, y As Variant) As Variant
Dim res() As Variant
ReDim res(UBound(x), UBound(x, 2))
For i = 1 To UBound(x)
For j = 1 To UBound(x, 2)
res(i, j) = x(i, j) - y(i, j)
Next j
Next i
sq_sub = res
End Function
 
Private Function matrix_mul(x As Variant, y As Variant) As Variant
matrix_mul = WorksheetFunction.MMult(x, y)
End Function
 
Private Function QRHouseholder(ByVal a As Variant) As Variant
Dim columns As Integer: columns = UBound(a, 2)
Dim rows As Integer: rows = UBound(a)
Dim m As Integer: m = WorksheetFunction.Max(columns, rows)
Dim n As Integer: n = WorksheetFunction.Min(rows, columns)
I_ = mat_ident(m)
Q_ = I_
Dim q As Variant
Dim u As Variant, v As Variant, j As Integer
For j = 1 To WorksheetFunction.Min(m - 1, n)
u = mat_col(a, j)
u(j) = u(j) - mat_norm(u)
v = sq_div(u, mat_norm(u))
q = sq_sub(I_, sq_mul(2, matrix_mul(vtranspose(v), v)))
a = matrix_mul(q, a)
Q_ = matrix_mul(Q_, q)
Next j
'-- Get the upper triangular matrix R.
Dim R() As Variant
ReDim R(m, n)
For i = 1 To m 'in Phix this is n
For j = 1 To n 'in Phix this is i to n. starting at 1 to fill zeroes
R(i, j) = a(i, j)
Next j
Next i
Dim res(2) As Variant
res(1) = Q_
res(2) = R
QRHouseholder = res
End Function
 
Private Sub pp(m As Variant)
For i = 1 To UBound(m)
For j = 1 To UBound(m, 2)
Debug.Print Format(m(i, j), "0.#####"),
Next j
Debug.Print
Next i
End Sub
Public Sub main()
a = [{12, -51, 4; 6, 167, -68; -4, 24, -41;-1,1,0;2,0,3}]
result = QRHouseholder(a)
q = result(1)
r_ = result(2)
Debug.Print "A"
pp a
Debug.Print "Q"
pp q
Debug.Print "R"
pp r_
Debug.Print "Q * R"
pp matrix_mul(q, r_)
End Sub</syntaxhighlight>{{out}}
<pre>A
12, -51, 4,
6, 167, -68,
-4, 24, -41,
-1, 1, 0,
2, 0, 3,
Q
0,84641 -0,39129 -0,34312 0,06641 -0,09126
0,42321 0,90409 0,02927 0,01752 -0,04856
-0,28214 0,17042 -0,93286 -0,02237 0,14365
-0,07053 0,01404 0,0011 0,99738 0,00728
0,14107 -0,01666 0,10577 0,00291 0,98419
R
14,17745 20,66663 -13,40157
0, 175,04254 -70,08031
0, 0, 35,20154
0, 0, 0,
0, 0, 0,
Q * R
12, -51, 4,
6, 167, -68,
-4, 24, -41,
-1, 1, 0,
2, 0, 3, </pre>
Least squares
<syntaxhighlight lang="vb">Public Sub least_squares()
x = [{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}]
y = [{1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321}]
Dim a() As Double
ReDim a(UBound(x), 3)
For i = 1 To UBound(x)
For j = 1 To 3
a(i, j) = x(i) ^ (j - 1)
Next j
Next i
result = QRHouseholder(a)
q = result(1)
r_ = result(2)
t = WorksheetFunction.Transpose(q)
b = matrix_mul(t, vtranspose(y))
Dim z(3) As Double
For k = 3 To 1 Step -1
Dim s As Double: s = 0
If k < 3 Then
For j = k + 1 To 3
s = s + r_(k, j) * z(j)
Next j
End If
z(k) = (b(k, 1) - s) / r_(k, k)
Next k
Debug.Print "Least-squares solution:",
For i = 1 To 3
Debug.Print Format(z(i), "0.#####"),
Next i
End Sub</syntaxhighlight>{{out}}
<pre>Least-squares solution: 1, 2, 3, </pre>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-matrix}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./matrix" for Matrix
import "./fmt" for Fmt
 
var minor = Fn.new { |x, d|
var nr = x.numRows
var nc = x.numCols
var m = Matrix.new(nr, nc)
for (i in 0...d) m[i, i] = 1
for (i in d...nr) {
for (j in d...nc) m[i, j] = x[i, j]
}
return m
}
 
var vmadd = Fn.new { |a, b, s|
var n = a.count
var c = List.filled(n, 0)
for (i in 0...n) c[i] = a[i] + s * b[i]
return c
}
 
var vmul = Fn.new { |v|
var n = v.count
var x = Matrix.new(n, n)
for (i in 0...n) {
for (j in 0...n) x[i, j] = -2 * v[i] * v[j]
}
for (i in 0...n) x[i, i] = x[i, i] + 1
return x
}
 
var vnorm = Fn.new { |x|
var n = x.count
var sum = 0
for (i in 0...n) sum = sum + x[i] * x[i]
return sum.sqrt
}
 
var vdiv = Fn.new { |x, d|
var n = x.count
var y = List.filled(n, 0)
for (i in 0...n) y[i] = x[i] / d
return y
}
 
var mcol = Fn.new { |m, c|
var n = m.numRows
var v = List.filled(n, 0)
for (i in 0...n) v[i] = m[i, c]
return v
}
 
var householder = Fn.new { |m|
var nr = m.numRows
var nc = m.numCols
var q = List.filled(nr, null)
var z = m.copy()
var k = 0
while (k < nc && k < nr-1) {
var e = List.filled(nr, 0)
z = minor.call(z, k)
var x = mcol.call(z, k)
var a = vnorm.call(x)
if (m[k, k] > 0) a = -a
for (i in 0...nr) e[i] = (i == k) ? 1 : 0
e = vmadd.call(x, e, a)
e = vdiv.call(e, vnorm.call(e))
q[k] = vmul.call(e)
z = q[k] * z
k = k + 1
}
var Q = q[0]
var R = q[0] * m
var i = 1
while (i < nc && i < nr-1) {
Q = q[i] * Q
i = i + 1
}
R = Q * m
Q = Q.transpose
return [Q, R]
}
 
var inp = [
[12, -51, 4],
[ 6, 167, -68],
[-4, 24, -41],
[-1, 1, 0],
[ 2, 0, 3]
]
var x = Matrix.new(inp)
var res = householder.call(x)
var Q = res[0]
var R = res[1]
var m = Q * R
System.print("Q:")
Fmt.mprint(Q, 8, 3)
System.print("\nR:")
Fmt.mprint(R, 8, 3)
System.print("\nQ * R:")
Fmt.mprint(m, 8, 3)</syntaxhighlight>
 
{{out}}
<pre>
Q:
| 0.846 -0.391 0.343 0.082 0.078|
| 0.423 0.904 -0.029 0.026 0.045|
| -0.282 0.170 0.933 -0.047 -0.137|
| -0.071 0.014 -0.001 0.980 -0.184|
| 0.141 -0.017 -0.106 -0.171 -0.969|
 
R:
| 14.177 20.667 -13.402|
| -0.000 175.043 -70.080|
| 0.000 0.000 -35.202|
| -0.000 -0.000 -0.000|
| 0.000 0.000 -0.000|
 
Q * R:
| 12.000 -51.000 4.000|
| 6.000 167.000 -68.000|
| -4.000 24.000 -41.000|
| -1.000 1.000 -0.000|
| 2.000 -0.000 3.000|
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">var [const] GSL=Import("zklGSL"); // libGSL (GNU Scientific Library)
A:=GSL.Matrix(3,3).set(12.0, -51.0, 4.0,
6.0, 167.0, -68.0,
Line 2,952 ⟶ 5,576:
println("Q:\n",Q.format());
println("R:\n",R.format());
println("Q*R:\n",(Q*R).format());</langsyntaxhighlight>
{{out}}
<pre>
9,482

edits