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
21template<class EigenVector_, class Matrix_, class Scale_>
22class ScaledWorkspace final : public Workspace<EigenVector_> {
23public:
24 ScaledWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
25 my_work(matrix.new_known_workspace()),
26 my_scale(scale),
27 my_column(column),
28 my_divide(divide)
29 {}
30
31private:
32 I<decltype(std::declval<Matrix_>().new_known_workspace())> my_work;
33 const Scale_& my_scale;
34 bool my_column;
35 bool my_divide;
36
37 EigenVector_ my_buffer;
38
39public:
40 void multiply(const EigenVector_& right, EigenVector_& out) {
41 if (my_column) {
42 if (my_divide) {
43 my_buffer = right.cwiseQuotient(my_scale);
44 } else {
45 my_buffer = right.cwiseProduct(my_scale);
46 }
47 my_work->multiply(my_buffer, out);
48
49 } else {
50 my_work->multiply(right, out);
51 if (my_divide) {
52 out.array() /= my_scale.array();
53 } else {
54 out.array() *= my_scale.array();
55 }
56 }
57 }
58};
59
60template<class EigenVector_, class Matrix_, class Scale_>
61class ScaledAdjointWorkspace final : public AdjointWorkspace<EigenVector_> {
62public:
63 ScaledAdjointWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
64 my_work(matrix.new_known_adjoint_workspace()),
65 my_scale(scale),
66 my_column(column),
67 my_divide(divide)
68 {}
69
70private:
71 I<decltype(std::declval<Matrix_>().new_known_adjoint_workspace())> my_work;
72 const Scale_& my_scale;
73 bool my_column;
74 bool my_divide;
75
76 EigenVector_ my_buffer;
77
78public:
79 void multiply(const EigenVector_& right, EigenVector_& out) {
80 if (my_column) {
81 my_work->multiply(right, out);
82 if (my_divide) {
83 out.array() /= my_scale.array();
84 } else {
85 out.array() *= my_scale.array();
86 }
87
88 } else {
89 if (my_divide) {
90 my_buffer = right.cwiseQuotient(my_scale);
91 } else {
92 my_buffer = right.cwiseProduct(my_scale);
93 }
94 my_work->multiply(my_buffer, out);
95 }
96 }
97};
98
99template<class EigenMatrix_, class Matrix_, class Scale_>
100class ScaledRealizeWorkspace final : public RealizeWorkspace<EigenMatrix_> {
101public:
102 ScaledRealizeWorkspace(const Matrix_& matrix, const Scale_& scale, const bool column, const bool divide) :
103 my_work(matrix.new_known_realize_workspace()),
104 my_scale(scale),
105 my_column(column),
106 my_divide(divide)
107 {}
108
109private:
110 I<decltype(std::declval<Matrix_>().new_known_realize_workspace())> my_work;
111 const Scale_& my_scale;
112 bool my_column;
113 bool my_divide;
114
115public:
116 const EigenMatrix_& realize(EigenMatrix_& buffer) {
117 my_work->realize_copy(buffer);
118
119 if (my_column) {
120 if (my_divide) {
121 buffer.array().rowwise() /= my_scale.adjoint().array();
122 } else {
123 buffer.array().rowwise() *= my_scale.adjoint().array();
124 }
125
126 } else {
127 if (my_divide) {
128 buffer.array().colwise() /= my_scale.array();
129 } else {
130 buffer.array().colwise() *= my_scale.array();
131 }
132 }
133
134 return buffer;
135 }
136};
156template<
157 class EigenVector_,
158 class EigenMatrix_,
159 class MatrixPointer_ = const Matrix<EigenVector_, EigenMatrix_>*,
160 class ScalePointer_ = const EigenVector_*
161>
162class ScaledMatrix final : public Matrix<EigenVector_, EigenMatrix_> {
163public:
173 ScaledMatrix(MatrixPointer_ matrix, ScalePointer_ scale, bool column, bool divide) :
174 my_matrix(std::move(matrix)),
175 my_scale(std::move(scale)),
176 my_column(column),
177 my_divide(divide)
178 {}
179
180private:
181 MatrixPointer_ my_matrix;
182 ScalePointer_ my_scale;
183 bool my_column;
184 bool my_divide;
185
186public:
187 Eigen::Index rows() const {
188 return my_matrix->rows();
189 }
190
191 Eigen::Index cols() const {
192 return my_matrix->cols();
193 }
194
195public:
196 std::unique_ptr<Workspace<EigenVector_> > new_workspace() const {
197 return new_known_workspace();
198 }
199
200 std::unique_ptr<AdjointWorkspace<EigenVector_> > new_adjoint_workspace() const {
201 return new_known_adjoint_workspace();
202 }
203
204 std::unique_ptr<RealizeWorkspace<EigenMatrix_> > new_realize_workspace() const {
205 return new_known_realize_workspace();
206 }
207
208public:
212 auto new_known_workspace() const {
213 return std::make_unique<ScaledWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
214 }
215
219 auto new_known_adjoint_workspace() const {
220 return std::make_unique<ScaledAdjointWorkspace<EigenVector_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
221 }
222
226 auto new_known_realize_workspace() const {
227 return std::make_unique<ScaledRealizeWorkspace<EigenMatrix_, I<decltype(*my_matrix)>, I<decltype(*my_scale)> > >(*my_matrix, *my_scale, my_column, my_divide);
228 }
229};
230
231}
232
233#endif
Interfaces for matrix inputs.