MUQ  0.4.3
PCEFactory.cpp
Go to the documentation of this file.
2 
4 
5 using namespace muq::Approximation;
6 using namespace muq::Modeling;
7 using namespace muq::Utilities;
8 
9 PCEFactory::PCEFactory(std::vector<std::shared_ptr<Quadrature>> const& quadTypesIn,
10  std::vector<std::shared_ptr<IndexedScalarBasis>> const& polyTypesIn) : quadTypes(quadTypesIn),
11  polyTypes(polyTypesIn),
12  tensQuad(quadTypes)
13 {
14  unsigned int dim = quadTypes.size();
15  assert(dim==polyTypesIn.size());
16 }
17 
18 
19 PCEFactory::PCEFactory(std::vector<std::shared_ptr<Quadrature>> const& quadTypesIn,
20  std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders,
21  std::vector<std::shared_ptr<IndexedScalarBasis>> const& polyTypesIn) : PCEFactory(quadTypesIn, polyTypesIn)
22 {
23  unsigned int dim = quadTypesIn.size();
24  assert(dim==quadOrders->GetLength());
25  assert(dim==polyTypesIn.size());
26 
27  Setup(quadOrders);
28 }
29 
30 void PCEFactory::Setup(std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders)
31 {
32  if(quadOrders==quadOrdersCache)
33  return;
34 
35  quadOrdersCache = quadOrders;
36 
37  unsigned int dim = quadOrders->GetLength();
38 
39  /* Create a multiindex set containing polynomials that can be integrated exactly
40  with a tensor product quadrature rule defined by quadOrders and quadTypesIn
41  */
42  Eigen::RowVectorXi orders(dim);
43  for(unsigned int i=0; i<dim; ++i)
44  orders(i) = std::floor( quadTypes.at(i)->Exactness(quadOrders->GetValue(i)) / 2.0);
45 
46  polyMultis = MultiIndexFactory::CreateFullTensor(orders);
47 
48  // Build the tensor product quadrature rule
49  tensQuad.Compute(quadOrders->GetVector());
51  quadPts.resize( tensQuad.Points().cols());
52  for(unsigned int i=0; i<quadPts.size(); ++i)
53  quadPts.at(i) = tensQuad.Points().col(i);
54 }
55 
56 PCEFactory::PCEFactory(std::vector<std::shared_ptr<Quadrature>> const& quadTypesIn,
57  std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders,
58  std::vector<std::shared_ptr<IndexedScalarBasis>> const& polyTypesIn,
59  std::shared_ptr<MultiIndexSet> const& polyMultisIn) : PCEFactory(quadTypesIn,polyTypesIn)
60 {
61  polyMultis = polyMultisIn;
62  Setup(quadOrders);
63 }
64 
65 std::shared_ptr<PolynomialChaosExpansion> PCEFactory::Compute(std::shared_ptr<muq::Modeling::ModPiece> const& model)
66 {
67  // Make sure the model has a single input and single output
68  assert(model->outputSizes.size()==1);
69  assert(model->inputSizes.size()==1);
70 
71  // Evaluate the model at the quadrature points
72  std::vector<Eigen::VectorXd> quadEvals(quadPts.size());
73  for(unsigned int k=0; k<quadPts.size(); ++k)
74  quadEvals.at(k) = model->Evaluate(quadEvals.at(k)).at(0);
75 
76  return Compute(quadEvals);
77 }
78 
79 std::shared_ptr<PolynomialChaosExpansion> PCEFactory::Compute(std::vector<Eigen::VectorXd> const& quadEvals,
80  std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders)
81 {
82  Setup(quadOrders);
83  return Compute(quadEvals);
84 }
85 
86 std::shared_ptr<PolynomialChaosExpansion> PCEFactory::Compute(std::vector<std::reference_wrapper<const Eigen::VectorXd>> const& quadEvals,
87  std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders)
88 {
89  Setup(quadOrders);
90  return Compute(quadEvals);
91 }
92 
93 std::shared_ptr<PolynomialChaosExpansion> PCEFactory::Compute(std::vector<Eigen::VectorXd> const& quadEvals)
94 {
95  std::vector<std::reference_wrapper<const Eigen::VectorXd>> refVec;
96  for(auto& eval : quadEvals)
97  refVec.push_back(std::ref(eval));
98 
99  return Compute(refVec);
100 }
101 
102 std::shared_ptr<PolynomialChaosExpansion> PCEFactory::Compute(std::vector<std::reference_wrapper<const Eigen::VectorXd>> const& quadEvals)
103 {
104  assert(quadEvals.size()==quadPts.size());
105  unsigned int outputDim = quadEvals.at(0).get().size();
106 
107  auto pce = std::make_shared<PolynomialChaosExpansion>(polyTypes, polyMultis, outputDim);
108 
109  // Compute all of the coefficients
110  Eigen::MatrixXd coeffs = Eigen::MatrixXd::Zero(quadEvals.at(0).get().size(), polyMultis->Size());
111 
112  // Estimate the projection c_{ij} = <\psi_j, f_i> = \sum_{k=1}^N w_k \psi_j(x_k) f_i(x_k)
113  for(unsigned int k=0; k<quadPts.size(); ++k)
114  coeffs += quadWts(k) * quadEvals.at(k).get() * pce->BuildVandermonde(quadPts.at(k));
115 
116  Eigen::VectorXd allNorms = pce->GetNormalizationVec().array().square().matrix();
117  coeffs = (coeffs.array().rowwise() / allNorms.transpose().array()).eval();
118 
119  pce->SetCoeffs(coeffs);
120 
121  return pce;
122 }
123 
124 
125 std::vector<Eigen::VectorXd> const& PCEFactory::QuadPts(std::shared_ptr<muq::Utilities::MultiIndex> const& quadOrders)
126 {
127  Setup(quadOrders);
128  return QuadPts();
129 }
virtual void Compute(unsigned int order) override
Factory class for constructing a pseudo-spectral polynomial chaos approximation using a fixed quadrat...
Definition: PCEFactory.h:22
std::shared_ptr< muq::Utilities::MultiIndex > quadOrdersCache
Definition: PCEFactory.h:119
FullTensorQuadrature tensQuad
Definition: PCEFactory.h:124
PCEFactory(std::vector< std::shared_ptr< Quadrature >> const &quadTypesIn, std::vector< std::shared_ptr< IndexedScalarBasis >> const &polyTypesIn)
Definition: PCEFactory.cpp:9
std::vector< Eigen::VectorXd > const & QuadPts() const
Definition: PCEFactory.h:107
void Setup(std::shared_ptr< muq::Utilities::MultiIndex > const &quadOrders)
Definition: PCEFactory.cpp:30
std::vector< Eigen::VectorXd > quadPts
Definition: PCEFactory.h:128
std::shared_ptr< PolynomialChaosExpansion > Compute(std::shared_ptr< muq::Modeling::ModPiece > const &model)
Definition: PCEFactory.cpp:65
std::vector< std::shared_ptr< Quadrature > > quadTypes
Definition: PCEFactory.h:122
std::shared_ptr< muq::Utilities::MultiIndexSet > polyMultis
Definition: PCEFactory.h:126
std::vector< std::shared_ptr< IndexedScalarBasis > > polyTypes
Definition: PCEFactory.h:123
virtual Eigen::MatrixXd const & Points() const
Definition: Quadrature.h:161
virtual Eigen::VectorXd const & Weights() const
Definition: Quadrature.h:165