Minimizes the function of several variables by using the Nelder-Mead (Simplex) optimization method.
Minimize function of several variables by using Simplex method with lower and/or upper bounds for parameters. This version supports lower and upper bound(s) for function parameters Pars. Lower and upper bounds are defined in LB and UP arrays respectively. Depending on lower and/or upper bound for parameter, there are several possibilities for LB and UB:
Example 1
Minimize the "Banana" function, but use lower and upper limit for first parameter and only upper limit for second parameter. Uses MtxVec, Math387, Optimization;
function Banana(Pars: TVec;Const Consts : Array of TSample;
Const OConsts: Array of TObject): TSample;
begin
Result := 100*Sqr(Pars[1]-Sqr(Pars[0]))+Sqr(1-Pars[0]);
end;
procedure Example;
var stop: TOptStopReason;
fmin: TSample;
Pars: Array[0..1] of TSample;
begin
// Initial estimates for pars
Pars[0] := 0.2;
Pars[1] := 0.3;
// define lower and upper bounds
// 0<=pars[0]<=0.5
// pars[1]<=0.7
Simplex(Banana,Pars,[],[],[0,-INF],[0.5,0.7],fMin,stop);
end;
#include "MtxVecCpp.h" //MtxVecCPP.cpp must be included in the project
#include "Math387.hpp"
#include "Optimization.hpp"
double __fastcall Banana(TVec * Parameters, const double * Constants, const int Constants_Size,
System::TObject* const * ObjConst, const int ObjConst_Size)
{
double* Pars = Parameters->PValues1D(0);
return 100.0*IntPower(Pars[1]-IntPower(Pars[0],2),2)+IntPower(1.0-Pars[0],2);
}
void __fastcall Example();
{
double Pars[2];
double fmin;
TOptStopReason StopReason;
// initial estimates for x1 and x2
Pars[0] = 0;
Pars[1] = 0;
double lb[2];
doble ub[2];
// Lower and upper bounds
// 0<=x[0]<=0.5
// x[1]<=0.7
int iters = Simplex(Banana,Pars,1,NULL,-1,NULL,-1,
OPENARRAY(TSample,(0,-INF)),OPENARRAY(TSample,(0.5, 0.7)), fmin,StopReason,1000);
// stop if Iters >1000 or Tolerance < 1e-8
}
private double Banana(TVec x, double[] c, object[] o)
{
return 100*Math387.IntPower(x[1]-Math387.IntPower(x[0],2),2) + Math387.IntPower(1-x[0],2);
}
private void Example()
{
double[2] x;
double fmin;
TOptStopReason StopReason;
// initial estimates for x1 and x2
x[0] = 0;
x[1] = 0;
int iters = Simplex(Banana,x,null,null,
new double[] {0,-INF}, new double[] {0.5, 0.7},
out fmin,out StopReason,1000,1.0E-8,null);
// stop if Iters >1000 or Tolerance < 1e-8
}
Declaration
Function Simplex(Func: TRealFunction; var Pars: TSample; const Consts: array of TSample; const ObjConst: array of TObject; out FMin: TSample; out StopReason: TOptStopReason; MaxIter: Integer; Tolerance: TSample): Integer;
Declaration
Function Simplex(Func: TRealFunction; var Pars: array of TSample; const Consts: array of TSample; const ObjConst: array of TObject; out FMin: TSample; out StopReason: TOptStopReason; MaxIter: Integer = 500; Tolerance: TSample = 1.0E-8; Verbose: TStrings = nil): Integer;
the number of iterations required to reach the solution(minimum) within given tolerance.
Minimizes the function of several variables by using the Nelder-Mead (Simplex) optimization method. The advantage of Simplex method is it does not require gradient or Hessian.
Example 1
Problem: Find the minimum of the "Banana" function by using the Nelder-Mead (Simplex) method.
Solution:The Banana function is defined by the following equation:
Uses MtxVec, Math387, Optimization;
function Banana(Pars: TVec; Const Consts : Array of TSample;
Const OConsts: Array of TObject): TSample;
begin
Result := 100*Sqr(Pars[1]-Sqr(Pars[0]))+Sqr(1-Pars[0]);
end;
procedure Example;
var Iters : integer;
Pars : Array [0..1] of TSample;
StopReason : TOptStopReason;
begin
// initial estimates for x1 and x2
Pars[0] := 0;
Pars[1] := 0;
Iters := Simplex(Banana,Pars,[],[],FMin,StopReason,1000);
// stop if Iters >1000 or Tolerance < 1e-8
// Returns Pars = [1,1] and FMin = 0, meaning x1=1, x2=1 and minimum value is 0
end;
#include "MtxVecCpp.h" //MtxVecCPP.cpp must be included in the project
#include "Math387.hpp"
#include "Optimization.hpp"
double __fastcall Banana(TVec * Parameters, const double * Constants, const int Constants_Size,
System::TObject* const * ObjConst, const int ObjConst_Size)
{
double* Pars = Parameters->PValues1D(0);
return 100.0*IntPower(Pars[1]-IntPower(Pars[0],2),2)+IntPower(1.0-Pars[0],2);
}
void __fastcall Example();
{
double Pars[2];
double fmin;
TOptStopReason StopReason;
// initial estimates for x1 and x2
Pars[0] = 0;
Pars[1] = 0;
int iters = Simplex(Banana,Pars,1,NULL,-1,NULL,-1,fmin,StopReason,1000,1.0E-8,NULL);
// stop if Iters >1000 or Tolerance < 1e-8
// Returns Pars = [1,1] and FMin = 0, meaning x1=1, x2=1 and minimum value is 0
}
private double Banana(TVec x, double[] c, object[] o)
{
return 100*Math387.IntPower(x[1]-Math387.IntPower(x[0],2),2) + Math387.IntPower(1-x[0],2);
}
private void Example()
{
double[2] x;
double fmin;
TOptStopReason StopReason;
// initial estimates for x1 and x2
x[0] = 0;
x[1] = 0;
int iters = Simplex(Banana,x,null,null,out fmin,out StopReason,1000,1.0E-8,null);
// stop if Iters >1000 or Tolerance < 1e-8
// Returns x = [1,1] and FMin = 0, meaning x1=1, x2=1 and minimum value is 0
}