15 using namespace Eigen;
29 MatrixXd_sparse &dConstrAct_sparse, MatrixXd_sparse &HConstrAct_sparse,
30 MatrixXd_sparse &HObjAct_sparse, RowVectorXd &dObjAct, VectorXd &constrAct,
33 int ii, jj, nDvAct, nConstrAct;
35 this->subDvAct.reserve(nDv);
36 this->subDvAct.clear();
38 for (ii = 0; ii < nDv; ++ii)
40 nDvAct += int(isDvAct.at(ii));
43 this->subDvAct.push_back(ii);
47 this->subConstrAct.reserve(nConstr);
48 this->subConstrAct.clear();
50 for (ii = 0; ii < nConstr; ++ii)
52 nConstrAct += int(isConstrAct.at(ii));
53 if (isConstrAct.at(ii))
55 this->subConstrAct.push_back(ii);
59 dObjAct.setZero(nDvAct);
60 for (jj = 0; jj < nDvAct; ++jj)
62 dObjAct[jj] = dObj[this->subDvAct[jj]];
64 constrAct.setZero(nConstrAct);
65 for (jj = 0; jj < nConstrAct; ++jj)
67 constrAct[jj] = (constr[this->subConstrAct[jj]] - constrTarg[this->subConstrAct[jj]]);
69 lagMultAct.setZero(nConstrAct);
71 this->subConstrAct.GenerateHash();
72 this->subDvAct.GenerateHash();
74 if (this->UseFullMath())
77 this->PrepareMatricesForSQPFull(dConstrAct, HConstrAct, HObjAct);
81 this->PrepareMatricesForSQPSparse(dConstrAct_sparse, HConstrAct_sparse, HObjAct_sparse);
87 void RSVScalc::PrepareMatricesForSQPFull(Eigen::MatrixXd &dConstrAct, Eigen::MatrixXd &HConstrAct,
88 Eigen::MatrixXd &HObjAct)
91 int nConstrAct = this->subConstrAct.size();
92 int nDvAct = this->subDvAct.size();
94 dConstrAct.setZero(nConstrAct, nDvAct);
95 for (ii = 0; ii < nConstrAct; ++ii)
97 for (jj = 0; jj < nDvAct; ++jj)
99 dConstrAct(ii, jj) = dConstr(this->subConstrAct[ii], this->subDvAct[jj])
104 HConstrAct.setZero(nDvAct, nDvAct);
105 for (ii = 0; ii < nDvAct; ++ii)
107 for (jj = 0; jj < nDvAct; ++jj)
109 HConstrAct(ii, jj) = HConstr(this->subDvAct[ii], this->subDvAct[jj]);
112 HObjAct.setZero(nDvAct, nDvAct);
113 for (ii = 0; ii < nDvAct; ++ii)
115 for (jj = 0; jj < nDvAct; ++jj)
117 HObjAct(ii, jj) = HObj(this->subDvAct[ii], this->subDvAct[jj]);
121 this->dLag = this->dObj + this->lagMult.transpose() * this->dConstr;
122 this->HLag = HObjAct + HConstrAct;
124 void RSVScalc::PrepareMatricesForSQPSparse(MatrixXd_sparse &dConstrAct_sparse, MatrixXd_sparse &HConstrAct_sparse,
125 MatrixXd_sparse &HObjAct_sparse)
128 int nConstrAct = this->subConstrAct.size();
129 int nDvAct = this->subDvAct.size();
131 dConstrAct_sparse.resize(nConstrAct, nDvAct);
132 count = this->dConstr_sparse.nonZeros();
133 dConstrAct_sparse.reserve(count);
134 for (
int k = 0; k < count; ++k)
136 auto it = dConstr_sparse[k];
137 if (isConstrAct[it.row()] && isDvAct[it.col()])
139 ii = subConstrAct.find(it.row());
140 jj = subDvAct.find(it.col());
141 if (ii == rsvs3d::constants::__notfound || jj == rsvs3d::constants::__notfound)
143 std::cerr << std::endl
144 <<
"rows " << it.row() <<
", cols " << it.col() <<
", value " << it.value() << std::endl;
148 dConstrAct_sparse.insert(ii, jj) = it.value();
152 HConstrAct_sparse.resize(nDvAct, nDvAct);
153 count = this->HConstr_sparse.nonZeros();
154 HConstrAct_sparse.reserve(count);
155 for (
int k = 0; k < count; ++k)
157 auto it = HConstr_sparse[k];
158 if (isDvAct[it.row()] && isDvAct[it.col()])
160 ii = subDvAct.find(it.row());
161 jj = subDvAct.find(it.col());
162 HConstrAct_sparse.insert(ii, jj) = it.value();
166 HObjAct_sparse.resize(nDvAct, nDvAct);
167 count = this->HObj_sparse.nonZeros();
168 HObjAct_sparse.reserve(count);
169 for (
int k = 0; k < count; ++k)
171 auto it = HObj_sparse[k];
172 if (isDvAct[it.row()] && isDvAct[it.col()])
174 ii = subDvAct.find(it.row());
175 jj = subDvAct.find(it.col());
176 HObjAct_sparse.insert(ii, jj) = it.value();
179 this->dConstr_sparse.SetEqual(this->dConstr);
180 this->dLag = this->dObj + this->lagMult.transpose() * this->dConstr;
181 this->HLag_sparse = HObjAct_sparse + HConstrAct_sparse;
185 const MatrixXd &HObjAct, MatrixXd &sensMult, MatrixXd &sensInv,
186 MatrixXd &sensRes)
const
188 int nDvAct, nConstrAct;
191 nDvAct = this->subDvAct.size();
192 nConstrAct = this->subConstrAct.size();
197 sensInv.resize(nDvAct + nConstrAct, nDvAct + nConstrAct);
198 sensMult.resize(nDvAct + nConstrAct, nConstrAct);
199 sensRes.resize(nDvAct + nConstrAct, nConstrAct);
201 sensInv << HConstrAct + HObjAct, dConstrAct.transpose(), dConstrAct, MatrixXd::Zero(nConstrAct, nConstrAct);
204 for (
int i = 0; i < nConstrAct; ++i)
206 sensMult(nDvAct + i, i) = this->lagMult[this->subConstrAct[i]];
212 return (nDvAct > 0 && nConstrAct > 0);
216 MatrixXd_sparse &HObjAct, Eigen::MatrixXd &sensMult,
217 MatrixXd_sparse &sensInv, Eigen::MatrixXd &sensRes)
const
219 int nDvAct, nConstrAct;
222 nDvAct = this->subDvAct.size();
223 nConstrAct = this->subConstrAct.size();
228 sensInv.resize(nDvAct + nConstrAct, nDvAct + nConstrAct);
229 sensMult.resize(nDvAct + nConstrAct, nConstrAct);
230 sensRes.resize(nDvAct + nConstrAct, nConstrAct);
233 HObjAct = HConstrAct + HObjAct;
234 MatrixXd_sparse &HlagAct = HObjAct;
235 sensInv.reserve(HlagAct.nonZeros() + 2 * dConstrAct.nonZeros());
236 for (
int k = 0; k < HlagAct.outerSize(); ++k)
238 for (SparseMatrix<double>::InnerIterator it(HlagAct, k); it; ++it)
240 sensInv.insert(it.row(), it.col()) = it.value();
243 for (
int k = 0; k < dConstrAct.outerSize(); ++k)
245 for (SparseMatrix<double>::InnerIterator it(dConstrAct, k); it; ++it)
247 sensInv.insert(it.col(), it.row() + nDvAct) = it.value();
248 sensInv.insert(it.row() + nDvAct, it.col()) = it.value();
253 for (
int i = 0; i < nConstrAct; ++i)
255 sensMult(nDvAct + i, i) = this->lagMult[this->subConstrAct[i]];
261 return (nDvAct > 0 && nConstrAct > 0);
268 MatrixXd dConstrAct, HConstrAct, HObjAct;
269 MatrixXd_sparse dConstrAct_sparse, HConstrAct_sparse, HObjAct_sparse;
271 VectorXd constrAct, lagMultAct, deltaDVAct;
273 computeFlag = this->PrepareMatricesForSQP(dConstrAct, HConstrAct, HObjAct, dConstrAct_sparse, HConstrAct_sparse,
274 HObjAct_sparse, dObjAct, constrAct, lagMultAct);
278 if (this->UseFullMath())
280 this->ComputeSQPstep(calcMethod, dConstrAct, dObjAct, constrAct, lagMultAct);
284 this->ComputeSQPstep(calcMethod, dConstrAct_sparse, dObjAct, constrAct, lagMultAct);
289 for (ii = 0; ii < nDv; ++ii)
296 if (this->UseFullMath())
298 MatrixXd sensMult, sensInv, sensRes;
300 this->PrepareMatricesForSQPSensitivity(dConstrAct, HConstrAct, HObjAct, sensMult, sensInv, sensRes);
303 this->ComputeSQPsens(calcMethod, sensMult, sensInv, sensRes);
308 MatrixXd_sparse sensInv;
309 MatrixXd sensRes, sensMult;
310 bool computeSens = this->PrepareMatricesForSQPSensitivity(dConstrAct_sparse, HConstrAct_sparse,
311 HObjAct_sparse, sensMult, sensInv, sensRes);
314 sensInv.makeCompressed();
315 this->ComputeSQPsens(calcMethod, sensMult, sensInv, sensRes);
322 VectorXd &lagMultAct)
324 int ni = this->subDvAct.size();
325 VectorXd deltaDVAct(ni);
326 bool isNan, isLarge, rerunDefault =
true, attemptConstrOnly;
332 deltaDVAct.setZero();
333 attemptConstrOnly =
false;
334 if ((calcMethod % 10) != calcMethod)
336 calcMethod = calcMethod % 10;
337 attemptConstrOnly =
true;
344 rerunDefault = SQPstep<Eigen::HouseholderQR>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct, deltaDVAct,
345 isNan, isLarge, attemptConstrOnly);
350 rerunDefault = SQPstep<Eigen::ColPivHouseholderQR>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct,
351 deltaDVAct, isNan, isLarge, attemptConstrOnly);
357 rerunDefault = SQPstep<Eigen::LLT<MatrixXd>>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct, deltaDVAct,
358 isNan, isLarge, attemptConstrOnly);
362 rerunDefault = SQPstep<Eigen::PartialPivLU>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct, deltaDVAct,
363 isNan, isLarge, attemptConstrOnly);
367 SQPstep<Eigen::ColPivHouseholderQR>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct, deltaDVAct, isNan,
369 rerunDefault =
false;
373 if (attemptConstrOnly)
375 rerunDefault =
false;
383 ni = this->subDvAct.size();
384 for (ii = 0; ii < ni; ++ii)
386 this->deltaDV[subDvAct[ii]] = deltaDVAct[ii];
389 ni = this->subConstrAct.size();
390 this->lagMult.setZero(nConstr);
393 for (ii = 0; ii < nConstr; ++ii)
395 lagMult[subConstrAct[ii]] = 0;
400 for (ii = 0; ii < ni; ++ii)
402 this->lagMult[this->subConstrAct[ii]] = lagMultAct[ii];
403 isNan = isNan || isnan(lagMultAct[ii]);
409 DisplayVector(isConstrAct);
410 DisplayVector(isDvAct);
414 void RSVScalc::ComputeSQPstep(
int calcMethod, MatrixXd_sparse &dConstrAct, RowVectorXd &dObjAct, VectorXd &constrAct,
415 VectorXd &lagMultAct)
417 int ni = this->subDvAct.size();
418 VectorXd deltaDVAct(ni);
419 bool isNan, isLarge, rerunDefault =
true, attemptConstrOnly;
425 deltaDVAct.setZero();
426 attemptConstrOnly =
false;
427 if ((calcMethod % 10) != calcMethod)
429 calcMethod = calcMethod % 10;
430 attemptConstrOnly =
true;
432 this->HLag_sparse.makeCompressed();
433 dConstrAct.makeCompressed();
439 SQPstep_sparse<Eigen::SparseLU<MatrixXd_sparse>>(*
this, dConstrAct, dObjAct, constrAct, lagMultAct,
440 deltaDVAct, isNan, isLarge,
true);
441 rerunDefault =
false;
444 if (attemptConstrOnly)
446 rerunDefault =
false;
454 ni = this->subDvAct.size();
455 for (ii = 0; ii < ni; ++ii)
457 this->deltaDV[subDvAct[ii]] = deltaDVAct[ii];
460 ni = this->subConstrAct.size();
461 this->lagMult.setZero(nConstr);
464 for (ii = 0; ii < nConstr; ++ii)
466 lagMult[subConstrAct[ii]] = 0;
471 for (ii = 0; ii < ni; ++ii)
473 this->lagMult[this->subConstrAct[ii]] = lagMultAct[ii];
474 isNan = isNan || isnan(lagMultAct[ii]);
480 DisplayVector(isConstrAct);
481 DisplayVector(isDvAct);
485 void RSVScalc::ComputeSQPsens(
int calcMethod,
const Eigen::MatrixXd &sensMult,
const Eigen::MatrixXd &sensInv,
486 Eigen::MatrixXd &sensRes)
491 SQPsens<Eigen::HouseholderQR>(sensMult, sensInv, sensRes);
494 SQPsens<Eigen::ColPivHouseholderQR>(sensMult, sensInv, sensRes);
499 SQPsens<Eigen::LLT<MatrixXd>>(sensMult, sensInv, sensRes);
502 SQPsens<Eigen::PartialPivLU>(sensMult, sensInv, sensRes);
505 SQPsens<Eigen::ColPivHouseholderQR>(sensMult, sensInv, sensRes);
509 this->sensDv.setZero(this->nDv, this->nConstr);
510 int nConstrAct, nDvAct;
511 nConstrAct = this->subConstrAct.size();
512 nDvAct = this->subDvAct.size();
513 for (
int i = 0; i < nDvAct; ++i)
515 for (
int j = 0; j < nConstrAct; ++j)
517 this->sensDv(this->subDvAct[i], this->subConstrAct[j]) = sensRes(i, j);
522 bool SQPsens_sparse2(
const Eigen::MatrixXd &sensMult,
const MatrixXd_sparse &sensInv, Eigen::MatrixXd &sensRes)
524 Eigen::SparseLU<MatrixXd_sparse> HLagSystem;
525 HLagSystem.compute(sensInv);
526 if (HLagSystem.info() != Eigen::Success)
533 sensRes = -(HLagSystem.solve(sensMult));
538 void RSVScalc::ComputeSQPsens(
int calcMethod, Eigen::MatrixXd &sensMult, MatrixXd_sparse &sensInv,
539 Eigen::MatrixXd &sensRes)
544 SQPsens_sparse<Eigen::SparseLU<MatrixXd_sparse>>(sensMult, sensInv, sensRes);
548 this->sensDv.setZero(this->nDv, this->nConstr);
549 int nConstrAct, nDvAct;
550 nConstrAct = this->subConstrAct.size();
551 nDvAct = this->subDvAct.size();
552 for (
int i = 0; i < nDvAct; ++i)
554 for (
int j = 0; j < nConstrAct; ++j)
556 this->sensDv(this->subDvAct[i], this->subConstrAct[j]) = sensRes(i, j);
Provides the infrastructure for calculation of the RSVS equations.
Provides the infrastructure for calculation of the RSVS equations.
void CheckAndCompute(int calcMethod=0, bool sensCalc=false)
Prepare the active arrays for SQP calculation and calculate the SQP step.
bool PrepareMatricesForSQP(Eigen::MatrixXd &dConstrAct, Eigen::MatrixXd &HConstrAct, Eigen::MatrixXd &HObjAct, MatrixXd_sparse &dConstrAct_sparse, MatrixXd_sparse &HConstrAct_sparse, MatrixXd_sparse &HObjAct_sparse, Eigen::RowVectorXd &dObjAct, Eigen::VectorXd &constrAct, Eigen::VectorXd &lagMultAct)
Prepares the matrices needed for the SQP step calculation.
void ComputeSQPstep(int calcMethod, Eigen::MatrixXd &dConstrAct, Eigen::RowVectorXd &dObjAct, Eigen::VectorXd &constrAct, Eigen::VectorXd &lagMultAct)
Calculates the next SQP step.
bool PrepareMatricesForSQPSensitivity(const Eigen::MatrixXd &dConstrAct, const Eigen::MatrixXd &HConstrAct, const Eigen::MatrixXd &HObjAct, Eigen::MatrixXd &sensMult, Eigen::MatrixXd &sensInv, Eigen::MatrixXd &sensRes) const
Prepares the matrices needed for the calculation of the sensitivity of the SQP.
Provides a 2D std::vector based container.
#define RSVS3D_ERROR_LOGIC(M)
Throw a logic_error.
#define RSVS3D_ERROR_NOTHROW(M)
Generic rsvs warning.