irlba
A C++ library for IRLBA
Loading...
Searching...
No Matches
scaled.hpp
Go to the documentation of this file.
1#ifndef IRLBA_MATRIX_SCALED_HPP
2#define IRLBA_MATRIX_SCALED_HPP
3
4#include <memory>
5
6#include "../utils.hpp"
7#include "interface.hpp"
8
9#include "Eigen/Dense"
10
16namespace irlba {
17
27template<class EigenVector_, class Matrix_, class Scale_>
28class ScaledWorkspace final : public Workspace<EigenVector_> {
29public:
33 ScaledWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
34 my_work(matrix.new_known_workspace()),
35 my_scale(scale),
36 my_column(column),
37 my_divide(divide)
38 {}
43private:
44 I<decltype(std::declval<Matrix_>().new_known_workspace())> my_work;
45 const Scale_& my_scale;
46 bool my_column;
47 bool my_divide;
48
49 EigenVector_ my_buffer;
50
51public:
52 void multiply(const EigenVector_& right, EigenVector_& out) {
53 if (my_column) {
54 if (my_divide) {
55 my_buffer = right.cwiseQuotient(my_scale);
56 } else {
57 my_buffer = right.cwiseProduct(my_scale);
58 }
59 my_work->multiply(my_buffer, out);
60
61 } else {
62 my_work->multiply(right, out);
63 if (my_divide) {
64 out.array() /= my_scale.array();
65 } else {
66 out.array() *= my_scale.array();
67 }
68 }
69 }
70};
71
81template<class EigenVector_, class Matrix_, class Scale_>
82class ScaledAdjointWorkspace final : public AdjointWorkspace<EigenVector_> {
83public:
87 ScaledAdjointWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
88 my_work(matrix.new_known_adjoint_workspace()),
89 my_scale(scale),
90 my_column(column),
91 my_divide(divide)
92 {}
97private:
98 I<decltype(std::declval<Matrix_>().new_known_adjoint_workspace())> my_work;
99 const Scale_& my_scale;
100 bool my_column;
101 bool my_divide;
102
103 EigenVector_ my_buffer;
104
105public:
106 void multiply(const EigenVector_& right, EigenVector_& out) {
107 if (my_column) {
108 my_work->multiply(right, out);
109 if (my_divide) {
110 out.array() /= my_scale.array();
111 } else {
112 out.array() *= my_scale.array();
113 }
114
115 } else {
116 if (my_divide) {
117 my_buffer = right.cwiseQuotient(my_scale);
118 } else {
119 my_buffer = right.cwiseProduct(my_scale);
120 }
121 my_work->multiply(my_buffer, out);
122 }
123 }
124};
125
135template<class EigenMatrix_, class Matrix_, class Scale_>
136class ScaledRealizeWorkspace final : public RealizeWorkspace<EigenMatrix_> {
137public:
141 ScaledRealizeWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
142 my_work(matrix.new_known_realize_workspace()),
143 my_scale(scale),
144 my_column(column),
145 my_divide(divide)
146 {}
151private:
152 I<decltype(std::declval<Matrix_>().new_known_realize_workspace())> my_work;
153 const Scale_& my_scale;
154 bool my_column;
155 bool my_divide;
156
157public:
158 const EigenMatrix_& realize(EigenMatrix_& buffer) {
159 my_work->realize_copy(buffer);
160
161 if (my_column) {
162 if (my_divide) {
163 buffer.array().rowwise() /= my_scale.adjoint().array();
164 } else {
165 buffer.array().rowwise() *= my_scale.adjoint().array();
166 }
167
168 } else {
169 if (my_divide) {
170 buffer.array().colwise() /= my_scale.array();
171 } else {
172 buffer.array().colwise() *= my_scale.array();
173 }
174 }
175
176 return buffer;
177 }
178};
179
195template<
196 class EigenVector_,
197 class EigenMatrix_,
198 class MatrixPointer_ = const Matrix<EigenVector_, EigenMatrix_>*,
199 class ScalePointer_ = const EigenVector_*
200>
201class ScaledMatrix final : public Matrix<EigenVector_, EigenMatrix_> {
202public:
212 ScaledMatrix(MatrixPointer_ matrix, ScalePointer_ scale, bool column, bool divide) :
213 my_matrix(std::move(matrix)),
214 my_scale(std::move(scale)),
215 my_column(column),
216 my_divide(divide)
217 {}
218
219private:
220 MatrixPointer_ my_matrix;
221 ScalePointer_ my_scale;
222 bool my_column;
223 bool my_divide;
224
225public:
226 Eigen::Index rows() const {
227 return my_matrix->rows();
228 }
229
230 Eigen::Index cols() const {
231 return my_matrix->cols();
232 }
233
234public:
235 std::unique_ptr<Workspace<EigenVector_> > new_workspace() const {
236 return new_known_workspace();
237 }
238
239 std::unique_ptr<AdjointWorkspace<EigenVector_> > new_adjoint_workspace() const {
241 }
242
243 std::unique_ptr<RealizeWorkspace<EigenMatrix_> > new_realize_workspace() const {
245 }
246
247public:
251 std::unique_ptr<ScaledWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > > new_known_workspace() const {
252 return std::make_unique<ScaledWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
253 }
254
258 std::unique_ptr<ScaledAdjointWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > > new_known_adjoint_workspace() const {
259 return std::make_unique<ScaledAdjointWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
260 }
261
265 std::unique_ptr<ScaledRealizeWorkspace<EigenMatrix_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > > new_known_realize_workspace() const {
266 return std::make_unique<ScaledRealizeWorkspace<EigenMatrix_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
267 }
268};
269
270}
271
272#endif
Workspace class for multiplying a transposed Matrix.
Definition interface.hpp:61
Interface for a matrix to use in compute().
Definition interface.hpp:142
Workspace class for realizing a Matrix.
Definition interface.hpp:99
Workspace class for multiplying a transposed ScaledMatrix.
Definition scaled.hpp:82
void multiply(const EigenVector_ &right, EigenVector_ &out)
Definition scaled.hpp:106
Deferred scaling of a matrix.
Definition scaled.hpp:201
std::unique_ptr< ScaledRealizeWorkspace< EigenMatrix_, I< decltype(*my_matrix)>, I< decltype(*my_scale)> > > new_known_realize_workspace() const
Definition scaled.hpp:265
std::unique_ptr< RealizeWorkspace< EigenMatrix_ > > new_realize_workspace() const
Definition scaled.hpp:243
Eigen::Index cols() const
Definition scaled.hpp:230
ScaledMatrix(MatrixPointer_ matrix, ScalePointer_ scale, bool column, bool divide)
Definition scaled.hpp:212
std::unique_ptr< ScaledWorkspace< EigenVector_, I< decltype(*my_matrix)>, I< decltype(*my_scale)> > > new_known_workspace() const
Definition scaled.hpp:251
std::unique_ptr< AdjointWorkspace< EigenVector_ > > new_adjoint_workspace() const
Definition scaled.hpp:239
std::unique_ptr< ScaledAdjointWorkspace< EigenVector_, I< decltype(*my_matrix)>, I< decltype(*my_scale)> > > new_known_adjoint_workspace() const
Definition scaled.hpp:258
Eigen::Index rows() const
Definition scaled.hpp:226
std::unique_ptr< Workspace< EigenVector_ > > new_workspace() const
Definition scaled.hpp:235
Workspace class for realizing a ScaledMatrix.
Definition scaled.hpp:136
const EigenMatrix_ & realize(EigenMatrix_ &buffer)
Definition scaled.hpp:158
Workspace class for multiplying a ScaledMatrix.
Definition scaled.hpp:28
void multiply(const EigenVector_ &right, EigenVector_ &out)
Definition scaled.hpp:52
Workspace class for multiplying a Matrix.
Definition interface.hpp:24
Interfaces for matrix inputs.
Implements IRLBA for approximate SVD.
Definition compute.hpp:22