public Vector SolveLeastSquareQR( Vector b )
{
int l = Rows > Columns ? Columns : Rows;
//////////////////////////////////////////////////////////////////////////
// QR-decompose this = q*r
Matrix Q = new Matrix( Rows, Columns );
Matrix R = new Matrix( Columns, Columns );
// Make vectors x out of columns. Vectors g will populate q-matrix.
Vector[] x = new Vector[Columns];
Vector[] g = new Vector[Columns];
for ( int k=0; k < Columns; k++ )
{
x[k] = new Vector( Rows );
g[k] = new Vector( Rows );
for( int i=0; i < Rows; i++ )
x[k].m[i] = m[i,k];
}
// The main loop
for ( int k=0; k < Columns; k++ )
{
// Calculate r(k,k): norm of x[k]
R.m[k,k] = Math.Sqrt( x[k].Dot( x[k] ) );
if ( R.m[k,k] == 0.0 )
{
for ( int i=0; i < Rows; i++ )
g[k].m[i] = 0.0;
}
else
{ // set g-s
for ( int i=0; i < Rows; i++ )
{
double temp = 1.0 / R.m[k,k];
g[k].m[i] = x[k].m[i] * temp;
}
}
// Calculate non-diagonal elements of r-matrix
for ( int j=k+1; j < Columns; j++ )
{
R.m[j,k] = 0.0;
for ( int i=0; i < Rows; i++ )
R.m[k,j] += x[j].m[i] * g[k].m[i];
}
// Reset x-s
for ( int j=k+1; j < Columns; j++ )
for ( int i=0; i < Rows; i++ )
x[j].m[i] -= R.m[k,j] * g[k].m[i];
}
// Make q out of g-s
for( int i=0; i < Rows; i++ )
for( int k=0; k < Columns; k++ )
Q.m[i,k] = g[k].m[i];
//////////////////////////////////////////////////////////////////////////
// Solve R*x = Q.setToAdjoint()*b
Q = Q.GetTranspose();
Vector y = Q * b;
Vector Result = R.SolveBackwardSubstitution( y );
return Result;
}