← All NMath Code Examples
using System;
using CenterSpace.NMath.Core;
namespace CenterSpace.NMath.Examples.CSharp
{
/// <summary>
/// A .NET example in C# demonstrating the features of the classes for solving ordinary least
/// squares problems.
/// </summary>
class LeastSquaresExample
{
static void Main( string[] args )
{
// A general m x n system with random entries.
var rng = new RandGenUniform( -1, 1 );
rng.Reset( 0x124 );
int rows = 20;
int cols = 4;
var A = new DoubleMatrix( rows, cols, rng );
// Construct a class to solve the least squares problem using a
// Cholesky factorization of the normal equations.
var cholLsq = new DoubleCholeskyLeastSq( A );
Console.WriteLine();
// Make sure the Cholesky factorization is good (for example, that matrix A
// has full rank).
Console.WriteLine( "Cholesky least squares is good = {0}", cholLsq.IsGood );
// Create a random right-hand side to solve for.
var b = new DoubleVector( A.Rows, rng );
// Use Cholesky least squares method to solve.
DoubleVector x = cholLsq.Solve( b );
// Look at the norm squared of the residual Ax - b.
double residualNorm = cholLsq.ResidualNormSqr( b );
Console.WriteLine( "Cholesky: residual = {0}", residualNorm ); // 5.89829729588437
Console.WriteLine();
// Solve the same system with a QR decomposition and compare the results.
var qrLsq = new DoubleQRLeastSq( A );
Console.WriteLine( "Rank of A from QR = {0}", qrLsq.Rank );
x = qrLsq.Solve( b );
residualNorm = qrLsq.ResidualNormSqr( b );
Console.WriteLine( "QR: residual = {0}", residualNorm ); // 5.89829729588437
Console.WriteLine();
// How about SVD?
var svdLsq = new DoubleSVDLeastSq( A );
Console.WriteLine( "Rank of A from SVD = {0}", svdLsq.Rank );
x = svdLsq.Solve( b );
residualNorm = svdLsq.ResidualNormSqr( b );
Console.WriteLine( "SVD: residual = {0}", residualNorm ); // 5.89829729588438
Console.WriteLine();
// All methods give about the same residual. But what if A is nearly
// rank deficient? Set the 2nd column of A to be almost equal to the 3rd.
var normalRNG = new RandGenNormal( 0, 3e-23 );
normalRNG.Reset( 0x131 );
var smallNormalDeviates = new DoubleVector( A.Rows, normalRNG );
A.Col( 1 )[Slice.All] = A.Col( 2 ) + smallNormalDeviates;
// Use Cholesky least squares method to solve ill-conditioned.
cholLsq.Factor( A );
// Depending on your hardware, A could be so close to being rank
// deficient that the Cholesky factorization fails.
if ( !cholLsq.IsGood )
{
Console.WriteLine( "Can not use Cholesky method on A. A is rank deficient." );
}
else
{
x = cholLsq.Solve( b );
residualNorm = cholLsq.ResidualNormSqr( b );
Console.WriteLine( "Cholesky ill conditioned: residual = {0}", residualNorm );
}
Console.WriteLine();
// Solve the same system with a QR decomposition and compare the results.
qrLsq.Factor( A );
Console.WriteLine( "Rank of A from QR = {0}", qrLsq.Rank );
x = qrLsq.Solve( b );
residualNorm = qrLsq.ResidualNormSqr( b );
Console.WriteLine( "QR ill conditioned: residual = {0}", residualNorm );
Console.WriteLine();
// How about SVD?
svdLsq.Factor( A );
Console.WriteLine( "Rank of A from SVD = {0}", svdLsq.Rank );
x = svdLsq.Solve( b );
residualNorm = svdLsq.ResidualNormSqr( b );
Console.WriteLine( "SVD ill conditioned: residual = {0}", residualNorm );
Console.WriteLine();
Console.WriteLine( "Press Enter Key" );
Console.Read();
}
}
}
← All NMath Code Examples