1#ifndef IRLBA_MATRIX_SCALED_HPP
2#define IRLBA_MATRIX_SCALED_HPP
21template<
class EigenVector_,
class Matrix_,
class Scale_>
22class ScaledWorkspace final :
public Workspace<EigenVector_> {
24 ScaledWorkspace(
const Matrix_& matrix,
const Scale_& scale,
const bool column,
const bool divide) :
25 my_work(matrix.new_known_workspace()),
32 I<decltype(std::declval<Matrix_>().new_known_workspace())> my_work;
33 const Scale_& my_scale;
37 EigenVector_ my_buffer;
40 void multiply(
const EigenVector_& right, EigenVector_& out) {
43 my_buffer = right.cwiseQuotient(my_scale);
45 my_buffer = right.cwiseProduct(my_scale);
47 my_work->multiply(my_buffer, out);
50 my_work->multiply(right, out);
52 out.array() /= my_scale.array();
54 out.array() *= my_scale.array();
60template<
class EigenVector_,
class Matrix_,
class Scale_>
61class ScaledAdjointWorkspace final :
public AdjointWorkspace<EigenVector_> {
63 ScaledAdjointWorkspace(
const Matrix_& matrix,
const Scale_& scale,
const bool column,
const bool divide) :
64 my_work(matrix.new_known_adjoint_workspace()),
71 I<decltype(std::declval<Matrix_>().new_known_adjoint_workspace())> my_work;
72 const Scale_& my_scale;
76 EigenVector_ my_buffer;
79 void multiply(
const EigenVector_& right, EigenVector_& out) {
81 my_work->multiply(right, out);
83 out.array() /= my_scale.array();
85 out.array() *= my_scale.array();
90 my_buffer = right.cwiseQuotient(my_scale);
92 my_buffer = right.cwiseProduct(my_scale);
94 my_work->multiply(my_buffer, out);
99template<
class EigenMatrix_,
class Matrix_,
class Scale_>
100class ScaledRealizeWorkspace final :
public RealizeWorkspace<EigenMatrix_> {
102 ScaledRealizeWorkspace(
const Matrix_& matrix,
const Scale_& scale,
const bool column,
const bool divide) :
103 my_work(matrix.new_known_realize_workspace()),
110 I<decltype(std::declval<Matrix_>().new_known_realize_workspace())> my_work;
111 const Scale_& my_scale;
116 const EigenMatrix_& realize(EigenMatrix_& buffer) {
117 my_work->realize_copy(buffer);
121 buffer.array().rowwise() /= my_scale.adjoint().array();
123 buffer.array().rowwise() *= my_scale.adjoint().array();
128 buffer.array().colwise() /= my_scale.array();
130 buffer.array().colwise() *= my_scale.array();
159 class MatrixPointer_ =
const Matrix<EigenVector_, EigenMatrix_>*,
160 class ScalePointer_ =
const EigenVector_*
162class ScaledMatrix final :
public Matrix<EigenVector_, EigenMatrix_> {
173 ScaledMatrix(MatrixPointer_ matrix, ScalePointer_ scale,
bool column,
bool divide) :
174 my_matrix(std::move(matrix)),
175 my_scale(std::move(scale)),
181 MatrixPointer_ my_matrix;
182 ScalePointer_ my_scale;
187 Eigen::Index rows()
const {
188 return my_matrix->rows();
191 Eigen::Index cols()
const {
192 return my_matrix->cols();
196 std::unique_ptr<Workspace<EigenVector_> > new_workspace()
const {
197 return new_known_workspace();
200 std::unique_ptr<AdjointWorkspace<EigenVector_> > new_adjoint_workspace()
const {
201 return new_known_adjoint_workspace();
204 std::unique_ptr<RealizeWorkspace<EigenMatrix_> > new_realize_workspace()
const {
205 return new_known_realize_workspace();
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);
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);
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);
Interfaces for matrix inputs.