Callback: ICallbackNLOptimization;
Callback: Prognoz.Platform.Interop.Stat.ICallbackNLOptimization;
The Callback property determines the custom class used to calculate values of variables, criterion function and non-linear constraints.
If the Callback property is used, and if ISmNonLinearOptimization.UseDerivatives = True, the GetObjFunPartialDeriv and GetConstraintPartialDeriv methods are used to calculate derivatives, the methods are determined in Callback, to get derivative values, function gradient is calculated.
To get value of criterion function, use the ISmNonLinearOptimization.OptimalFunctionValue property.
Add a link to the Stat system assembly.
The example uses the CallBackNLO custom class, which description is given in ICallbackNLOptimization.GetConstraintPartialDeriv.
Sub UserProc;
Var
nlo: ISmNonLinearOptimization;
lb, ub: Array[0..3] Of Double;
LinConCfs: Array[0..3] Of Double;
LinCons: ISlLinearConstraints;
LinCon: ISlLinearConstraint;
NonLinCons: INonLinearConstraints;
NonLinCon: INonLinearConstraint;
CallBack : CallBackNLO;
i, res: Integer;
lcv: Array[4] Of Double;
OptVal: Double;
Begin
nlo := New SmNonLinearOptimization.Create;
For i := 0 To 3 Do
lb[i] := 1;
ub[i] := 5;
LinConCfs[i] := 1;
End For;
// Definition area parameters:
nlo.Boundary.BoundaryLower := lb;
nlo.Boundary.BoundaryUpper := ub;
// Coefficient order:
nlo.CoefficientsOrder := "x1;x2;x3;x4";
// Linear constraint parameters:
LinCons := nlo.LinearConstraints;
LinCons.Clear;
LinCon := LinCons.Add;
LinCon.BoundaryLower := -10e20;
LinCon.BoundaryUpper := 20;
LinConCfs[0] := 1;
LinConCfs[1] := 1;
LinConCfs[2] := 1;
LinConCfs[3] := 1;
LinCon.Value := LinConCfs;
// Maximum number of iterations and precision:
nlo.MaxIteration := 75;
nlo.Tolerance := 0.001;
// Non-linear constraint parameters:
NonLinCons := nlo.NonLinearConstraints;
NonLinCons.Clear;
NonLinCon := NonLinCons.Add;
NonLinCon.BoundaryLower := -10e20;
NonLinCon.BoundaryUpper := 40;
NonLinCon := NonLinCons.Add;
NonLinCon.BoundaryLower := 25;
NonLinCon.BoundaryUpper := 10e21;
// Linear constraint parameters:
LinCon := LinCons.Add;
lcv[0] := 1; lcv[1] := 1; lcv[2] := 1; lcv[3] := 1;
LinCon.Value := lcv;
LinCon.BoundaryLower := -10;
LinCon.BoundaryUpper := 9;
// CallBack:
CallBack := New CallBackNLO.Create;
Callback.MAXCOUNT := 1000;
Callback.CallCount := 0;
nlo.Callback := CallBack;
// Task calculation:
res := nlo.Execute;
If res <> 0 Then
Debug.WriteLine(nlo.Errors);
Else
Debug.WriteLine("=== Criterion function value ===");
Debug.Indent;
OptVal := nlo.OptimalFunctionValue;
Debug.WriteLine(OptVal.ToString);
Debug.Unindent;
Debug.WriteLine("=== Solution ===");
Debug.Indent;
For i := 0 To nlo.Solution.Length - 1 Do
Debug.WriteLine(i.ToString + ", " + nlo.Solution[i].ToString)
End For;
Debug.Unindent;
Debug.WriteLine("=== Criterion function gradient ===");
Debug.Indent;
For i := 0 To nlo.FunctionGradient.Length - 1 Do
Debug.WriteLine(i.ToString + ", " + nlo.FunctionGradient[i].ToString);
End For;
Debug.Unindent;
End If;
End Sub UserProc;
Executing this example shows the calculation results in the console window:
Criterion function value.
Solution.
Criterion function gradient.
The requirements and result of the Fore.NET example execution match with those in the Fore example.
Imports Prognoz.Platform.Interop.Stat;
…
Public Shared Sub Main(Params: StartParams);
Var
nlo: ISmNonLinearOptimization;
lb, ub: Array[0..3] Of double;
LinConCfs: Array[0..3] Of double;
LinCons: ISlLinearConstraints;
LinCon: ISlLinearConstraint;
NonLinCons: INonLinearConstraints;
NonLinCon: INonLinearConstraint;
CallBack : CallBackNLO;
i, res: Integer;
lcv: Array[4] Of double;
OptVal: Double;
Solution, FuncGradient: System.Array;
opt: Array[16] Of double;
z: Array[4] Of double;
Begin
nlo := New SmNonLinearOptimization.Create();
For i := 0 To 3 Do
lb[i] := 1;
ub[i] := 5;
LinConCfs[i] := 1;
End For;
// Definition area parameters:
nlo.Boundary.BoundaryLower := lb;
nlo.Boundary.BoundaryUpper := ub;
// Coefficient order:
nlo.CoefficientsOrder := "x1;x2;x3;x4";
// Linear constraint parameters:
LinCons := nlo.LinearConstraints;
LinCons.Clear();
LinCon := LinCons.Add();
LinCon.BoundaryLower := -10e20;
LinCon.BoundaryUpper := 20;
LinConCfs[0] := 1;
LinConCfs[1] := 1;
LinConCfs[2] := 1;
LinConCfs[3] := 1;
LinCon.Value := LinConCfs;
// Maximum number of iterations and precision:
nlo.MaxIteration := 75;
nlo.Tolerance := 0.001;
// Non-linear constraint parameters:
NonLinCons := nlo.NonLinearConstraints;
NonLinCons.Clear();
NonLinCon := NonLinCons.Add();
NonLinCon.BoundaryLower := -10e20;
NonLinCon.BoundaryUpper := 40;
NonLinCon := NonLinCons.Add();
NonLinCon.BoundaryLower := 25;
NonLinCon.BoundaryUpper := 10e21;
// Linear constraint parameters:
LinCon := LinCons.Add();
lcv[0] := 1; lcv[1] := 1; lcv[2] := 1; lcv[3] := 1;
LinCon.Value := lcv;
LinCon.BoundaryLower := -10;
LinCon.BoundaryUpper := 9;
// CallBack:
CallBack := New CallBackNLO.Create();
Callback.MAXCOUNT := 100;
Callback.CallCount := 0;
Callback._options := opt;
Callback.U := z;
nlo.Callback := CallBack;
// Task calculation:
res := nlo.Execute();
If res <> 0 Then
System.Diagnostics.Debug.WriteLine(nlo.Errors);
Else
System.Diagnostics.Debug.WriteLine("=== Criterion function value ===");
System.Diagnostics.Debug.Indent();
OptVal := nlo.OptimalFunctionValue;
System.Diagnostics.Debug.WriteLine(OptVal.ToString());
System.Diagnostics.Debug.Unindent();
System.Diagnostics.Debug.WriteLine("=== Solution ===");
Solution := nlo.Solution;
System.Diagnostics.Debug.Indent();
For i := 0 To nlo.Solution.Length - 1 Do
System.Diagnostics.Debug.WriteLine(i.ToString() + ", " + Solution[i].ToString())
End For;
System.Diagnostics.Debug.Unindent();
System.Diagnostics.Debug.WriteLine("=== Criterion function gradient ===");
FuncGradient := nlo.FunctionGradient;
System.Diagnostics.Debug.Indent();
For i := 0 To nlo.FunctionGradient.Length - 1 Do
System.Diagnostics.Debug.WriteLine(i.ToString() + ", " + FuncGradient[i].ToString());
End For;
System.Diagnostics.Debug.Unindent();
End If;
End Sub;
See also: