37 #include "gtest/gtest.h"
71 optim.setObjectiveFunction(objective, 1,
false);
73 EXPECT_EQ(optim.getObjectiveDimension(), 1);
74 EXPECT_EQ(optim.getNonLsqObjectiveDimension(), 1);
75 EXPECT_EQ(optim.getLsqObjectiveDimension(), 0);
78 double value = optim.computeValueObjective();
79 EXPECT_EQ(value, 5) <<
"x*x+1 with x=2";
81 value = optim.computeValueNonLsqObjective();
82 EXPECT_EQ(value, 5) <<
"x*x+1 with x=2";
85 Eigen::VectorXd gradient(optim.getParameterDimension());
86 optim.computeGradientObjective(gradient);
88 EXPECT_NEAR(gradient(0), 4, 1e-5) <<
"2*x = 2*2 = 4";
91 Eigen::MatrixXd hessian(optim.getParameterDimension(), optim.getParameterDimension());
92 optim.computeDenseHessianObjective(hessian);
94 EXPECT_NEAR(hessian(0, 0), 2, 1e-5);
106 values[0] =
x[0] - 1;
107 values[1] = 6 -
x[0];
109 optim.setObjectiveFunction(objective, 2,
true);
111 EXPECT_EQ(optim.getObjectiveDimension(), 1);
112 EXPECT_EQ(optim.getNonLsqObjectiveDimension(), 0);
113 EXPECT_EQ(optim.getLsqObjectiveDimension(), 2);
116 Eigen::Vector2d lsq_values;
117 optim.computeValuesLsqObjective(lsq_values);
118 EXPECT_EQ(lsq_values(0), 1) <<
"(2-1)";
119 EXPECT_EQ(lsq_values(1), 4) <<
"(6-2)";
121 double value = optim.computeValueObjective();
123 EXPECT_EQ(value, lsq_values.squaredNorm()) <<
"(2-1)^2 + (6-4)^2 = 1 + 16 = 17";
126 Eigen::MatrixXd lsq_jacob(optim.getLsqObjectiveDimension(), optim.getParameterDimension());
127 optim.computeDenseJacobianLsqObjective(lsq_jacob);
128 EXPECT_NEAR(lsq_jacob(0, 0), 1, 1e-5);
129 EXPECT_NEAR(lsq_jacob(1, 0), -1, 1e-5);
133 Eigen::VectorXd gradient(optim.getParameterDimension());
134 optim.computeGradientObjective(gradient);
135 EXPECT_NEAR(gradient(0), -6, 1e-5);
139 Eigen::MatrixXd hessian(optim.getParameterDimension(), optim.getParameterDimension());
140 optim.computeDenseHessianObjective(hessian);
141 EXPECT_NEAR(hessian(0, 0), 4, 1e-4);
146 Eigen::VectorXd
x(1);
153 values[0] =
x[0] - 1;
154 values[1] = 6 -
x[0];
156 optim.setObjectiveFunction(objective, 2,
true);
159 int nnz = optim.computeSparseJacobianLsqObjectiveNNZ();
162 Eigen::VectorXi irow(nnz);
163 Eigen::VectorXi icol(nnz);
164 Eigen::VectorXd values(nnz);
165 optim.computeSparseJacobianLsqObjectiveStructure(irow, icol);
166 optim.computeSparseJacobianLsqObjectiveValues(values);
170 std::vector<Eigen::Triplet<double>> triplets;
172 if (!triplets.empty()) jacob_sparse.
setFromTriplets(triplets.begin(), triplets.end());
174 Eigen::MatrixXd jacob_sol(2, 1);
181 optim.computeSparseJacobianLsqObjective(jacob_sparse_eigen);
185 int hess_nnz = optim.computeSparseHessianObjectiveNNZ();
187 Eigen::VectorXi hess_irow(hess_nnz);
188 Eigen::VectorXi hess_icol(hess_nnz);
189 Eigen::VectorXd hess_values(hess_nnz);
190 optim.computeSparseHessianObjectiveStructure(hess_irow, hess_icol);
191 optim.computeSparseHessianObjectiveValues(hess_values);
197 if (!triplets.empty()) sparse_hessian.
setFromTriplets(triplets.begin(), triplets.end());
199 Eigen::MatrixXd hessian_sol(1, 1);
206 optim.computeSparseHessianObjective(sparse_hessian_eigen);
212 Eigen::VectorXd
x(3);
221 values[0] =
x[0] *
x[0] + 1;
222 values[1] =
x[1] +
x[2] - 10;
224 optim.setEqualityConstraint(ceq, 2);
227 Eigen::VectorXd values(optim.getEqualityDimension());
228 optim.computeValuesEquality(values);
230 EXPECT_EQ(values[0], 5) <<
"x*x+1 with x=2";
231 EXPECT_EQ(values[1], -3) <<
"3+4-10";
234 Eigen::MatrixXd jacobian(optim.getEqualityDimension(), optim.getParameterDimension());
235 optim.computeDenseJacobianEqualities(jacobian,
nullptr);
237 Eigen::MatrixXd jacob_sol(2, 3);
238 jacob_sol << 4, 0, 0, 0, 1, 1;
243 Eigen::MatrixXd hessian(optim.getParameterDimension(), optim.getParameterDimension());
244 optim.computeDenseHessianEqualities(hessian,
nullptr);
246 Eigen::MatrixXd hessian_sol(3, 3);
247 hessian_sol << 2, 0, 0, 0, 0, 0, 0, 0, 0;
254 Eigen::VectorXd
x(3);
263 values[0] =
x[0] *
x[0] + 1;
264 values[1] =
x[1] +
x[2] - 10;
266 optim.setEqualityConstraint(ceq, 2);
269 int nnz = optim.computeSparseJacobianEqualitiesNNZ();
271 EXPECT_EQ(nnz, optim.getParameterDimension() * optim.getEqualityDimension());
273 Eigen::VectorXi irow(nnz);
274 Eigen::VectorXi icol(nnz);
275 Eigen::VectorXd values(nnz);
276 optim.computeSparseJacobianEqualitiesStructure(irow, icol);
277 optim.computeSparseJacobianEqualitiesValues(values);
280 std::vector<Eigen::Triplet<double>> triplet_list;
281 for (
int i = 0; i < nnz; ++i) triplet_list.emplace_back(irow[i], icol[i], values[i]);
283 sparse_jacobian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
285 Eigen::MatrixXd jacob_sol(2, 3);
286 jacob_sol << 4, 0, 0, 0, 1, 1;
292 optim.computeSparseJacobianEqualities(sparse_jacob_eigen);
296 int hess_nnz = optim.computeSparseHessianEqualitiesNNZ();
298 Eigen::VectorXi hess_irow(hess_nnz);
299 Eigen::VectorXi hess_icol(hess_nnz);
300 Eigen::VectorXd hess_values(hess_nnz);
301 optim.computeSparseHessianEqualitiesStructure(hess_irow, hess_icol);
302 optim.computeSparseHessianEqualitiesValues(hess_values);
305 triplet_list.clear();
306 for (
int i = 0; i < hess_nnz; ++i) triplet_list.emplace_back(hess_irow[i], hess_icol[i], hess_values[i]);
308 sparse_hessian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
310 Eigen::MatrixXd hessian_sol(3, 3);
311 hessian_sol << 2, 0, 0, 0, 0, 0, 0, 0, 0;
317 optim.computeSparseHessianEqualities(sparse_hessian_eigen);
323 Eigen::VectorXd
x(3);
332 values[0] =
x[0] *
x[0] + 1;
333 values[1] =
x[1] +
x[2] - 9;
335 optim.setInequalityConstraint(
c, 2);
338 Eigen::VectorXd values(optim.getInequalityDimension());
339 optim.computeValuesInequality(values);
341 EXPECT_EQ(values[0], 5) <<
"x*x+1 with x=2";
342 EXPECT_EQ(values[1], -10) <<
"3-4-9";
345 optim.computeValuesActiveInequality(values);
346 EXPECT_EQ(values[0], 5);
347 EXPECT_EQ(values[1], 0);
350 Eigen::MatrixXd jacobian(optim.getInequalityDimension(), optim.getParameterDimension());
351 optim.computeDenseJacobianInequalities(jacobian,
nullptr);
353 Eigen::MatrixXd jacob_sol(2, 3);
354 jacob_sol << 4, 0, 0, 0, 1, 1;
358 optim.computeDenseJacobianActiveInequalities(jacobian);
360 Eigen::MatrixXd active_ineq_jacob_sol(2, 3);
361 active_ineq_jacob_sol << 4, 0, 0, 0, 0, 0;
365 Eigen::MatrixXd hessian(optim.getParameterDimension(), optim.getParameterDimension());
366 optim.computeDenseHessianInequalities(hessian,
nullptr);
368 Eigen::MatrixXd hessian_sol(3, 3);
369 hessian_sol << 2, 0, 0, 0, 0, 0, 0, 0, 0;
376 Eigen::VectorXd
x(3);
385 values[0] =
x[0] *
x[0] + 1;
386 values[1] =
x[1] +
x[2] - 9;
388 optim.setInequalityConstraint(
c, 2);
391 int nnz = optim.computeSparseJacobianInequalitiesNNZ();
393 EXPECT_EQ(nnz, optim.getParameterDimension() * optim.getInequalityDimension());
395 Eigen::VectorXi irow(nnz);
396 Eigen::VectorXi icol(nnz);
397 Eigen::VectorXd values(nnz);
398 optim.computeSparseJacobianInequalitiesStructure(irow, icol);
399 optim.computeSparseJacobianInequalitiesValues(values);
402 std::vector<Eigen::Triplet<double>> triplet_list;
403 for (
int i = 0; i < nnz; ++i) triplet_list.emplace_back(irow[i], icol[i], values[i]);
405 sparse_jacobian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
407 Eigen::MatrixXd jacob_sol(2, 3);
408 jacob_sol << 4, 0, 0, 0, 1, 1;
414 optim.computeSparseJacobianInequalities(sparse_jacob_eigen);
418 optim.computeSparseJacobianActiveInequalitiesValues(values);
419 triplet_list.clear();
420 for (
int i = 0; i < nnz; ++i) triplet_list.emplace_back(irow[i], icol[i], values[i]);
421 sparse_jacobian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
423 Eigen::MatrixXd active_ineq_jacob_sol(2, 3);
424 active_ineq_jacob_sol << 4, 0, 0, 0, 0, 0;
428 optim.computeSparseJacobianActiveInequalities(sparse_jacob_eigen);
432 int hess_nnz = optim.computeSparseHessianInequalitiesNNZ();
434 Eigen::VectorXi hess_irow(hess_nnz);
435 Eigen::VectorXi hess_icol(hess_nnz);
436 Eigen::VectorXd hess_values(hess_nnz);
437 optim.computeSparseHessianInequalitiesStructure(hess_irow, hess_icol);
438 optim.computeSparseHessianInequalitiesValues(hess_values);
441 triplet_list.clear();
442 for (
int i = 0; i < hess_nnz; ++i) triplet_list.emplace_back(hess_irow[i], hess_icol[i], hess_values[i]);
444 sparse_hessian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
446 Eigen::MatrixXd hessian_sol(3, 3);
447 hessian_sol << 2, 0, 0, 0, 0, 0, 0, 0, 0;
453 optim.computeSparseHessianInequalities(sparse_hessian_eigen);
459 optim.resizeParameterVector(3);
461 Eigen::VectorXd
x(3);
465 optim.setParameterVector(
x);
468 Eigen::VectorXd lb(3);
472 optim.setLowerBounds(lb);
475 optim.setUpperBound(1, 5);
476 optim.setUpperBound(2, 6);
479 Eigen::VectorXd lb_return(optim.getParameterDimension());
480 Eigen::VectorXd ub_return(optim.getParameterDimension());
481 optim.getBounds(lb_return, ub_return);
485 EXPECT_EQ(ub_return[1], 5);
486 EXPECT_EQ(ub_return[2], 6);
489 EXPECT_EQ(optim.finiteBoundsDimension(), 3);
490 EXPECT_EQ(optim.finiteCombinedBoundsDimension(), 2);
495 Eigen::MatrixXd active_bound_jacobian(optim.finiteCombinedBoundsDimension(), optim.getParameterDimension());
496 optim.computeDenseJacobianFiniteCombinedBounds(active_bound_jacobian);
501 optim.setParameterValue(1, -3);
502 optim.setParameterValue(2, 6.01);
503 Eigen::MatrixXd active_bound_jacobian_sol(2, 3);
504 active_bound_jacobian_sol << 0, -1, 0, 0, 0, 1;
506 optim.computeDenseJacobianFiniteCombinedBounds(active_bound_jacobian);
512 optim.resizeParameterVector(3);
514 Eigen::VectorXd
x(3);
518 optim.setParameterVector(
x);
521 Eigen::VectorXd lb(3);
525 optim.setLowerBounds(lb);
528 optim.setUpperBound(1, 5);
529 optim.setUpperBound(2, 6);
533 int nnz = optim.computeSparseJacobianFiniteCombinedBoundsNNZ();
535 Eigen::VectorXi irow(nnz);
536 Eigen::VectorXi icol(nnz);
537 Eigen::VectorXd values(nnz);
538 optim.computeSparseJacobianFiniteCombinedBoundsStructure(irow, icol);
539 optim.computeSparseJacobianFiniteCombinedBoundsValues(values);
542 std::vector<Eigen::Triplet<double>> triplet_list;
543 for (
int i = 0; i < nnz; ++i) triplet_list.emplace_back(irow[i], icol[i], values[i]);
545 sparse_jacobian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
550 optim.computeSparseJacobianFiniteCombinedBounds(sparse_jacob_eigen);
554 optim.setParameterValue(1, -3);
555 optim.setParameterValue(2, 6.01);
557 optim.computeSparseJacobianFiniteCombinedBoundsValues(values);
559 triplet_list.clear();
560 for (
int i = 0; i < nnz; ++i) triplet_list.emplace_back(irow[i], icol[i], values[i]);
561 sparse_jacobian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
563 Eigen::MatrixXd active_bound_jacobian_sol(2, 3);
564 active_bound_jacobian_sol << 0, -1, 0, 0, 0, 1;
569 optim.computeSparseJacobianFiniteCombinedBounds(sparse_jacob_eigen);
575 optim.resizeParameterVector(3);
577 Eigen::VectorXd
x(3);
581 optim.setParameterVector(
x);
584 Eigen::VectorXd lb(3);
588 optim.setLowerBounds(lb);
591 optim.setUpperBound(1, 5);
592 optim.setUpperBound(2, 6);
597 optim.setObjectiveFunction(objective, 1,
true);
602 values[0] =
x[0] *
x[0] + 1;
603 values[1] =
x[1] +
x[2] - 10;
605 optim.setEqualityConstraint(ceq, 2);
610 values[0] =
x[0] *
x[0] + 1;
611 values[1] =
x[1] +
x[2] - 9;
613 optim.setInequalityConstraint(
c, 2);
615 int dim_obj_lsq = optim.getLsqObjectiveDimension();
616 int dim_eq = optim.getEqualityDimension();
617 int dim_ineq = optim.getInequalityDimension();
618 int dim_bounds = optim.finiteCombinedBoundsDimension();
620 int dim_total = dim_obj_lsq + dim_eq + dim_ineq + dim_bounds;
623 optim.computeCombinedSparseJacobian(jacobian,
true,
true,
true,
true,
true, 2, 3, 4);
625 Eigen::MatrixXd sol1(7, 3);
626 sol1 << 4, 0, 0, 4, 0, 0, 0, 1, 1, 4, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1;
628 sol1.middleRows(dim_obj_lsq, dim_eq) *= 2;
629 sol1.middleRows(dim_obj_lsq + dim_eq, dim_ineq) *= 3;
630 sol1.middleRows(dim_obj_lsq + dim_eq + dim_ineq, dim_bounds) *= 4;
633 optim.computeCombinedSparseJacobian(jacobian,
true,
true,
true,
true,
false, 2, 3, 4);
635 Eigen::MatrixXd sol2 = sol1;
641 Eigen::MatrixXd sol3(5, 3);
642 sol3 << 4, 0, 0, 4, 0, 0, 0, 1, 1, 4, 0, 0, 0, 1, 1;
644 int jac_nnz = optim.computeCombinedSparseJacobiansNNZ();
646 Eigen::VectorXi jac_irow(jac_nnz);
647 Eigen::VectorXi jac_icol(jac_nnz);
648 Eigen::VectorXd jac_values(jac_nnz);
649 optim.computeCombinedSparseJacobiansStructure(jac_irow, jac_icol);
650 optim.computeCombinedSparseJacobiansValues(jac_values);
653 std::vector<Eigen::Triplet<double>> triplet_list;
656 sparse_hessian.
setFromTriplets(triplet_list.begin(), triplet_list.end());
660 double multiplier_obj_lsq = 5;
661 Eigen::Vector2d multiplier_eq(2, 3);
662 Eigen::Vector2d multiplier_ineq(3, 4);
664 sol3.row(0) *= multiplier_obj_lsq;
665 sol3.row(1) *= multiplier_eq(0);
666 sol3.row(2) *= multiplier_eq(1);
667 sol3.row(3) *= multiplier_ineq(0);
668 sol3.row(4) *= multiplier_ineq(1);
670 jac_values.setZero();
671 optim.computeCombinedSparseJacobiansValues(jac_values,
true,
true,
true, &multiplier_obj_lsq, multiplier_eq.data(), multiplier_ineq.data());
674 sparse_hessian.
setFromTriplets(triplet_list.begin(), triplet_list.end());