slope 0.29.0
Loading...
Searching...
No Matches
math.cpp
1#include "math.h"
2#include "constants.h"
3
4namespace slope {
5
6Eigen::VectorXd
7logSumExp(const Eigen::MatrixXd& a)
8{
9 Eigen::VectorXd max_vals = a.rowwise().maxCoeff();
10 Eigen::ArrayXd sum_exp =
11 (a.colwise() - max_vals).array().exp().rowwise().sum();
12
13 return max_vals.array() + sum_exp.max(constants::P_MIN).log();
14}
15
16Eigen::MatrixXd
17softmax(const Eigen::MatrixXd& a)
18{
19 Eigen::VectorXd shift = a.rowwise().maxCoeff();
20 Eigen::MatrixXd exp_a = (a.colwise() - shift).array().exp();
21 Eigen::ArrayXd row_sums = exp_a.rowwise().sum();
22 return exp_a.array().colwise() / row_sums;
23}
24
25std::vector<int>
26setUnion(const std::vector<int>& a, const std::vector<int>& b)
27{
28 std::vector<int> out;
29 std::set_union(
30 a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(out));
31
32 return out;
33}
34
35std::vector<int>
36setDiff(const std::vector<int>& a, const std::vector<int>& b)
37{
38 std::vector<int> out;
39 std::set_difference(
40 a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(out));
41
42 return out;
43}
44
45Eigen::ArrayXd
46geomSpace(const double start, const double end, const int n)
47{
48 if (n == 1) {
49 return Eigen::ArrayXd::Constant(1, start);
50 } else {
51 return Eigen::ArrayXd::LinSpaced(n, std::log(start), std::log(end)).exp();
52 }
53}
54
55Eigen::VectorXd
56l2Norms(const Eigen::SparseMatrix<double>& x)
57{
58 const int p = x.cols();
59
60 Eigen::VectorXd out(p);
61
62 for (int j = 0; j < p; ++j) {
63 out(j) = x.col(j).norm();
64 }
65
66 return out;
67}
68
69Eigen::VectorXd
70l2Norms(const Eigen::MatrixXd& x)
71{
72 return x.colwise().norm();
73}
74
75Eigen::VectorXd
76means(const Eigen::SparseMatrix<double>& x)
77{
78 const int n = x.rows();
79 const int p = x.cols();
80
81 Eigen::VectorXd out(p);
82
83 for (int j = 0; j < p; ++j) {
84 out(j) = x.col(j).sum() / n;
85 }
86
87 return out;
88}
89
90Eigen::VectorXd
91means(const Eigen::MatrixXd& x)
92{
93 return x.colwise().mean();
94}
95
96Eigen::VectorXd
97ranges(const Eigen::SparseMatrix<double>& x)
98{
99 const int p = x.cols();
100
101 Eigen::VectorXd out(p);
102
103 for (int j = 0; j < p; ++j) {
104 double x_j_max = 0.0;
105 double x_j_min = 0.0;
106
107 for (typename Eigen::SparseMatrix<double>::InnerIterator it(x, j); it;
108 ++it) {
109 x_j_max = std::max(x_j_max, it.value());
110 x_j_min = std::min(x_j_min, it.value());
111 }
112
113 out(j) = x_j_max - x_j_min;
114 }
115
116 return out;
117}
118
119Eigen::VectorXd
120ranges(const Eigen::MatrixXd& x)
121{
122 return x.colwise().maxCoeff() - x.colwise().minCoeff();
123}
124
125Eigen::VectorXd
126maxAbs(const Eigen::SparseMatrix<double>& x)
127{
128 const int p = x.cols();
129
130 Eigen::VectorXd out(p);
131
132 for (int j = 0; j < p; ++j) {
133 double x_j_maxabs = 0.0;
134
135 for (typename Eigen::SparseMatrix<double>::InnerIterator it(x, j); it;
136 ++it) {
137 x_j_maxabs = std::max(x_j_maxabs, std::abs(it.value()));
138 }
139
140 out(j) = x_j_maxabs;
141 }
142
143 return out;
144}
145
146Eigen::VectorXd
147maxAbs(const Eigen::MatrixXd& x)
148{
149 return x.cwiseAbs().colwise().maxCoeff();
150}
151
152Eigen::VectorXd
153mins(const Eigen::SparseMatrix<double>& x)
154{
155 const int p = x.cols();
156
157 Eigen::VectorXd out(p);
158
159 for (int j = 0; j < p; ++j) {
160 double x_j_min = 0.0;
161
162 for (typename Eigen::SparseMatrix<double>::InnerIterator it(x, j); it;
163 ++it) {
164 x_j_min = std::min(x_j_min, it.value());
165 }
166
167 out(j) = x_j_min;
168 }
169
170 return out;
171}
172
173Eigen::VectorXd
174mins(const Eigen::MatrixXd& x)
175{
176 return x.colwise().minCoeff();
177}
178
179Eigen::VectorXd
180stdDevs(const Eigen::SparseMatrix<double>& x)
181{
182 const int n = x.rows();
183 const int p = x.cols();
184
185 Eigen::VectorXd x_means = means(x);
186 Eigen::VectorXd out(p);
187
188 for (int j = 0; j < p; ++j) {
189 double sum_sq_diff = 0.0;
190 const double mean = x_means(j);
191
192 // Process non-zero elements
193 for (Eigen::SparseMatrix<double>::InnerIterator it(x, j); it; ++it) {
194 double diff = it.value() - mean;
195 sum_sq_diff += diff * diff;
196 }
197
198 // Account for zeros
199 int nz_count = x.col(j).nonZeros();
200 if (nz_count < n) {
201 sum_sq_diff += (n - nz_count) * mean * mean;
202 }
203
204 // Standard deviation is sqrt of the average of squared differences
205 out(j) = std::sqrt(sum_sq_diff / n);
206 }
207
208 return out;
209}
210
211Eigen::VectorXd
212stdDevs(const Eigen::MatrixXd& x)
213{
214 int n = x.rows();
215 int p = x.cols();
216
217 Eigen::VectorXd x_means = means(x);
218 Eigen::VectorXd out(p);
219
220 for (int j = 0; j < p; ++j) {
221 out(j) = (x.col(j).array() - x_means(j)).matrix().norm();
222 }
223
224 out.array() /= std::sqrt(n);
225
226 return out;
227}
228
229} // namespace slope
Definitions of constants used in libslope.
Mathematical support functions for the slope package.
constexpr double P_MIN
Minimum allowed probability value to avoid numerical underflow.
Definition constants.h:30
Namespace containing SLOPE regression implementation.
Definition clusters.cpp:5
Eigen::VectorXd maxAbs(const Eigen::SparseMatrix< double > &x)
Computes the maximum absolute value for each column of a matrix.
Definition math.cpp:126
Eigen::VectorXd means(const Eigen::SparseMatrix< double > &x)
Computes the arithmetic mean for each column of a sparse matrix.
Definition math.cpp:76
Eigen::VectorXd logSumExp(const Eigen::MatrixXd &a)
Definition math.cpp:7
Eigen::MatrixXd softmax(const Eigen::MatrixXd &a)
Definition math.cpp:17
std::vector< int > setDiff(const std::vector< int > &a, const std::vector< int > &b)
Computes the set difference of two sorted integer vectors.
Definition math.cpp:36
Eigen::VectorXd stdDevs(const Eigen::SparseMatrix< double > &x)
Computes the standard deviation for each column of a matrix.
Definition math.cpp:180
std::vector< int > setUnion(const std::vector< int > &a, const std::vector< int > &b)
Computes the union of two sorted integer vectors.
Definition math.cpp:26
Eigen::VectorXd ranges(const Eigen::SparseMatrix< double > &x)
Computes the range (max - min) for each column of a matrix.
Definition math.cpp:97
Eigen::VectorXd l2Norms(const Eigen::SparseMatrix< double > &x)
Computes the L2 (Euclidean) norms for each column of a sparse matrix.
Definition math.cpp:56
Eigen::VectorXd mins(const Eigen::SparseMatrix< double > &x)
Computes the minimum value for each column of a sparse matrix.
Definition math.cpp:153
Eigen::ArrayXd geomSpace(const double start, const double end, const int n)
Creates an array of n numbers in geometric progression from start to end.
Definition math.cpp:46