49 void compute_d(Eigen::VectorXd& d,
const Eigen::MatrixXd& J,
const Eigen::VectorXd& np);
50 void update_z(Eigen::VectorXd& z,
const Eigen::MatrixXd& J,
const Eigen::VectorXd& d,
int iq);
51 void update_r(
const Eigen::MatrixXd& R, Eigen::VectorXd& r,
const Eigen::VectorXd& d,
int iq);
52 bool add_constraint(Eigen::MatrixXd& R, Eigen::MatrixXd& J, Eigen::VectorXd& d,
int& iq,
double& rnorm);
53 void delete_constraint(Eigen::MatrixXd& R, Eigen::MatrixXd& J, Eigen::VectorXi& A, Eigen::VectorXd& u,
int n,
int p,
int& iq,
int l);
58 void cholesky_solve(
const Eigen::MatrixXd& L, Eigen::VectorXd& x,
const Eigen::VectorXd& b);
59 void forward_elimination(
const Eigen::MatrixXd& L, Eigen::VectorXd& y,
const Eigen::VectorXd& b);
60 void backward_elimination(
const Eigen::MatrixXd& U, Eigen::VectorXd& x,
const Eigen::VectorXd& y);
64 double scalar_product(
const Eigen::VectorXd& x,
const Eigen::VectorXd& y);
68 void print_matrix(
const char* name,
const Eigen::MatrixXd& A,
int n = -1,
int m = -1);
71 void print_vector(
const char* name,
const Eigen::Matrix< T, Eigen::Dynamic, 1 >& v,
int n = -1);
76 const Eigen::MatrixXd& _CE,
const Eigen::VectorXd& ce0,
77 const Eigen::MatrixXd& _CI,
const Eigen::VectorXd& ci0,
87 const Eigen::MatrixXd& CE = _CE.transpose();
88 const Eigen::MatrixXd& CI = _CI.transpose();
89 static Eigen::MatrixXd G(_G.rows(),_G.cols());
90 G.resize(_G.rows(),_G.cols());
94 std::ostringstream msg;
98 unsigned mx = std::numeric_limits<int>::max();
99 if(G.cols() >= mx || G.rows() >= mx ||
100 CE.rows() >= mx || CE.cols() >= mx ||
101 CI.rows() >= mx || CI.cols() >= mx ||
102 ci0.size() >= mx || ce0.size() >= mx || g0.size() >= mx){
103 msg <<
"The dimensions of one of the input matrices or vectors were " 104 <<
"too large." << std::endl
105 <<
"The maximum allowable size for inputs to solve_quadprog is:" 107 throw std::logic_error(msg.str());
110 int n = G.cols(), p = CE.cols(), m = CI.cols();
111 if ((
int)G.rows() != n)
113 msg <<
"The matrix G is not a square matrix (" << G.rows() <<
" x " 115 throw std::logic_error(msg.str());
117 if ((
int)CE.rows() != n)
119 msg <<
"The matrix CE is incompatible (incorrect number of rows " 120 << CE.rows() <<
" , expecting " << n <<
")";
121 throw std::logic_error(msg.str());
123 if ((
int)ce0.size() != p)
125 msg <<
"The vector ce0 is incompatible (incorrect dimension " 126 << ce0.size() <<
", expecting " << p <<
")";
127 throw std::logic_error(msg.str());
129 if ((
int)CI.rows() != n)
131 msg <<
"The matrix CI is incompatible (incorrect number of rows " 132 << CI.rows() <<
" , expecting " << n <<
")";
133 throw std::logic_error(msg.str());
135 if ((
int)ci0.size() != m)
137 msg <<
"The vector ci0 is incompatible (incorrect dimension " 138 << ci0.size() <<
", expecting " << m <<
")";
139 throw std::logic_error(msg.str());
142 register int i, j, k, l;
144 static Eigen::MatrixXd R(n, n), J(n, n);
147 static Eigen::VectorXd s(m + p),z(n),r(m + p),d(n),np(n),u(m + p),x_old(n),u_old(m + p);
156 double f_value, psi, c1, c2, sum, ss, R_norm;
158 if (std::numeric_limits<double>::has_infinity)
159 inf = std::numeric_limits<double>::infinity();
164 static Eigen::VectorXi A(m + p),A_old(m + p),iai(m + p);
170 static Eigen::VectorXi iaexcl(m + p);
171 iaexcl.resize(m + p);
177 std::cout << std::endl <<
"Starting solve_quadprog" << std::endl;
192 for (i = 0; i < n; i++)
212 for (i = 0; i < n; i++)
216 for (j = 0; j < n; j++)
239 std::cout <<
"Unconstrained solution: " << f_value << std::endl;
245 for (i = 0; i < p; i++)
247 for (j = 0; j < n; j++)
262 if (fabs(
scalar_product(z, z)) > std::numeric_limits<double>::epsilon())
266 for (k = 0; k < n; k++)
271 for (k = 0; k < iq; k++)
281 throw std::runtime_error(
"Constraints are linearly dependent");
287 for (i = 0; i < m; i++)
295 for (i = p; i < iq; i++)
305 for (i = 0; i < m; i++)
309 for (j = 0; j < n; j++)
310 sum += CI(j,i) * x[j];
313 psi += std::min(0.0, sum);
320 if (fabs(psi) <= m * std::numeric_limits<double>::epsilon() * c1 * c2* 100.0)
329 for (i = 0; i < iq; i++)
335 for (i = 0; i < n; i++)
339 for (i = 0; i < m; i++)
341 if (s[i] < ss && iai[i] != -1 && iaexcl[i])
355 for (i = 0; i < n; i++)
363 std::cout <<
"Trying with constraint " << ip << std::endl;
374 std::cout <<
"Step direction z" << std::endl;
387 for (k = p; k < iq; k++)
391 if (u[k] / r[k] < t1)
399 if (fabs(
scalar_product(z, z)) > std::numeric_limits<double>::epsilon())
405 t = std::min(t1, t2);
407 std::cout <<
"Step sizes: " << t <<
" (t1 = " << t1 <<
", t2 = " << t2 <<
") ";
424 for (k = 0; k < iq; k++)
430 std::cout <<
" in dual space: " 431 << f_value << std::endl;
442 for (k = 0; k < n; k++)
447 for (k = 0; k < iq; k++)
451 std::cout <<
" in both spaces: " 452 << f_value << std::endl;
459 if (fabs(t - t2) < std::numeric_limits<double>::epsilon())
462 std::cout <<
"Full step has taken " << t << std::endl;
476 for (i = 0; i < m; i++)
478 for (i = p; i < iq; i++)
484 for (i = 0; i < n; i++)
500 std::cout <<
"Partial step has taken " << t << std::endl;
513 for (k = 0; k < n; k++)
514 sum += CI(k,ip) * x[k];
515 s[ip] = sum + ci0[ip];
523 inline void compute_d(Eigen::VectorXd& d,
const Eigen::MatrixXd& J,
const Eigen::VectorXd& np)
525 register int i, j, n = d.size();
529 for (i = 0; i < n; i++)
532 for (j = 0; j < n; j++)
533 sum += J(j,i) * np[j];
538 inline void update_z(Eigen::VectorXd& z,
const Eigen::MatrixXd& J,
const Eigen::VectorXd& d,
int iq)
540 register int i, j, n = z.size();
543 for (i = 0; i < n; i++)
546 for (j = iq; j < n; j++)
547 z[i] += J(i,j) * d[j];
551 inline void update_r(
const Eigen::MatrixXd& R, Eigen::VectorXd& r,
const Eigen::VectorXd& d,
int iq)
557 for (i = iq - 1; i >= 0; i--)
560 for (j = i + 1; j < iq; j++)
561 sum += R(i,j) * r[j];
562 r[i] = (d[i] - sum) / R(i,i);
566 bool add_constraint(Eigen::MatrixXd& R, Eigen::MatrixXd& J, Eigen::VectorXd& d,
int& iq,
double& R_norm)
570 std::cout <<
"Add constraint " << iq <<
'/';
572 register int i, j, k;
573 double cc, ss, h, t1, t2, xny;
579 for (j = n - 1; j >= iq + 1; j--)
592 if (fabs(h) < std::numeric_limits<double>::epsilon())
605 xny = ss / (1.0 + cc);
606 for (k = 0; k < n; k++)
610 J(k,j - 1) = t1 * cc + t2 * ss;
611 J(k,j) = xny * (t1 + J(k,j - 1)) - t2;
619 for (i = 0; i < iq; i++)
622 std::cout << iq << std::endl;
628 if (fabs(d[iq - 1]) <= std::numeric_limits<double>::epsilon() * R_norm)
633 R_norm = std::max<double>(R_norm, fabs(d[iq - 1]));
637 void delete_constraint(Eigen::MatrixXd& R, Eigen::MatrixXd& J, Eigen::VectorXi& A, Eigen::VectorXd& u,
int n,
int p,
int& iq,
int l)
640 std::cout <<
"Delete constraint " << l <<
' ' << iq;
642 register int i, j, k, qq = -1;
643 double cc, ss, h, xny, t1, t2;
646 for (i = p; i < iq; i++)
654 for (i = qq; i < iq - 1; i++)
658 for (j = 0; j < n; j++)
666 for (j = 0; j < iq; j++)
671 std::cout <<
'/' << iq << std::endl;
677 for (j = qq; j < iq; j++)
682 if (fabs(h) < std::numeric_limits<double>::epsilon())
696 xny = ss / (1.0 + cc);
697 for (k = j + 1; k < iq; k++)
701 R(j,k) = t1 * cc + t2 * ss;
702 R(j + 1,k) = xny * (t1 + R(j,k)) - t2;
704 for (k = 0; k < n; k++)
708 J(k,j) = t1 * cc + t2 * ss;
709 J(k,j + 1) = xny * (J(k,j) + t1) - t2;
716 register double a1, b1, t;
722 return a1 * ::std::sqrt(1.0 + t * t);
728 return b1 * ::std::sqrt(1.0 + t * t);
730 return a1 * ::std::sqrt(2.0);
736 register int i, n = x.size();
740 for (i = 0; i < n; i++)
747 register int i, j, k, n = A.rows();
750 for (i = 0; i < n; i++)
752 for (j = i; j < n; j++)
755 for (k = i - 1; k >= 0; k--)
756 sum -= A(i,k)*A(j,k);
761 std::ostringstream os;
764 os <<
"Error in cholesky decomposition, sum: " << sum;
765 throw std::logic_error(os.str());
768 A(i,i) = ::std::sqrt(sum);
771 A(j,i) = sum / A(i,i);
773 for (k = i + 1; k < n; k++)
778 void cholesky_solve(
const Eigen::MatrixXd& L, Eigen::VectorXd& x,
const Eigen::VectorXd& b)
781 static Eigen::VectorXd y(n);
792 register int i, j, n = L.rows();
794 y[0] = b[0] / L(0,0);
795 for (i = 1; i < n; i++)
798 for (j = 0; j < i; j++)
799 y[i] -= L(i,j) * y[j];
800 y[i] = y[i] / L(i,i);
806 register int i, j, n = U.rows();
808 x[n - 1] = y[n - 1] / U(n - 1,n - 1);
809 for (i = n - 2; i >= 0; i--)
812 for (j = i + 1; j < n; j++)
813 x[i] -= U(i,j) * x[j];
814 x[i] = x[i] / U(i,i);
818 void print_matrix(
const char* name,
const Eigen::MatrixXd& A,
int n,
int m)
820 std::ostringstream s;
827 s << name <<
": " << std::endl;
828 for (
int i = 0; i < n; i++)
831 for (
int j = 0; j < m; j++)
836 t = t.substr(0, t.size() - 3);
838 std::cout << t << std::endl;
842 void print_vector(
const char* name,
const Eigen::Matrix<T, Eigen::Dynamic, 1 >& v,
int n)
844 std::ostringstream s;
849 s << name <<
": " << std::endl <<
" ";
850 for (
int i = 0; i < n; i++)
855 t = t.substr(0, t.size() - 2);
857 std::cout << t << std::endl;
void update_r(const Eigen::MatrixXd &R, Eigen::VectorXd &r, const Eigen::VectorXd &d, int iq)
void cholesky_decomposition(Eigen::MatrixXd &A)
void print_vector(const char *name, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &v, int n=-1)
void backward_elimination(const Eigen::MatrixXd &U, Eigen::VectorXd &x, const Eigen::VectorXd &y)
double solve_quadprog(const Eigen::MatrixXd &_G, const Eigen::VectorXd &g0, const Eigen::MatrixXd &_CE, const Eigen::VectorXd &ce0, const Eigen::MatrixXd &_CI, const Eigen::VectorXd &ci0, Eigen::VectorXd &x)
void delete_constraint(Eigen::MatrixXd &R, Eigen::MatrixXd &J, Eigen::VectorXi &A, Eigen::VectorXd &u, int n, int p, int &iq, int l)
void compute_d(Eigen::VectorXd &d, const Eigen::MatrixXd &J, const Eigen::VectorXd &np)
void forward_elimination(const Eigen::MatrixXd &L, Eigen::VectorXd &y, const Eigen::VectorXd &b)
bool add_constraint(Eigen::MatrixXd &R, Eigen::MatrixXd &J, Eigen::VectorXd &d, int &iq, double &rnorm)
void cholesky_solve(const Eigen::MatrixXd &L, Eigen::VectorXd &x, const Eigen::VectorXd &b)
double scalar_product(const Eigen::VectorXd &x, const Eigen::VectorXd &y)
void update_z(Eigen::VectorXd &z, const Eigen::MatrixXd &J, const Eigen::VectorXd &d, int iq)
double distance(double a, double b)
void print_matrix(const char *name, const Eigen::MatrixXd &A, int n=-1, int m=-1)