120 行
4.1 KiB
MQL5
120 行
4.1 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| slsqp_optimization_with_numerical_gradients.mq5 |
|
|
//| Copyright 2025, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
#include<slsqp_article\slsqp.mqh>
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
//---objective function object
|
|
CObjectiveFunc obj_func;
|
|
//---inequality constraints function object
|
|
CIneqConstraints ineq_func;
|
|
//---equality constraints function object
|
|
CEqConstraints eq_func;
|
|
//---the initial guess
|
|
vector initp = {2, 0};
|
|
//---gradient configuration instance
|
|
GradDiffOptions obj_options;
|
|
//---configure upper and lower limits
|
|
obj_options.bounds = matrix::Zeros(2,2);
|
|
obj_options.bounds[0,1] = 10.;
|
|
obj_options.bounds[1,1] = 10.;
|
|
//---set gradient calculation method
|
|
obj_options.method = GRAD_POINT_2;
|
|
//---set gradient options for objective function and constraints
|
|
obj_func.setParams(obj_options);
|
|
ineq_func.setParams(1,2,obj_options);
|
|
eq_func.setParams(1,2,obj_options);
|
|
//---initialize and verify configuration of all function objects
|
|
if(!obj_func.initialize(initp) || !ineq_func.initialize(initp) || !eq_func.initialize(initp))
|
|
return;
|
|
//---the minimizer instance
|
|
CSlsqp slsqp_minim;
|
|
//---configure the minimizer
|
|
slsqp_minim.SetInequalityConstraints(ineq_func);
|
|
slsqp_minim.SetEqualityConstraints(eq_func);
|
|
//---run the optimizer
|
|
OptimizeResult ro = slsqp_minim.Minimize(obj_func);
|
|
//---check return code
|
|
Print("Minimization return code : ", ro.return_code);
|
|
//---print results
|
|
if(ro.return_code>0)
|
|
{
|
|
Print("Solution ", ro.solution);
|
|
Print("Minimum value of function ", ro.objective_result);
|
|
Print("Gradient at the minimum ", ro.objective_gradient);
|
|
Print("Number of iterations ", ro.niter);
|
|
Print("Number of function evaluations ", ro.nfeval);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| objective function |
|
|
//+------------------------------------------------------------------+
|
|
class CObjectiveFunc:public CFunctor
|
|
{
|
|
protected:
|
|
vector obj_gradient;
|
|
public:
|
|
CObjectiveFunc(void)
|
|
{
|
|
m_clip = true;
|
|
obj_gradient = vector::Zeros(2);
|
|
}
|
|
~CObjectiveFunc(void)
|
|
{
|
|
}
|
|
virtual double orig_fun(vector& x) override
|
|
{
|
|
return pow((x[0] - 1),2) + pow((x[1] - 2.5),2);
|
|
}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| inequality constraints |
|
|
//+------------------------------------------------------------------+
|
|
class CIneqConstraints: public CConstraints
|
|
{
|
|
private:
|
|
vector obj_result;
|
|
public:
|
|
CIneqConstraints(void)
|
|
{
|
|
obj_result = vector::Zeros(1);
|
|
}
|
|
~CIneqConstraints(void)
|
|
{
|
|
}
|
|
virtual vector orig_fun(vector& x) override
|
|
{
|
|
obj_result[0] = pow(x[0],2) - x[1];
|
|
return obj_result;
|
|
}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| equality constraints |
|
|
//+------------------------------------------------------------------+
|
|
class CEqConstraints: public CConstraints
|
|
{
|
|
private:
|
|
vector obj_result;
|
|
public:
|
|
CEqConstraints(void)
|
|
{
|
|
obj_result = vector::Zeros(1);
|
|
}
|
|
~CEqConstraints(void)
|
|
{
|
|
}
|
|
virtual vector orig_fun(vector& x) override
|
|
{
|
|
obj_result[0] = x[0] - x[1] + 2;
|
|
return obj_result;
|
|
}
|
|
};
|
|
//+------------------------------------------------------------------+
|