← All NMath Code Examples
using System;
using CenterSpace.NMath.Core;
namespace CenterSpace.NMath.Examples.CSharp
{
/// <summary>
/// A .NET example in C# showing how to use ConstrainedLeastSquares class to
/// solve the constrained least squares problem
/// Cx = d, subject to the constraints
/// Ax < b
/// </summary>
public class ConstrainedLeastSquaresExample
{
static void Main( string[] args )
{
// Solve, in the least squares sense, Cx = d, subect to Ax <= b
// and -0.1 <= x[i] <= 2.0
var C = new DoubleMatrix( "5x4 [0.9501 0.7620 0.6153 0.4057 " +
"0.2311 0.4564 0.7919 0.9354 " +
"0.6068 0.0185 0.9218 0.9169 " +
"0.4859 0.8214 0.7382 0.4102 " +
"0.8912 0.4447 0.1762 0.8936]" );
var d = new DoubleVector( 0.0578, 0.3528, 0.8131, 0.0098, 0.1388 );
// Constraint coefficient matrix
var A = new DoubleMatrix( "3x4[0.2027 0.2721 0.7467 0.4659 " +
"0.1987 0.1988 0.4450 0.4186 " +
"0.6037 0.0152 0.9318 0.8462]" );
// Constraints right hand sides.
var b = new DoubleVector( 0.5251, 0.2026, 0.6721 );
// Create the constrained least squares problem for minimizing
// || Cx - d||^2 subject to Ax <= b and -0.1 <= x[i] <= 2.0
// We first construct the problem object from the matrix C and the
// vector d, we then add the constraints.
var problem = new ConstrainedLeastSquaresProblem( C, d );
// Add the inequality constraints Ax <= b using a constraint tolerance
// of 0.00001. This allows for small violations of the constraints.
// Specifically the constraints will be considered satisfied for a
// vector x if
// Ax <= b + 0.00001
double constraintTolerance = 0.00001;
for ( int i = 0; i < A.Rows; i++ )
{
problem.AddUpperBoundConstraint( A.Row( i ), b[i], constraintTolerance );
}
// All variable values for the solution must satisfy the bounds
// -0.1 <= x[i] <= 2.0
var lb = new DoubleVector( problem.NumVariables, -0.10 );
var ub = new DoubleVector( problem.NumVariables, 2.0 );
for ( int i = 0; i < problem.NumVariables; i++ )
{
problem.AddBounds( i, lb[i], ub[i], .00001 );
}
// Create the solver instance.
var solver = new ConstrainedLeastSquares();
// The ConstrainedLeastSquares solver uses a QP (Quadratic Programming) solver
// to solve the constrained least squares problem.
// The current default QP solver is the NMath active set quadratic programming
// solver with default options.
bool success = solver.Solve( problem );
Console.WriteLine( "Default solver success = " + success );
Console.WriteLine( "Default solver solution x = " + solver.X.ToString( "0.0000" ) );
Console.WriteLine( "Default solver residual norm = " + solver.ResidualNorm.ToString( "0.0000" ) );
Console.WriteLine( "Default solver performed {0} iterations", solver.Iterations );
// You can pass in an instance of a quadratic programming solver for the
// constrained least squares class to use. This allows you to set
// option on the QP solver and inspect results of the QP
// solver.
var interiorPointQp = new InteriorPointQPSolver();
var solverParams = new InteriorPointQPSolverParams
{
MaxIterations = 10000,
PresolveLevel = InteriorPointQPSolverParams.PresolveLevelOption.None
};
solver.Solve( problem, interiorPointQp, solverParams );
Console.WriteLine( "\nInterior point solver success = " + success );
Console.WriteLine( "Interior point QP result = " + interiorPointQp.Result );
Console.WriteLine( "Interior point QP solver iteration count = " + solver.Iterations );
Console.WriteLine( "Interior point solver solution x = " + solver.X.ToString( "0.0000" ) );
Console.WriteLine( "Interior point solver residual norm = " + solver.ResidualNorm.ToString( "0.0000" ) );
// If you use the active set QP solver you can determine which constraints
// are active in the solution by accessing the active set QP solvers
// Lagrange multiplier property. A constraint is active if its corresponding
// Lagrange multiplier is non-zero.
var activeSetQP = new ActiveSetQPSolver();
success = solver.Solve( problem, activeSetQP );
Console.WriteLine( "\nActive set solver success = " + success );
Console.WriteLine( "Active set solver solution x = " + solver.X.ToString( "0.0000" ) );
Console.WriteLine( "Active set solver residual norm = " + solver.ResidualNorm.ToString( "0.0000" ) );
// Print out the active constraints.
for ( int i = 0; i < activeSetQP.LagrangeMultiplier.Length; i++ )
{
if ( activeSetQP.LagrangeMultiplier[i] != 0.0 )
{
Console.WriteLine( "Constraint {0} = {1} is active", i, problem.Constraints[i].ToString() );
}
}
Console.WriteLine();
Console.WriteLine( "Press Enter Key" );
Console.Read();
}
}
}
← All NMath Code Examples