MUQ  0.4.3
KroneckerProductOperator.cpp
Go to the documentation of this file.
2 
5 
6 using namespace muq::Modeling;
7 
8 KroneckerProductOperator::KroneckerProductOperator(std::shared_ptr<LinearOperator> Ain,
9  std::shared_ptr<LinearOperator> Bin) : LinearOperator(Ain->rows()*Bin->rows(), Ain->cols()*Bin->cols()), A(Ain), B(Bin)
10 {
11 
12 }
13 
14 Eigen::MatrixXd KroneckerProductOperator::Apply(Eigen::Ref<const Eigen::MatrixXd> const& x)
15 {
16 
17  Eigen::MatrixXd output(nrows, x.cols());
18 
19  for(int i=0; i<x.cols(); ++i)
20  {
21  Eigen::VectorXd xVec = x.col(i);
22  Eigen::Map<Eigen::MatrixXd> xMat(xVec.data(), B->cols(), A->cols());
23  Eigen::Map<Eigen::MatrixXd> bMat(&output(0,i), B->rows(), A->rows());
24 
25  bMat = A->Apply( B->Apply( xMat ).transpose() ).transpose();
26  }
27 
28  return output;
29 }
30 
31 
32 
33 Eigen::MatrixXd KroneckerProductOperator::ApplyTranspose(Eigen::Ref<const Eigen::MatrixXd> const& x)
34 {
35  Eigen::MatrixXd output(ncols, x.cols());
36 
37  for(int i=0; i<x.cols(); ++i)
38  {
39  Eigen::VectorXd xVec = x.col(i);
40  Eigen::Map<const Eigen::MatrixXd> xMat(xVec.data(), B->rows(), A->rows());
41  Eigen::Map<Eigen::MatrixXd> bMat(&output(0,i), B->cols(), A->cols());
42 
43  bMat = A->ApplyTranspose( B->ApplyTranspose( xMat ).transpose() ).transpose();
44  }
45 
46  return output;
47 }
48 
49 
50 std::shared_ptr<LinearOperator> muq::Modeling::KroneckerSum(std::shared_ptr<LinearOperator> A,
51  std::shared_ptr<LinearOperator> B)
52 {
53  auto part1 = std::make_shared<KroneckerProductOperator>(A, std::make_shared<IdentityOperator>(B->cols()));
54  auto part2 = std::make_shared<KroneckerProductOperator>(std::make_shared<IdentityOperator>(A->rows()), B);
55 
56  return std::make_shared<SumOperator>(part1, part2);
57 }
58 
59 
60 Eigen::MatrixXd muq::Modeling::KroneckerProduct(Eigen::Ref<const Eigen::MatrixXd> const& A,
61  Eigen::Ref<const Eigen::MatrixXd> const& B)
62 {
63  Eigen::MatrixXd output(A.rows()*B.rows(), A.cols()*B.cols());
64  for(int j=0; j<A.cols(); ++j)
65  {
66  for(int i=0; i<A.rows(); ++i)
67  {
68  output.block(i*B.rows(), j*B.cols(), B.rows(), B.cols()) = A(i,j)*B;
69  }
70  }
71  return output;
72 }
KroneckerProductOperator(std::shared_ptr< LinearOperator > Ain, std::shared_ptr< LinearOperator > Bin)
virtual Eigen::MatrixXd Apply(Eigen::Ref< const Eigen::MatrixXd > const &x) override
Generic linear operator base class.
virtual Eigen::MatrixXd ApplyTranspose(Eigen::Ref< const Eigen::MatrixXd > const &x)=0
Eigen::MatrixXd KroneckerProduct(Eigen::Ref< const Eigen::MatrixXd > const &A, Eigen::Ref< const Eigen::MatrixXd > const &B)
std::shared_ptr< LinearOperator > KroneckerSum(std::shared_ptr< LinearOperator > A, std::shared_ptr< LinearOperator > B)