13 PolynomialChaosExpansion::PolynomialChaosExpansion(std::shared_ptr<OrthogonalPolynomial>
const& basisCompsIn,
14 std::shared_ptr<muq::Utilities::MultiIndexSet>
const& multisIn,
21 std::shared_ptr<muq::Utilities::MultiIndexSet>
const& multisIn,
28 std::shared_ptr<muq::Utilities::MultiIndexSet>
const& multisIn,
29 Eigen::MatrixXd
const& coeffsIn) :
BasisExpansion(basisCompsIn, multisIn, coeffsIn)
34 std::shared_ptr<muq::Utilities::MultiIndexSet>
const& multisIn,
35 unsigned int outputDim) :
BasisExpansion(basisCompsIn, multisIn, Eigen::MatrixXd::Zero(outputDim, multisIn->Size()))
42 Eigen::VectorXd result = Eigen::VectorXd::Zero(
multis->Size());
45 for (
unsigned int i = 0; i <
multis->Size(); i++) {
49 Eigen::RowVectorXi multi =
multis->IndexToMulti(i)->GetVector();
50 for(
int k=0;
k<multi.size(); ++
k){
51 norm *= std::dynamic_pointer_cast<OrthogonalPolynomial>(
basisComps.at(
k))->Normalization(multi(
k));
53 result(i) = std::sqrt(norm);
65 if (normalVec.rows() <= 1) {
66 return Eigen::VectorXd::Zero(
coeffs.rows());
69 Eigen::VectorXd squareNorm = normalVec.tail(normalVec.rows() - 1).array().square();
76 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
77 dimMeasures(i) = std::dynamic_pointer_cast<OrthogonalPolynomial>(
basisComps.at(i))->Normalization(0);
81 return coeffs.rightCols(
coeffs.cols() - 1).array().square().matrix() * squareNorm / dimMeasures.prod();
89 if (normalVec.rows() <= 1) {
90 return Eigen::MatrixXd::Zero(
coeffs.rows(),
coeffs.rows());
93 Eigen::VectorXd squareNorm = normalVec.tail(normalVec.rows() - 1).array().square();
100 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
101 dimMeasures(i) = std::dynamic_pointer_cast<OrthogonalPolynomial>(
basisComps.at(i))->Normalization(0);
103 Eigen::VectorXd quadVec = squareNorm / dimMeasures.prod();
107 int npolys =
coeffs.cols();
110 cov(i,j) =
coeffs.row(j).tail(npolys - 1) * quadVec.asDiagonal() *
coeffs.row(i).tail(npolys - 1).transpose();
129 return (
coeffs.array().square().matrix() * normalVec.array().square().matrix()).array().sqrt();
135 Eigen::VectorXd
const& weights,
136 std::shared_ptr<MultiIndexSet>
const& polynomials,
137 std::vector<std::vector<unsigned int>>
const& locToGlob)
139 std::shared_ptr<PolynomialChaosExpansion> firstNonNull;
140 for(
unsigned int i=0; i<expansions.size();++i){
141 if(expansions.at(i) !=
nullptr) {
142 firstNonNull = expansions.at(i);
146 assert(firstNonNull);
149 Eigen::MatrixXd newCoeffs = Eigen::MatrixXd::Zero(firstNonNull->outputSizes(0), polynomials->Size());
151 for(
unsigned int i=0; i<expansions.size(); ++i){
152 if(std::abs(weights(i))>10.0*std::numeric_limits<double>::epsilon()){
153 for(
unsigned int k=0;
k<expansions.at(i)->
coeffs.cols(); ++
k){
154 newCoeffs.col(locToGlob.at(i).at(
k)) += weights(i)*expansions.at(i)->coeffs.col(
k);
159 return std::make_shared<PolynomialChaosExpansion>(firstNonNull->basisComps, polynomials, newCoeffs);
163 Eigen::VectorXd
const& weights)
165 assert(weights.size()==expansions.size());
167 std::shared_ptr<PolynomialChaosExpansion> firstNonNull;
168 for(
unsigned int i=0; i<expansions.size();++i){
169 if(expansions.at(i) !=
nullptr) {
170 firstNonNull = expansions.at(i);
174 assert(firstNonNull);
176 unsigned int inputDim = firstNonNull->inputSizes(0);
177 unsigned int outputDim = firstNonNull->outputSizes(0);
180 auto allPolynomials = std::make_shared<MultiIndexSet>(inputDim);
183 std::vector<std::vector<unsigned int>> locToGlob(weights.size());
186 for(
int j=0; j<expansions.size(); ++j)
189 if(std::abs(weights(j))>10.0*std::numeric_limits<double>::epsilon()){
190 assert(expansions.at(j));
193 unsigned int numTerms = expansions.at(j)->multis->Size();
194 locToGlob.at(j).resize(numTerms);
195 for (
unsigned int i = 0; i < numTerms; ++i)
196 locToGlob.at(j).at(i) = allPolynomials->AddActive(expansions.at(j)->multis->IndexToMulti(i));
211 for (
unsigned int i = 0; i <
multis->Size(); ++i){
212 if(
multis->IndexToMulti(i)->GetValue(targetDim)==0)
217 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
218 dimMeasures(i) = std::dynamic_pointer_cast<OrthogonalPolynomial>(
basisComps.at(i))->Normalization(0);
222 return (
coeffs.array().square().matrix() * normalVec.array().square().matrix()).array() / dimMeasures.prod() /
Variance().array();
229 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
242 Eigen::ArrayXd contributesToIndex = Eigen::VectorXd::Zero(
NumTerms());
245 for(
unsigned int i=0; i<
multis->Size(); ++i){
246 auto currMulti =
multis->IndexToMulti(i);
247 int miSum = currMulti->Sum();
250 for(
auto&
k : targetDims)
251 partSum += currMulti->GetValue(
k);
253 if((miSum>0)&&(partSum==miSum)){
254 contributesToIndex(i) = 1;
262 Eigen::VectorXd filterdVec = normalVec.array() * contributesToIndex;
265 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
266 dimMeasures(i) = std::dynamic_pointer_cast<OrthogonalPolynomial>(
basisComps.at(i))->Normalization(0);
270 return (
coeffs.array().square().matrix() * filterdVec.array().square().matrix()).array() / dimMeasures.prod() /
Variance().array();
277 for (
unsigned int i = 0; i <
inputSizes(0); ++i)
287 group.
attrs[
"expansion_type"] =
"PCE";
292 std::shared_ptr<PolynomialChaosExpansion> output = std::dynamic_pointer_cast<PolynomialChaosExpansion>(
BasisExpansion::FromHDF5(filename,groupName));
294 throw std::runtime_error(
"Could not read PolynomialChaosExpansion from group \"" + groupName +
"\". HDF5 file does not seem to contain a PCE. Is the \"expansion_type\" attribute set to \"PCE\"?");
300 std::shared_ptr<PolynomialChaosExpansion> output = std::dynamic_pointer_cast<PolynomialChaosExpansion>(
BasisExpansion::FromHDF5(group));
302 throw std::runtime_error(
"Could not read PolynomialChaosExpansion from group \"" + group.
Path() +
"\". HDF5 file does not seem to contain a PCE. Is the \"expansion_type\" attribute set to \"PCE\"?");
Class for defining expansions of basis functions defined by a MultiIndexSet and collection of IndexSc...
std::shared_ptr< muq::Utilities::MultiIndexSet > multis
static std::shared_ptr< BasisExpansion > FromHDF5(std::string filename, std::string groupName="/")
Loads an expansion from an HDF5 file.
virtual unsigned NumTerms() const
std::vector< std::shared_ptr< IndexedScalarBasis > > basisComps
virtual void ToHDF5(std::string filename, std::string groupName="/") const
Saves the expansion to group in an HDF5 file.
A class for representing and using expansions of orthogonal multivariate polynomials.
static std::shared_ptr< PolynomialChaosExpansion > FromHDF5(std::string filename, std::string groupName="/")
Loads an expansion from an HDF5 file.
Eigen::MatrixXd Covariance() const
Eigen::VectorXd Mean() const
Eigen::VectorXd GetNormalizationVec() const
Eigen::VectorXd Variance() const
compute the variance of the current expansion
Eigen::VectorXd Magnitude() const
Compute the L2 norm of each output.
static std::shared_ptr< PolynomialChaosExpansion > ComputeWeightedSum(std::vector< std::shared_ptr< PolynomialChaosExpansion >> expansions, Eigen::VectorXd const &weights)
Eigen::MatrixXd TotalSensitivity() const
Compute all Sobol total sensitivities. Rows are outputs, each column is an input.
PolynomialChaosExpansion(std::shared_ptr< OrthogonalPolynomial > const &basisCompsIn, std::shared_ptr< muq::Utilities::MultiIndexSet > const &multisIn, Eigen::MatrixXd const &coeffsIn)
virtual void ToHDF5(muq::Utilities::H5Object &group) const override
Write PCE to HDF5 file.
Eigen::MatrixXd MainSensitivity() const
Eigen::VectorXd SobolSensitivity(unsigned int targetDim) const
Compute the main sensitivity index for the input dimension, for each output dimension.
const Eigen::VectorXi inputSizes
const Eigen::VectorXi outputSizes