19 Discretization::Discretization(std::size_t
const numCells) :
22 nodeLocs(Eigen::VectorXd::LinSpaced(numCells+1, -1.0, 1.0)),
23 cellLocs(0.5*(nodeLocs.tail(numCells) + nodeLocs.head(numCells)))
26 Data::Data(Eigen::VectorXd
const& x, Eigen::VectorXd
const& soln, Eigen::VectorXd
const& obsLoc, Eigen::VectorXd
const& obs) :
34 return (M_PI*mesh.cellLocs).array().cos() + (3.0*M_PI*mesh.cellLocs).array().sin();
38 return Eigen::VectorXd::Ones(mesh.cellLocs.size());
41 std::shared_ptr<LinearOperator>
InterpolateOntoObs(Discretization
const& mesh, Eigen::VectorXd
const& obsLoc) {
42 Eigen::MatrixXd A = Eigen::MatrixXd::Zero(obsLoc.size(), mesh.numNodes);
44 for( std::size_t i=0; i<obsLoc.size(); ++i ) {
45 while( mesh.nodeLocs(j+1)<obsLoc(i) ) { ++j; }
46 assert(j<mesh.numNodes-1);
47 assert(obsLoc(i)>mesh.nodeLocs(j)-1.0e-14);
48 assert(obsLoc(i)<mesh.nodeLocs(j+1)+1.0e-14);
50 A(i, j) = (mesh.nodeLocs(j+1)-obsLoc(i))/(mesh.nodeLocs(j+1)-mesh.nodeLocs(j));
51 assert(A(i, j)>-1.0e-14); assert(A(i, j)<1.0+1.0e-14);
52 A(i, j+1) = 1.0-A(i, j);
55 return LinearOperator::Create(A);
58 Data GenerateData(std::size_t
const numCells, std::size_t
const numObs,
double const obsVar) {
59 const Discretization mesh(numCells);
64 auto mod = std::make_shared<FlowEquation>(recharge);
65 const Eigen::VectorXd obsLoc = Eigen::VectorXd::LinSpaced(numObs, -1.0, 1.0);
69 const Eigen::VectorXd trueSol = mod->Evaluate(trueCond).at(0);
70 return Data(mesh.nodeLocs, trueSol, obsLoc, interp->Evaluate(trueSol).at(0) + std::sqrt(obsVar)*RandomGenerator::GetNormal(interp->outputSizes(0)));
73 std::shared_ptr<ModPiece>
ConstructDensity(std::size_t
const numCells,
Data const& data,
double const likelihoodVar) {
74 const Discretization mesh(numCells);
76 const double sigma2 = 1.0;
77 const double length = 0.1;
78 auto kernel = std::make_shared<SquaredExpKernel>(1, sigma2, length);
81 const std::size_t order = 15;
83 const Eigen::RowVectorXd points = quad.
Points();
84 const Eigen::VectorXd weights = quad.
Weights();
87 const Eigen::Matrix modes = klexpansion.
GetModes(mesh.cellLocs.transpose());
88 auto logConductivity = LinearOperator::Create(modes);
90 auto prior = std::make_shared<Gaussian>(modes.cols());
92 const std::size_t numSamps = 15;
93 Eigen::MatrixXd priorSamples(numSamps, mesh.numCells);
94 for( std::size_t i=0; i<numSamps; ++i ) {
95 priorSamples.row(i) = logConductivity->Evaluate(prior->Sample()).at(0);
98 const std::string filename =
"output.h5";
99 auto file = std::make_shared<HDF5File>(filename);
100 file->WriteMatrix(
"/prior information/x", mesh.cellLocs);
101 file->WriteMatrix(
"/prior information/samples", priorSamples);
104 auto graph = std::make_shared<WorkGraph>();
105 graph->AddNode(std::make_shared<IdentityOperator>(logConductivity->inputSizes(0)),
"theta");
106 graph->AddNode(logConductivity,
"log conductivity");
107 graph->AddEdge(
"theta", 0,
"log conductivity", 0);
109 graph->AddNode(std::make_shared<ExpOperator>(mesh.numCells),
"conductivity");
110 graph->AddEdge(
"log conductivity", 0,
"conductivity", 0);
114 auto forwardMod = std::make_shared<FlowEquation>(recharge);
116 graph->AddNode(forwardMod,
"forward model");
117 graph->AddEdge(
"conductivity", 0,
"forward model", 0);
120 graph->AddEdge(
"forward model", 0,
"observations", 0);
122 auto likelihood = std::make_shared<Gaussian>(data.
obs, likelihoodVar*Eigen::VectorXd::Ones(data.
obs.size()));
123 graph->AddNode(likelihood->AsDensity(),
"likelihood");
124 graph->AddEdge(
"observations", 0,
"likelihood", 0);
126 graph->AddNode(prior->AsDensity(),
"prior");
127 graph->AddEdge(
"theta", 0,
"prior", 0);
129 graph->AddNode(std::make_shared<DensityProduct>(2),
"posterior");
130 graph->AddEdge(
"prior", 0,
"posterior", 0);
131 graph->AddEdge(
"likelihood", 0,
"posterior", 1);
133 graph->Visualize(
"WorkGraph.pdf");
135 return graph->CreateModPiece(
"posterior");
138 std::vector<std::shared_ptr<ModPiece> >
ConstructDensities(std::size_t
const numLevels, std::size_t
const baseRefinement) {
140 const std::size_t numObs = 25;
141 const double obsVar = 1.0e-4;
142 const Data data =
GenerateData(baseRefinement*(numLevels+1), numObs, obsVar);
144 const std::string filename =
"output.h5";
145 auto file = std::make_shared<HDF5File>(filename);
146 file->WriteMatrix(
"/truth/x", data.
x);
147 file->WriteMatrix(
"/truth/solution", data.
soln);
148 file->WriteMatrix(
"/data/locations", data.
obsLoc);
149 file->WriteMatrix(
"/data/observations", data.
obs);
152 std::vector<std::shared_ptr<ModPiece> > logDensities(numLevels);
154 for( std::size_t i=0; i<numLevels; ++i ) {
Data GenerateData(std::size_t const numCells, std::size_t const numObs, double const obsVar)
std::shared_ptr< LinearOperator > InterpolateOntoObs(Discretization const &mesh, Eigen::VectorXd const &obsLoc)
Interpolate the model solution onto the observation points.
std::vector< std::shared_ptr< ModPiece > > ConstructDensities(std::size_t const numLevels, std::size_t const baseRefinement)
Eigen::VectorXd GetTrueLogConductivity(Discretization const &mesh)
std::shared_ptr< ModPiece > ConstructDensity(std::size_t const numCells, Data const &data, double const likelihoodVar)
Eigen::VectorXd GetRecharge(Discretization const &mesh)
Class for computing Gauss Quadrature rules from an orthogonal polynomial family.
virtual void Compute(unsigned int quadOrder) override
Used to compute and evaluate the Karhunen-Loeve decomposition of a zero mean Gaussian process....
virtual Eigen::MatrixXd GetModes(Eigen::Ref< const Eigen::MatrixXd > const &pts) const override
virtual Eigen::MatrixXd const & Points() const
virtual Eigen::VectorXd const & Weights() const
Data(Eigen::VectorXd const &x, Eigen::VectorXd const &soln, Eigen::VectorXd const &obsLoc, Eigen::VectorXd const &obs)
const Eigen::VectorXd soln
The true solution.
const Eigen::VectorXd obs
The observations.
const Eigen::VectorXd x
The locations where we have computed the true solution.
const Eigen::VectorXd obsLoc
The locations where we have made observations.