Loading...
Searching...
No Matches
Pagani2016filter.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12
13 License
14 This file is part of ITHACA-FV
15
16 ITHACA-FV is free software: you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 ITHACA-FV is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
28
29\*---------------------------------------------------------------------------*/
30
31
34
35#include "Pagani2016filter.H"
36
37namespace ITHACAmuq
38{
39// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
40// Constructor
41Pagani2016filter::Pagani2016filter() {}
42Pagani2016filter::Pagani2016filter(int _Nseeds)
43{
44 Nseeds = _Nseeds;
45}
46
47// * * * * * * * * * * * * * * Filter Methods * * * * * * * * * * * * * * //
48
49// Return number of samples per ensamble
51{
52 return Nseeds;
53}
54
56{
57 return trueObservations.rows();
58}
59
60// Return time
62{
63 return timeVector(timeStepI);
64}
65
66//--------------------------------------------------------------------------
68double Pagani2016filter::getTime(int _timeStepI)
69{
70 return timeVector(_timeStepI);
71}
72
73//--------------------------------------------------------------------------
76{
77 return timeStepI;
78}
79
80//--------------------------------------------------------------------------
83{
84 return timeVector;
85}
86
87//--------------------------------------------------------------------------
90{
91 return stateMean;
92}
93
94//--------------------------------------------------------------------------
97{
98 return parameterMean;
99}
100
101//--------------------------------------------------------------------------
104{
105 Info << "debug : stateMean.cols() = " << stateMean.cols() << endl;
106 Info << "debug : _index = " << _index << endl;
107 stateMean.col(_index) = stateEns.mean();
108}
109
110//--------------------------------------------------------------------------
113{
114 parameterMean.col(_index) = parameterEns.mean();
115}
116
117//--------------------------------------------------------------------------
120{
121 return timeSampI;
122}
123
124//--------------------------------------------------------------------------
127{
128 return observationStart + observationDelta * _timeSampleI;
129}
130
131//--------------------------------------------------------------------------
133void Pagani2016filter::setTrueObservations(Eigen::MatrixXd _observations)
134{
135 trueObservations = _observations;
136 Info << "trueObservations = \n" << trueObservations << endl;
137
138 for (int colI = 0; colI < trueObservations.cols(); colI++)
139 {
140 trueObservations.col(colI) += measNoiseDensity->Sample();
141 }
142
143 Info << "trueObservations w. error = \n" << trueObservations << endl;
144}
145
146//--------------------------------------------------------------------------
148void Pagani2016filter::setTime(double _startTime, double _deltaTime,
149 double _endTime)
150{
151 M_Assert(_endTime > _startTime, "endTime must be bigger than startTime");
152 startTime = _startTime;
153 deltaTime = _deltaTime;
154 endTime = _endTime;
155 Ntimes = round((endTime - startTime) / deltaTime);
156 Info << "startTime = " << startTime << endl;
157 Info << "endTime = " << endTime << endl;
158 Info << "deltaTime = " << deltaTime << endl;
159 Info << "Ntimes = " << Ntimes << endl;
160 timeVector = Eigen::VectorXd::LinSpaced(Ntimes + 1, startTime, endTime);
161}
162
163//--------------------------------------------------------------------------
165void Pagani2016filter::setObservationTime(int _observationStart,
166 int _observationDelta)
167{
168 M_Assert(timeVector.size() > 0,
169 "Setup the timeVector before setting up the observations vector");
170 M_Assert(_observationStart > 0, "First observation timestep can't be 0");
171 observationStart = _observationStart;
172 observationDelta = _observationDelta;
173 Info << "First observation at time = " << timeVector(observationStart) << " s"
174 << endl;
175 Info << "Observations taken every " << observationDelta << " timesteps" << endl;
176 observationBoolVec = Eigen::VectorXi::Zero(timeVector.size() - 1);
177
178 for (int i = observationStart - 1; i < Ntimes; i += observationDelta)
179 {
180 observationBoolVec(i) = 1;
181 }
182}
183
184//--------------------------------------------------------------------------
187{
188 M_Assert(observationSize > 0,
189 "Read measurements before setting up the measurement noise");
190 Eigen::VectorXd measNoise_mu = Eigen::VectorXd::Zero(observationSize);
191 Eigen::MatrixXd measNoise_cov = Eigen::MatrixXd::Identity(observationSize,
192 observationSize) * cov;
193 measNoiseDensity = std::make_shared<muq::Modeling::Gaussian>(measNoise_mu,
194 measNoise_cov);
195 measurementNoiseFlag = 1;
196}
197
198//--------------------------------------------------------------------------
201{
202 M_Assert(parameterSize > 0,
203 "Set parameter size before setting up the parameter error");
204 Eigen::VectorXd parameterError_mu = Eigen::VectorXd::Zero(parameterSize);
205 Eigen::MatrixXd parameterError_cov = Eigen::MatrixXd::Identity(parameterSize,
206 parameterSize) * cov;
207 parameterErrorDensity = std::make_shared<muq::Modeling::Gaussian>
208 (parameterError_mu,
209 parameterError_cov);
210}
211
212//--------------------------------------------------------------------------
215 Eigen::MatrixXd _cov)
216{
217 if (stateSize == 0)
218 {
219 stateSize = _mean.size();
220 }
221 else
222 {
223 std::string message = "State has size = " + std::to_string(stateSize)
224 + " while input mean vector has size = "
225 + std::to_string(_mean.size());
226 M_Assert(stateSize == _mean.size(), message.c_str());
227 }
228
229 M_Assert(_cov.rows() == stateSize
230 && _cov.cols() == stateSize,
231 "To initialize the state ensemble use mean and cov with same dimentions");
232 initialStateDensity = std::make_shared<muq::Modeling::Gaussian>(_mean, _cov);
233 initialStateFlag = 1;
234}
235
236//--------------------------------------------------------------------------
239{
240 M_Assert(initialStateFlag == 1,
241 "Initialize the initial state density before sampling it");
242 stateEns.assignSamples(ensembleFromDensity(initialStateDensity));
243}
244
245//--------------------------------------------------------------------------
248{
249 M_Assert(parameterPriorFlag == 1,
250 "Initialize the initial parameter density before sampling it");
251 parameterEns.assignSamples(ensembleFromDensity(parameterPriorDensity));
252}
253
254//--------------------------------------------------------------------------
257 Eigen::MatrixXd _cov)
258{
259 if (parameterSize == 0)
260 {
261 parameterSize = _mean.size();
262 }
263 else
264 {
265 std::string message = "The input mean has size = " + std::to_string(
266 _mean.size())
267 + " but the parameterSize is "
268 + std::to_string(parameterSize);
269 M_Assert(parameterSize == _mean.size(), message.c_str());
270 }
271
272 M_Assert(_cov.rows() == parameterSize
273 && _cov.cols() == parameterSize, "Use mean and cov with same dimentions");
274 parameterPriorMean = _mean;
275 parameterPriorCov = _cov;
276 parameterPriorDensity = std::make_shared<muq::Modeling::Gaussian>(_mean, _cov);
277 parameterPriorFlag = 1;
278}
279
280//--------------------------------------------------------------------------
283 std::shared_ptr<muq::Modeling::Gaussian> _density)
284{
285 M_Assert(Nseeds > 0, "Number of samples not set up correctly");
286 Eigen::MatrixXd output(_density->Sample().size(), Nseeds);
287
288 for (int i = 0; i < Nseeds; i++)
289 {
290 output.col(i) = _density->Sample();
291 }
292
293 return output;
294}
295
296//--------------------------------------------------------------------------
298void Pagani2016filter::setObservationSize(int _size)
299{
300 observationSize = _size;
301 Info << "Observation size = " << observationSize << endl;
302}
303
304//--------------------------------------------------------------------------
306void Pagani2016filter::setStateSize(int _size)
307{
308 stateSize = _size;
309 Info << "State size = " << stateSize << endl;
310}
311
312//--------------------------------------------------------------------------
314int Pagani2016filter::getStateSize()
315{
316 return stateSize;
317}
318
319//--------------------------------------------------------------------------
321void Pagani2016filter::setParameterSize(int _size)
322{
323 parameterSize = _size;
324 Info << "Parameter size = " << parameterSize << endl;
325}
326
327//--------------------------------------------------------------------------
329int Pagani2016filter::getParameterSize()
330{
331 return parameterSize;
332}
333
334//--------------------------------------------------------------------------
337{
338 Eigen::MatrixXd parameterObservation_crossCov =
339 parameterEns.crossCov(observationEns.getSamples());
340 Eigen::MatrixXd stateObservation_crossCov =
341 stateEns.crossCov(observationEns.getSamples());
342 Eigen::MatrixXd observation_Cov = observationEns.cov();
343 Eigen::MatrixXd P = measNoiseDensity->ApplyCovariance(
344 Eigen::MatrixXd::Identity(observationSize, observationSize));
345 P += observation_Cov;
346 Info << "debug : P = \n" << P << endl;
347 P = P.inverse(); //TODO check if invertible
348 Info << "debug : P inverse = \n" << P << endl;
349 Eigen::MatrixXd parameterUpdateMat = parameterObservation_crossCov * P;
350 Eigen::MatrixXd stateUpdateMat = stateObservation_crossCov * P;
351
352 for (int seedI = 0; seedI < Nseeds; seedI++)
353 {
354 Eigen::VectorXd observationDelta =
355 trueObservations.col(timeSampI) - observationEns.getSample(seedI);
356 parameterEns.assignSample(seedI,
357 parameterEns.getSample(seedI) + parameterUpdateMat * observationDelta);
358 stateEns.assignSample(seedI,
359 stateEns.getSample(seedI) + stateUpdateMat * observationDelta);
360 }
361
362 Info << "debug : parameterEns.mean() =\n" << parameterEns.mean() << endl;
363 Info << "debug : stateEns.mean() =\n" << stateEns.mean() << endl;
364}
365
366//--------------------------------------------------------------------------
368void Pagani2016filter::run(word outputFolder)
369{
370 M_Assert(initialStateFlag == 1, "Set up the initial state density");
371 M_Assert(parameterPriorFlag == 1, "Set up the parameter prior density");
372 M_Assert(measurementNoiseFlag == 1, "Set up the measurement noise");
373 M_Assert(stateSize > 0, "Set state size");
374 M_Assert(observationSize > 0, "Set observation size");
375 M_Assert(parameterSize > 0, "Set parameter size");
376 // Initialization
379 int NtimeObservations = observationBoolVec.sum();
380 stateMean.resize(stateSize, Ntimes);
381 state_maxConf.resize(stateSize, Ntimes);
382 state_minConf.resize(stateSize, Ntimes);
383 parameter_maxConf.resize(parameterSize, Ntimes);
384 parameter_minConf.resize(parameterSize, Ntimes);
385 parameterMean.resize(parameterSize, Ntimes);
386
387 for (timeSampI = 0; timeSampI < NtimeObservations; timeSampI++)
388 {
389 Info << "timeSamp " << timeSampI << endl;
390 oldStateEns.assignSamples(stateEns.getSamples());
392 update();
393 }
394
395 ITHACAstream::exportMatrix(stateMean, "stateMean", "eigen", outputFolder);
396 ITHACAstream::exportMatrix(parameterMean, "parameterMean", "eigen",
397 outputFolder);
398 ITHACAstream::exportMatrix(parameter_maxConf, "parameter_maxConf", "eigen",
399 outputFolder);
400 ITHACAstream::exportMatrix(parameter_minConf, "parameter_minConf", "eigen",
401 outputFolder);
402 Info << "\n*****************************************************" << endl;
403 Info << "Kalman filter run ENDED" << endl;
404 Info << "\n*****************************************************" << endl;
405}
406}
Header file of the Pagani2016filter class.
Eigen::MatrixXd getParameterMean()
Return parameter mean.
void setTime(double _startTime, double _deltaTime, double _endTime)
Setup the time vector.
int getTimeStep()
Return timestep.
void update()
Perform Kalman filter update.
void setParameterPriorDensity(Eigen::VectorXd _mean, Eigen::MatrixXd _cov)
Create parameter ensemble.
void setMeasNoise(double cov)
Setup of the measurement noise distribution.
int getObservationTimestep(int _timeSampleI)
Return timestep at corresponding to the input observation step.
Eigen::VectorXd getTimeVector()
Return time vector.
void sampleInitialState()
Create initial state ensemble.
void setObservationTime(int _observationStart, int _observationDelta)
Setup the observation vector.
ensemble observationEns
Observation ensemble.
Eigen::MatrixXd parameter_minConf
parameter minimum confidence level
std::shared_ptr< muq::Modeling::Gaussian > measNoiseDensity
Measurement noise density.
void computeStateMean(int _index)
Compute state mean.
std::shared_ptr< muq::Modeling::Gaussian > parameterErrorDensity
Parameter error density.
void setParameterError(double cov)
Setup of the parameter error distribution.
Eigen::MatrixXd state_maxConf
State maximum confidence level.
Eigen::MatrixXd ensembleFromDensity(std::shared_ptr< muq::Modeling::Gaussian > _density)
General class to sample from an input density.
int getObservationSize()
Return the size of the observation vector.
Eigen::MatrixXd state_minConf
State minimum confidence level.
ensemble parameterEns
Parameter ensemble.
double getTime()
Return time.
void computeParameterMean(int _index)
Compute parameter mean.
int getNumberOfSamples()
Return number of samples per ensamble.
virtual void stateProjection()=0
Project the state in between two sampling steps and fills the state and parameter mean and confidence...
Eigen::MatrixXd getStateMean()
Return state mean.
void setTrueObservations(Eigen::MatrixXd _observations)
Set the observations matrix.
ensemble oldStateEns
Old state ensemble.
void run(word outputFolder)
Run the filtering.
void setInitialStateDensity(Eigen::VectorXd _mean, Eigen::MatrixXd _cov)
Create initial state ensemble.
void sampleInitialParameter()
Create initial parameter ensemble.
Eigen::MatrixXd parameter_maxConf
parameter maximum confidence level
ensemble stateEns
State ensemble.
void exportMatrix(Eigen::Matrix< T, -1, dim > &matrix, word Name, word type, word folder)
Export the reduced matrices in numpy (type=python), matlab (type=matlab) and txt (type=eigen) format ...