CONOPT
Loading...
Searching...
No Matches
qp4.cpp
Go to the documentation of this file.
1
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <math.h>
11#include <string.h>
12#include <iostream>
13#include "conopt.hpp"
14
15/* QP Model: Min (x-target)*Q*(x-target)/2 s.t.
16 sum( x ) = 1;
17 where x is a vector of non-negative variables of length nvar
18 target is a vector of +10, and
19 Q is a matrix with +1 on the diagonal and 0.1 on the
20 first upper and lower bi-diagonal */
21
23{
24public:
25 std::vector<double> Q; // Q matrix values (diagonal and off-diagonal)
26 std::vector<int> Qrow; // Row indices of Q matrix
27 std::vector<int> Qcol; // Column indices of Q matrix
28 std::vector<double> Target; // Target vector
29 int nvar;
30 int nqnz;
31
39 QP4_ModelData(int numvar) : nvar(numvar), nqnz(2 * numvar - 1)
40 {
41 Q.resize(nqnz);
42 Qrow.resize(nqnz);
43 Qcol.resize(nqnz);
44 Target.resize(nvar, 10.0); // all targets set to 10.0
45
46 int j = 0;
47 for (int i = 0; i < nvar; ++i)
48 {
49 Q[j] = 1.0;
50 Qrow[j] = i;
51 Qcol[j] = i;
52 ++j;
53
54 if (i < nvar - 1)
55 {
56 Q[j] = 0.1;
57 Qrow[j] = i + 1;
58 Qcol[j] = i;
59 ++j;
60 }
61 }
62 }
63
68 {
69 /* */
70 /* Information about Variables: */
71 /* Default: Lower = -Inf, Curr = 0, and Upper = +inf. */
72 /* Default: the status information in Vsta is not used. */
73 /* */
74 /* Lower bound = 0 on all variables: */
75 /* */
76 for (int i = 0; i < nvar; ++i)
77 addVariable(0.0, Conopt::Infinity); // lower = 0, upper = +∞
78
79 /* Build common index/coeff lists */
80 std::vector<int> varIdx(nvar);
81 std::vector<double> ones(nvar, 1.0); // coefficients
82 std::vector<int> nlflags_free(nvar, 1); // nonlinear for objective
83 std::vector<int> nlflags_sum(nvar, 0); // linear for sum-to-one constraint
84
85 for (int i = 0; i < nvar; ++i)
86 varIdx[i] = i;
87
88 /* */
89 /* Constraint 0: Objective */
90 /* Rhs = 0 and type Non binding */
91 /* */
92 addConstraint(ConoptConstraintType::Free, 0.0, varIdx, ones, nlflags_free);
93
94 /* */
95 /* Constraint 1: Objective */
96 /* Rhs = 1 and type Equality */
97 /* */
98 addConstraint(ConoptConstraintType::Eq, 1.0, varIdx, ones, nlflags_sum);
99
100 /* setting the objective constraint */
102
103 /* setting the optimisation direction */
105
106 /* setting the structure of the hessian */
108 }
109
114 int FDEval(const double x[], double *g, double jac[], int rowno, const int jacnum[], int mode,
115 int ignerr, int *errcnt, int numvar, int numjac, int thread) override
116 {
117 if (rowno == 0)
118 {
119 // Mode 1 or 3: Evaluate function value
120 if (mode == 1 || mode == 3)
121 {
122 double sum = 0.0;
123 for (int k = 0; k < nqnz; ++k)
124 {
125 int i = Qrow[k], j = Qcol[k];
126 double qi = Q[k];
127 if (i == j)
128 sum += (x[i] - Target[i]) * qi * (x[i] - Target[i]);
129 else
130 sum += 2.0 * (x[i] - Target[i]) * qi * (x[j] - Target[j]);
131 }
132 *g = sum / 2.0;
133 }
134
135 // Mode 2 or 3: Evaluate gradient
136 if (mode == 2 || mode == 3)
137 {
138 for (int i = 0; i < numvar; ++i)
139 jac[i] = 0.0;
140
141 for (int k = 0; k < nqnz; ++k)
142 {
143 int i = Qrow[k], j = Qcol[k];
144 double qi = Q[k];
145 if (i == j)
146 jac[i] += qi * (x[i] - Target[i]);
147 else
148 {
149 jac[i] += qi * (x[j] - Target[j]);
150 jac[j] += qi * (x[i] - Target[i]);
151 }
152 }
153 }
154 }
155
156 return 0;
157 }
158
163 int SDDir(const double x[], const double dx[], double d2g[], int rowno, const int jacnum[],
164 int *nodrv, int numvar, int numjac, int thread) override
165 {
166 int i, j, k;
167 /* */
168 /* Is only called for rowno = 0, the nonlinear objective */
169 /* Return H*Dx = Q*Dx in d2g */
170 /* */
171 if (rowno == 0)
172 {
173 for (i = 0; i < numvar; i++)
174 d2g[i] = 0.0;
175 for (k = 0; k < nqnz; k++)
176 {
177 i = Qrow[k];
178 j = Qcol[k];
179 if (i == j)
180 d2g[i] += Q[k] * dx[i];
181 else
182 {
183 d2g[i] += Q[k] * dx[j];
184 d2g[j] += Q[k] * dx[i];
185 }
186 }
187 }
188 return 0;
189 }
190
195 int SDLagrVal(const double x[], const double u[], const int hsrw[], const int hscl[],
196 double hsvl[], int *nodrv, int numvar, int numcon, int nhess) override
197 {
198 int k;
199
200 for (k = 0; k < nqnz; k++)
201 hsvl[k] = Q[k] * u[0];
202 return 0;
203 }
204};
205
206#include "std.cpp"
207
211int main(int argc, char **argv)
212{
213 int COI_Error = 0;
214
215 // the number of variables in the problem
216 int numvar = 1000;
217
218 // getting the program name from the executable path
219 std::string pname = getProgramName(argv[0]);
220
221 // initialising the Conopt Object
223 QP4_ModelData modeldata(numvar);
224 Tut_MessageHandler msghandler(pname);
225
226 // adding the message handler to the conopt interface
227 conopt.setMessageHandler(msghandler);
228
229 // building the model
230 modeldata.buildModel();
231
232 // loading the model in the conopt object
233 conopt.loadModel(modeldata);
234
235#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && defined(CONOPT_LICENSE_TEXT)
236 std::string license = CONOPT_LICENSE_TEXT;
237 COI_Error += conopt.setLicense(CONOPT_LICENSE_INT_1, CONOPT_LICENSE_INT_2, CONOPT_LICENSE_INT_3, license);
238#endif
239
240 if (COI_Error)
241 {
242 conopt.sendMessage(
243 "Skipping COI_Solve due to setup errors. COI_Error = " + std::to_string(COI_Error));
244 cpp_log(conopt, "Skipping Solve due to setup errors", COI_Error);
245 }
246
247 COI_Error = conopt.solve(); /* Optimize */
248
249 conopt.sendMessage("After solving. COI_Error = " + std::to_string(COI_Error));
250 if (conopt.modelStatus() != 2 || conopt.solutionStatus() != 1)
251 cpp_log(conopt, "Incorrect Model or Solver Status", -1);
252 else if (fabs(conopt.objectiveValue() - 59978.0) > 0.001)
253 cpp_log(conopt, "Incorrect objective returned", -1);
254
255 conopt.printStatus();
256
257 cpp_log(conopt, "Successful Solve", COI_Error);
258}
The Conopt class.
Definition conopt.hpp:27
static constexpr double Infinity
Definition conopt.hpp:30
std::vector< int > Qcol
Definition qp4.cpp:27
std::vector< double > Q
Definition qp4.cpp:25
std::vector< int > Qrow
Definition qp4.cpp:26
std::vector< double > Target
Definition qp4.cpp:28
char pname[MAXLINE]
Definition comdecl.h:10
int COI_Error
Definition comdecl.h:15
CONOPT C++ interface header file. This is the main object for the CONOPT C++ interface.
int main(int argc, char **argv)
Main program. A simple setup and call of CONOPT.
Definition qp4.cpp:211
int SDLagrVal(const double x[], const double u[], const int hsrw[], const int hscl[], double hsvl[], int *nodrv, int numvar, int numcon, int nhess) override
Computes and returns the numerical values of the Hessian.
Definition qp4.cpp:195
void buildModel()
adds the variables and constraints for the problem
Definition qp4.cpp:67
int FDEval(const double x[], double *g, double jac[], int rowno, const int jacnum[], int mode, int ignerr, int *errcnt, int numvar, int numjac, int thread) override
defines the nonlinearities of the model by returning numerical values.
Definition qp4.cpp:114
int SDDir(const double x[], const double dx[], double d2g[], int rowno, const int jacnum[], int *nodrv, int numvar, int numjac, int thread) override
computes the directional second derivative for a single constraint
Definition qp4.cpp:163
QP4_ModelData(int numvar)
the constructor for the QP instance model data.
Definition qp4.cpp:39
int addVariable(double lower, double upper, double curr=0, int varstatus=-1)
adds a variable to the model. The non-zero coefficients are added later.
void setObjectiveElement(ConoptObjectiveElement elem, int elemindex)
sets the index for the objective variable or constraint
int addConstraint(ConoptConstraintType constype, double rhs, int slackstatus=-1)
adds a constraint to the problem. The non-zero coefficients are added later
void setOptimizationSense(ConoptSense sense)
sets the optimisation direction.
void setSDLagrangianStructure(const std::vector< int > &rownum, const std::vector< int > &colnum)
sets the structure of the second derivatives of the Lagrangian
void cpp_log(Conopt &conopt, std::string msg, int code)
Definition std.cpp:111
std::string getProgramName(char *execname)
Definition std.cpp:95