**22.1****
****QR Decompositions** (.NET, C#, CSharp, VB, Visual Basic, F#)

A QR decomposition is a representation of a matrix A of the form:

where P is a permutation matrix, Q is orthogonal, and R is upper trapezoidal (or upper triangular if A has more rows than columns and full rank).

**NMath**
provides QR decomposition classes for four
datatypes: single- and double-precision floating point numbers, and single-
and double-precision complex numbers. The classnames are **FloatQRDecomp**,
**DoubleQRDecomp**,
**FloatComplexQRDecomp**,
and **DoubleComplexQRDecomp**.

Instances of the QR decomposition classes are constructed
from general matrices of the appropriate datatype. For example, this
code creates a **FloatQRDecomp** from
a **FloatMatrix**:

Code Example – C# QR decomposition

var A =

new FloatMatrix( "5x3 [ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 ]" );

var qr = new FloatQRDecomp( A );

Code Example – VB QR decomposition

Dim A As New FloatMatrix(

"5x3 [ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 ]")

Dim QR As New FloatQRDecomp(A)

By default, pivoting is done so that the entries
along the diagonal of R are non-increasing.
For greater control, **NMath**
provides QR decomposition server classes
that create QR decomposition objects with non-default decomposition parameters.
The classnames are **FloatQRDecompServer**,
**DoubleQRDecompServer**,
**FloatComplexQRDecompServer**,
and **DoubleComplexQRDecompServer**.

The QR decomposition server classes all have the same interface:

● The Pivoting property sets whether or not pivoting is performed. By default, pivoting is true.

● The SetInitialColumn() method moves a given column to the beginning of AP before the computation, and fixes it in place during the computation.

● The SetFreeColumn() method allows a given column to be interchanged during the computation with any other free column. By default, all columns are free.

● The GetDecomp() method takes a matrix and returns a decomposition object using the current pivoting parameters.

For example, this code uses a **DoubleComplexQRDecompServer**
to turn off pivoting:

Code Example – C# QR decomposition

var qrs = new DoubleComplexQRDecompServer();

qrs.Pivoting = false;

int rows = 10, cols = 3;

var A = new DoubleComplexMatrix( rows, cols,

new RandGenUniform( -1, 1 ) );

DoubleComplexQRDecomp qr = qrs.GetDecomp( A );

Code Example – VB QR decomposition

Dim QRS As New DoubleComplexQRDecompServer()

QRS.Pivoting = False

Dim Rows As Integer = 10

Dim Cols As Integer = 3

Dim A As New DoubleComplexMatrix(Rows, Cols,

New RandGenUniform(-1.0, 1.0))

Dim QR As DoubleComplexQRDecomp = QRS.GetDecomp(A)

This code moves column 7 to the beginning of AP before the computation, and fixes it in place during the computation:

Code Example – C# QR decomposition

var qrs = new DoubleQRDecompServer();

qrs.SetIntialColumn( 7 );

int rows = 20, cols = 12;

var A = new DoubleMatrix( rows, cols,

new RandGenUniform(-1,1) );

DoubleQRDecomp qr = qrs.GetDecomp( A );

Code Example – VB QR decomposition

Dim QRS As New DoubleQRDecompServer()

QRS.SetIntialColumn(7)

Dim Rows As Integer = 20

Dim Cols As Integer = 12

Dim A As New DoubleMatrix(Rows, Cols,

New RandGenUniform(-1.0, 1.0))

Dim QR As DoubleQRDecomp = QRS.GetDecomp(A)

Once a QR decomposition object has been constructed from a matrix, various read-only properties are provided for retrieving the elements of the decomposition, and for retrieving information about the original matrix:

● P gets the permutation matrix.

● Q gets the orthogonal matrix.

● R gets the upper trapezoidal matrix.

● Rows gets the number of rows in the original matrix A.

● Cols gets the number of columns in the original matrix A.

For example:

Code Example – C# QR decomposition

int rows = 10, cols = 3;

DoubleMatrix A =

new DoubleMatrix( rows, cols, new RanGenUniform( 1, -1 ) );

var qr = new DoubleQRDecomp( A );

DoubleMatrix Q = qr.Q;

DoubleMatrix R = qr.R;

DoubleMatrix P = qr.P;

Code Example – VB QR decomposition

Dim Rows As Integer = 10

Dim Cols As Integer = 3

Dim A As New DoubleMatrix(Rows, Cols,

New RandGenUniform(-1.0, 1.0))

Dim QR As New DoubleQRDecomp(A)

Dim Q As DoubleMatrix = QR.Q

Dim R As DoubleMatrix = QR.R

Dim P As DoubleMatrix = QR.P

Methods are also provided for manipulating the component matrices P, Q, or R:

● Px(), Qx(), and Rx() compute the inner product of a component matrix and a given vector.

● PTx(), QTx(), and RTx() compute the inner product of the transpose of a component matrix and a given vector, or conjugate transpose for complex types.

● QM() computes the inner product of the orthogonal matrix Q and a given matrix. QTM() uses the transpose of Q, or conjugate transpose for complex types.

● RInvx() computes the inner product of the inverse of the the upper trapezoidal matrix R and a given vector. RTInvx() uses the transpose of R, or conjugate transpose for complex types.

● RDiagonal() returns the main diagonal of the upper trapezoidal matrix R.

These methods are more efficient than retrieving a component matrix using the P, Q, and R properties and manipulating it yourself.

For example:

Code Example – C# QR decomposition

int rows = 12, cols = 20;

var A = new FloatComplexMatrix( rows, cols, rng );

var qr = new FloatComplexQRDecomp( A );

var x = new FloatComplexVector( qr.P.Cols, 1, 1 );

FloatComplexVector y = qr.Px( x );

Code Example – VB QR decomposition

Dim Rows As Integer = 12

Dim Cols As Integer = 20

Dim A As New FloatComplexMatrix(Rows, Cols, rng)

Dim QR As New FloatComplexQRDecomp(A)

Dim X As New FloatComplexVector(QR.P.Cols, 1, 1)

Dim Y As FloatComplexVector = QR.Px(X)

An existing decomposition object can be reused with another matrix using the Factor() method:

Code Example – C# QR decomposition

int rows = 10, cols = 3;

var rng = new RandGenUniform( -1, 1 );

var A = new FloatMatrix( rows, cols, rng );

var qr = new FloatQRDecomp( A );

FloatMatrix Q1 = qr.Q;

FloatMatrix R1 = qr.R;

FloatMatrix P1 = qr.P;

rows = 7;

cols = 7;

var B = new FloatMatrix( rows, cols, rng );

qr.Factor( B );

FloatMatrix Q2 = qr.Q;

FloatMatrix R2 = qr.R;

FloatMatrix P2 = qr.P;

Code Example – VB QR decomposition

Dim Rows As Integer = 10

Dim Cols As Integer = 3

Dim RNG As New RandGenUniform(-1.0, 1.0)

Dim A As New FloatMatrix(Rows, Cols, RNG)

Dim QR As New FloatQRDecomp(A)

Dim Q1 As FloatMatrix = QR.Q

Dim R1 As FloatMatrix = QR.R

Dim P1 As FloatMatrix = QR.P

Rows = 7

Cols = 7

Dim B As New FloatMatrix(Rows, Cols, RNG)

QR.Factor(B)

Dim Q2 As FloatMatrix = QR.Q

Dim R2 As FloatMatrix = QR.R

Dim P2 As FloatMatrix = QR.P