Nonlinear Programming
Mathwrist Code Example Series
(October 5, 2023)
Abstract
This document gives some code examples on how to use the nonlinear programming (NLP) features in Mathwrist’s C++ Numerical Programming Library (NPL).
Disk-constrained Rosenbrock
This example illustrates minimizing the Rosenbrock’s function subject to unit disk constraint using the sequential quadratic programming (SQP) solver.
1
// Objective function.
2
struct Rosenbrock : public FunctionND
3
{
4
FunctionND* clone() const { return 0; }
6
double eval(const Matrix& x, Matrix* _g=0, Matrix* _H=0) const
7
{
8
double x1 = x(0, 0);
9
double x2 = x(1, 0);
10
double temp1 = x2 - x1 * x1;
11
const double retval = 100 * temp1 * temp1 +
12
(1 - x1) * (1 - x1);
14
if (_g != 0)
15
{
16
(*_g)(0, 0) = 400 * (x1 * x1 * x1 - x1 * x2) + 2 * x1 - 2;
17
(*_g)(1, 0) = 200 * (x2 - x1 * x1);
18
}
20
if (_H != 0)
21
{
22
(*_H)(0, 0) = 1200 * x1 * x1 - 400 * x2 + 2;
23
(*_H)(0, 1) = -400 * x1;
24
(*_H)(1, 0) = -400 * x1;
25
(*_H)(1, 1) = 200;
26
}
28
return retval;
29
}
31
size_t dimension_size() const { return 2; }
32
};
34
// unit disk constraint x1^2 + x2^2 <= 1.
35
struct FDisk : public FunctionND
36
{
37
FunctionND* clone() const { return 0; }
39
double eval(const Matrix& x, Matrix* _g=0, Matrix* _H=0) const
40
{
41
double x1 = x(0, 0);
42
double x2 = x(1, 0);
43
const double retval = x1 * x1 + x2 * x2;
45
if (_g != 0)
46
{
47
(*_g)(0, 0) = 2 * x1;
48
(*_g)(1, 0) = 2 * x2;
49
}
51
if (_H != 0)
52
{
53
(*_H)(0, 0) = 2;
54
(*_H)(0, 1) = 0;
55
(*_H)(1, 0) = 0;
56
(*_H)(1, 1) = 2;
57
}
59
return retval;
60
}
62
size_t dimension_size() const { return 2; }
63
};
65
Rosenbrock rosenbrock;
67
// Nonlinear constraint functions.
68
VtrValueFunctionND_M cx(1);
69
cx[0] = FunctionND::Handle(new FDisk);
71
NonlinearProg::Problem nlp(rosenbrock, cx);
73
// Unit disk bounded below 1.
74
nlp.bounds_nonlinear[0] = Bound::upper(1);
76
// Initial guess x = 0
77
Matrix x(2, 1);
79
SQP_ActiveSet sqp(nlp);
80
sqp.set_max_iter(100);
82
sqp(x);
84
// Compare with known solution.
85
assert(std::abs(x(0, 0) - 0.786415) < 1.e-6);
86
assert(std::abs(x(1, 0) - 0.617698) < 1.e-6);