Data Analysis Mathematics Linear Algebra Statistics
New Version 8.1!

Supports .NET 6.0. Try it for free with our fully functional 60-day trial version. QuickStart Samples

# Nonlinear Programming QuickStart Sample (Visual Basic)

Illustrates solving nonlinear programs (optimization problems with linear or nonlinear constraints) using the NonlinearProgram and related classes in Visual Basic.

```Option Infer On

' The linear programming classes reside in their own namespace.
Imports Extreme.Mathematics.Optimization
' Vectors and matrices are in the Extreme.Mathematics.LinearAlgebra
' namespace
Imports Extreme.Mathematics

Namespace Extreme.Numerics.QuickStart.VB
' Illustrates solving nonlinear programming problems
' using the classes in the Extreme.Mathematics.Optimization
' namespace of the Extreme Optimization Numerical Libraries for .NET.
Module NonlinearProgramming

Sub Main()
' This QuickStart Sample illustrates the two ways to create a Nonlinear Program.

' The first is in terms of matrices. The coefficients
' are supplied as a matrix. The cost vector, right-hand side
' and constraints on the variables are supplied as a vector.

Console.WriteLine("Problem with only linear constraints:")

' The variables are the concentrations of each chemical compound:
' H, H2, H2O, N, N2, NH, NO, O, O2, OH

' The objective function is the free energy, which we want to minimize:
Dim c = Vector.Create( _
-6.089, -17.164, -34.054, -5.914, -24.721, _
-14.986, -24.1, -10.708, -26.662, -22.179)
Dim objectiveFunction As Func(Of Vector(Of Double), Double) =
Function(x) x.DotProduct(c + Vector.Log(x) - Math.Log(x.Sum()))
Dim objectiveGradient As Func(Of Vector(Of Double), Vector(Of Double), Vector(Of Double)) =
Function(x, y)
Dim s As Double = x.Sum()
Dim y1 = c + Vector.Log(x) - Math.Log(s) + 1 - x / s
y1.CopyTo(y)
Return y
End Function

' The constraints are the mass balance relationships for each element.
' The rows correspond to the elements H, N, and O.
' The columns are the index of the variable.
' The value is the number of times the element occurs in the
' compound corresponding to the variable:
' H, H2, H2O, N, N2, NH, NO, O, O2, OH
' All this is stored in a sparse matrix, so 0 values are omitted:
Dim A = Matrix.CreateSparse(3, 10, _
New Integer() {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2}, _
New Integer() {0, 1, 2, 5, 9, 3, 4, 5, 6, 2, 6, 7, 8, 9}, _
New Double() {1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1})
' The right-hand sides are the atomic weights of the elements
' in the mixture.
Dim b = Vector.Create(2.0, 1.0, 1.0)

' The number of moles for each compound must be positive.
Dim l = Vector.CreateConstant(10, 0.000001)
Dim u = Vector.CreateConstant(10, Double.PositiveInfinity)

' We create the nonlinear program with the specified constraints:
' Because we have variable bounds, we use the constructor
' that lets us do this.
Dim nlp1 As New NonlinearProgram(objectiveFunction, objectiveGradient, A, b, b, l, u)

' We could add more (linear or nonlinear) constraints here,
' but this is all we have in our problem.

nlp1.InitialGuess = Vector.CreateConstant(10, 0.1)
Dim solution = nlp1.Solve()
Console.WriteLine("Solution: {0:F3}", solution)
Console.WriteLine("Optimal value:   {0:F5}", nlp1.OptimalValue)
Console.WriteLine("# iterations: {0}", nlp1.SolutionReport.IterationsNeeded)
Console.WriteLine()

' The second method is building the nonlinear program from scratch.

Console.WriteLine("Problem with nonlinear constraints:")

' We start by creating a nonlinear program object. We supply
' the number of variables in the constructor.
Dim nlp2 As New NonlinearProgram(2)

nlp2.ObjectiveFunction = Function(x) Math.Exp(x(0)) * (4 * x(0) * x(0) + 2 * x(1) * x(1) + 4 * x(0) * x(1) + 2 * x(1) + 1)
Function(x, y)
Dim exp As Double = Math.Exp(x(0))
y(0) = exp * (4 * x(0) * x(0) + 2 * x(1) * x(1) + 4 * x(0) * x(1) + 8 * x(0) + 6 * x(1) + 1)
y(1) = exp * (4 * x(0) + 4 * x(1) + 2)
Return y
End Function

' Add constraint x0*x1 - x0 -x1 <= -1.5
nlp2.AddNonlinearConstraint(Function(x) x(0) * x(1) - x(0) - x(1) + 1.5, ConstraintType.LessThanOrEqual, 0.0,
Function(x, y)
y(0) = x(1) - 1
y(1) = x(0) - 1
Return y
End Function)

' Add constraint x0*x1 >= -10
' If the gradient is omitted, it is approximated using divided differences.
nlp2.AddNonlinearConstraint(Function(x) x(0) * x(1), ConstraintType.GreaterThanOrEqual, -10.0)

nlp2.InitialGuess = Vector.Create(-1.0, 1.0)

solution = nlp2.Solve()
Console.WriteLine("Solution: {0:F6}", solution)
Console.WriteLine("Optimal value:   {0:F6}", nlp2.OptimalValue)
Console.WriteLine("# iterations: {0}", nlp2.SolutionReport.IterationsNeeded)
#If NET40 Then
#End If

Console.Write("Press Enter key to exit...")