34 #include <Eigen/SparseCholesky>
39 Eigen::VectorXd Shrinkage(
const Eigen::VectorXd&
a,
const double kappa) {
40 const Eigen::VectorXd a_plus_kappa =
a.array() + kappa;
41 const Eigen::VectorXd a_minus_kappa =
a.array() - kappa;
42 return a_plus_kappa.cwiseMin(0) + a_minus_kappa.cwiseMax(0);
48 const Eigen::SparseMatrix<double>& A,
49 const Eigen::VectorXd& b,
52 CHECK_GT(options.
rho, 0);
53 CHECK_GT(options.
alpha, 0);
58 Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> linear_solver;
59 linear_solver.compute(A.transpose() * A);
61 Eigen::VectorXd
z = Eigen::VectorXd::Zero(A.rows());
62 Eigen::VectorXd z_old(A.rows());
63 Eigen::VectorXd u = Eigen::VectorXd::Zero(A.rows());
65 Eigen::VectorXd Ax(A.rows());
66 Eigen::VectorXd Ax_hat(A.rows());
68 const double b_norm = b.norm();
69 const double eps_pri_threshold =
71 const double eps_dual_threshold =
75 *
x = linear_solver.solve(A.transpose() * (b +
z - u));
76 if (linear_solver.info() != Eigen::Success) {
81 Ax_hat = options.
alpha * Ax + (1 - options.
alpha) * (
z + b);
84 z = Shrinkage(Ax_hat - b + u, 1 / options.
rho);
88 const double r_norm = (Ax -
z - b).norm();
89 const double s_norm = (-options.
rho * A.transpose() * (
z - z_old)).norm();
90 const double eps_pri =
92 std::max(b_norm, std::max(Ax.norm(),
z.norm()));
93 const double eps_dual =
97 if (r_norm < eps_pri && s_norm < eps_dual) {
bool SolveLeastAbsoluteDeviations(const LeastAbsoluteDeviationsOptions &options, const Eigen::SparseMatrix< double > &A, const Eigen::VectorXd &b, Eigen::VectorXd *x)
double relative_tolerance
double absolute_tolerance