52 const std::string& cd_type,
53 std::optional<int> random_seed = std::nullopt)
55 , update_clusters(update_clusters)
56 , cd_iterations(cd_iterations)
58 , rng(random_seed.has_value() ? std::mt19937(*random_seed)
59 : std::mt19937(std::random_device{}()))
64 void run(Eigen::VectorXd& beta0,
65 Eigen::VectorXd& beta,
67 const Eigen::ArrayXd& lambda,
68 const std::unique_ptr<Loss>& loss,
70 const Eigen::VectorXd& gradient,
71 const std::vector<int>& working_set,
72 const Eigen::MatrixXd& x,
73 const Eigen::VectorXd& x_centers,
74 const Eigen::VectorXd& x_scales,
75 const Eigen::MatrixXd& y)
override;
78 void run(Eigen::VectorXd& beta0,
79 Eigen::VectorXd& beta,
81 const Eigen::ArrayXd& lambda,
82 const std::unique_ptr<Loss>& loss,
84 const Eigen::VectorXd& gradient,
85 const std::vector<int>& working_set,
86 const Eigen::SparseMatrix<double>& x,
87 const Eigen::VectorXd& x_centers,
88 const Eigen::VectorXd& x_scales,
89 const Eigen::MatrixXd& y)
override;
92 void run(Eigen::VectorXd& beta0,
93 Eigen::VectorXd& beta,
95 const Eigen::ArrayXd& lambda,
96 const std::unique_ptr<Loss>& loss,
98 const Eigen::VectorXd& gradient,
99 const std::vector<int>& working_set,
100 const Eigen::Map<Eigen::MatrixXd>& x,
101 const Eigen::VectorXd& x_centers,
102 const Eigen::VectorXd& x_scales,
103 const Eigen::MatrixXd& y)
override;
106 void run(Eigen::VectorXd& beta0,
107 Eigen::VectorXd& beta,
108 Eigen::MatrixXd& eta,
109 const Eigen::ArrayXd& lambda,
110 const std::unique_ptr<Loss>& loss,
112 const Eigen::VectorXd& gradient,
113 const std::vector<int>& working_set,
114 const Eigen::Map<Eigen::SparseMatrix<double>>& x,
115 const Eigen::VectorXd& x_centers,
116 const Eigen::VectorXd& x_scales,
117 const Eigen::MatrixXd& y)
override;
134 template<
typename MatrixType>
135 void runImpl(Eigen::VectorXd& beta0,
136 Eigen::VectorXd& beta,
137 Eigen::MatrixXd& eta,
138 const Eigen::ArrayXd& lambda,
139 const std::unique_ptr<Loss>& loss,
141 const Eigen::VectorXd& gradient_in,
142 const std::vector<int>& working_set,
144 const Eigen::VectorXd& x_centers,
145 const Eigen::VectorXd& x_scales,
146 const Eigen::MatrixXd& y)
148 using Eigen::MatrixXd;
149 using Eigen::VectorXd;
151 const int n = x.rows();
152 const int m = eta.cols();
157 pgd_solver.run(beta0,
173 MatrixXd w = MatrixXd::Ones(n, m);
176 loss->updateWeightsAndWorkingResponse(w, z, eta, y);
178 MatrixXd residual = eta - z;
180 Eigen::ArrayXd lambda_cumsum(lambda.size() + 1);
181 lambda_cumsum(0) = 0.0;
182 std::partial_sum(lambda.begin(), lambda.end(), lambda_cumsum.begin() + 1);
184 for (
int it = 0; it < this->cd_iterations; ++it) {
186 computeObjective(penalty, beta, residual, w, lambda, working_set);
190 Eigen::MatrixXd old_residual = residual;
191 Eigen::VectorXd old_beta = beta;
192 Eigen::VectorXd old_beta0 = beta0;
205 this->update_clusters,
210 computeObjective(penalty, beta, residual, w, lambda, working_set);
212 if (!std::isfinite(new_obj) || new_obj > old_obj) {
214 clusters = old_clusters;
215 residual = old_residual;
229 double computeObjective(
const SortedL1Norm& penalty,
230 const Eigen::VectorXd& beta,
231 const Eigen::MatrixXd& residual,
232 const Eigen::MatrixXd& w,
233 const Eigen::ArrayXd& lambda,
234 const std::vector<int>& working_set)
237 0.5 * (residual.array().square() * w.array()).sum() / residual.rows() +
238 penalty.eval(beta(working_set), lambda.head(working_set.size()));
245 double pgd_learning_rate =
247 double pgd_learning_rate_decr =
250 bool update_clusters =
false;
251 int cd_iterations = 10;
252 std::string cd_type =
255 std::random_device{}()
void run(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::MatrixXd &eta, const Eigen::ArrayXd &lambda, const std::unique_ptr< Loss > &loss, const SortedL1Norm &penalty, const Eigen::VectorXd &gradient, const std::vector< int > &working_set, const Eigen::SparseMatrix< double > &x, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const Eigen::MatrixXd &y) override
Pure virtual function defining the solver's optimization routine.
void run(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::MatrixXd &eta, const Eigen::ArrayXd &lambda, const std::unique_ptr< Loss > &loss, const SortedL1Norm &penalty, const Eigen::VectorXd &gradient, const std::vector< int > &working_set, const Eigen::MatrixXd &x, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const Eigen::MatrixXd &y) override
Pure virtual function defining the solver's optimization routine.
void run(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::MatrixXd &eta, const Eigen::ArrayXd &lambda, const std::unique_ptr< Loss > &loss, const SortedL1Norm &penalty, const Eigen::VectorXd &gradient, const std::vector< int > &working_set, const Eigen::Map< Eigen::SparseMatrix< double > > &x, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const Eigen::MatrixXd &y) override
Pure virtual function defining the solver's optimization routine.
void run(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::MatrixXd &eta, const Eigen::ArrayXd &lambda, const std::unique_ptr< Loss > &loss, const SortedL1Norm &penalty, const Eigen::VectorXd &gradient, const std::vector< int > &working_set, const Eigen::Map< Eigen::MatrixXd > &x, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const Eigen::MatrixXd &y) override
Pure virtual function defining the solver's optimization routine.
double coordinateDescent(Eigen::VectorXd &beta0, Eigen::VectorXd &beta, Eigen::MatrixXd &residual, Clusters &clusters, const Eigen::ArrayXd &lambda_cumsum, const T &x, const Eigen::MatrixXd &w, const Eigen::VectorXd &x_centers, const Eigen::VectorXd &x_scales, const bool intercept, const JitNormalization jit_normalization, const bool update_clusters, std::mt19937 &rng, const std::string &cd_type="cyclical")