slope 6.2.1
Loading...
Searching...
No Matches
ols.h
Go to the documentation of this file.
1
9#pragma once
10
11#include <Eigen/Dense>
12#include <Eigen/SparseCore>
13#include <Eigen/SparseQR>
14#include <utility>
15
16namespace slope {
17namespace detail {
18
33template<typename T>
34std::pair<double, Eigen::VectorXd>
35fitOls(const Eigen::MatrixBase<T>& X,
36 const Eigen::VectorXd& y,
37 bool fit_intercept = true)
38{
39 Eigen::MatrixXd x_mod = X;
40
41 if (fit_intercept) {
42 // Add column of ones for intercept
43 Eigen::MatrixXd ones = Eigen::MatrixXd::Ones(x_mod.rows(), 1);
44 x_mod.conservativeResize(Eigen::NoChange, x_mod.cols() + 1);
45 x_mod.rightCols(1) = ones;
46 }
47
48 // Solve with column pivoting
49 Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qr(x_mod);
50 Eigen::VectorXd all_coefs = qr.solve(y);
51
52 double intercept = 0.0;
53 Eigen::VectorXd coeffs;
54
55 if (fit_intercept) {
56 intercept = all_coefs(all_coefs.size() - 1);
57 coeffs = all_coefs.head(all_coefs.size() - 1);
58 } else {
59 coeffs = all_coefs;
60 }
61
62 return { intercept, coeffs };
63}
64
80template<typename T>
81std::pair<double, Eigen::VectorXd>
82fitOls(const Eigen::SparseMatrixBase<T>& X,
83 const Eigen::VectorXd& y,
84 bool fit_intercept = true)
85{
86 // TODO: Investigate if we can avoid this copy.
87 Eigen::SparseMatrix<double> x_mod = X;
88
89 if (fit_intercept) {
90 // Construct column of ones for intercept
91 Eigen::VectorXd ones = Eigen::VectorXd::Ones(x_mod.rows());
92 Eigen::SparseMatrix<double> intercept_col(x_mod.rows(), 1);
93 intercept_col.reserve(x_mod.rows());
94
95 for (int i = 0; i < x_mod.rows(); ++i) {
96 intercept_col.insert(i, 0) = ones(i);
97 }
98
99 // Concatenate X and intercept column
100 Eigen::SparseMatrix<double> temp(x_mod.rows(), x_mod.cols() + 1);
101 temp.leftCols(x_mod.cols()) = x_mod;
102 temp.rightCols(1) = intercept_col;
103 x_mod = temp;
104 }
105
106 // Solve with sparse QR
107 Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>>
108 solver;
109 solver.compute(x_mod);
110 Eigen::VectorXd all_cofs = solver.solve(y);
111
112 double intercept = 0.0;
113 Eigen::VectorXd coeffs;
114
115 if (fit_intercept) {
116 intercept = all_cofs(all_cofs.size() - 1);
117 coeffs = all_cofs.head(all_cofs.size() - 1);
118 } else {
119 coeffs = all_cofs;
120 }
121
122 return { intercept, coeffs };
123}
124
125} // namespace detail
126} // namespace slope
Namespace containing SLOPE regression implementation.
Definition clusters.h:11