From 4f435fcc60a68fdbf38da8d4ba86d7d125044a13 Mon Sep 17 00:00:00 2001 From: kohlhaasrebecca <rebecca.kohlhaas@outlook.com> Date: Wed, 24 Jan 2024 10:30:40 +0100 Subject: [PATCH] Minimal test for umbridge model Added a minimal test based on pylink classification. More work needed for higher-dim. model outputs here --- .../Beam9points_1/SSBeam_Deflection.tpl.inp | 6 - .../Beam9points_1/SSBeam_Deflection_1.inp | 8 +- .../Beam9points_10/SSBeam_Deflection_10.inp | 6 - .../Beam9points_11/SSBeam_Deflection_11.inp | 6 - .../Beam9points_12/SSBeam_Deflection_12.inp | 6 - .../Beam9points_13/SSBeam_Deflection_13.inp | 6 - .../Beam9points_14/SSBeam_Deflection_14.inp | 6 - .../Beam9points_15/SSBeam_Deflection_15.inp | 6 - .../Beam9points_16/SSBeam_Deflection_16.inp | 6 - .../Beam9points_2/SSBeam_Deflection_2.inp | 6 - .../Beam9points_3/SSBeam_Deflection_3.inp | 6 - .../Beam9points_4/SSBeam_Deflection_4.inp | 6 - .../Beam9points_5/SSBeam_Deflection_5.inp | 6 - .../Beam9points_6/SSBeam_Deflection_6.inp | 6 - .../Beam9points_7/SSBeam_Deflection_7.inp | 6 - .../Beam9points_8/SSBeam_Deflection_8.inp | 6 - .../Beam9points_9/SSBeam_Deflection_9.inp | 6 - examples/borehole/example_borehole.py | 2 +- .../bayesvalidrox/__init__.py | 25 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 795 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 968 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 860 bytes .../bayesvalidrox/bayes_inference/__init__.py | 9 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 303 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 354 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 368 bytes .../bayes_inference.cpython-310.pyc | Bin 0 -> 31276 bytes .../bayes_inference.cpython-311.pyc | Bin 0 -> 60952 bytes .../bayes_inference.cpython-39.pyc | Bin 0 -> 31419 bytes .../bayes_model_comparison.cpython-310.pyc | Bin 0 -> 15645 bytes .../bayes_model_comparison.cpython-311.pyc | Bin 0 -> 27157 bytes .../bayes_model_comparison.cpython-39.pyc | Bin 0 -> 15716 bytes .../__pycache__/discrepancy.cpython-310.pyc | Bin 0 -> 3806 bytes .../__pycache__/discrepancy.cpython-311.pyc | Bin 0 -> 4661 bytes .../__pycache__/discrepancy.cpython-39.pyc | Bin 0 -> 3869 bytes .../__pycache__/mcmc.cpython-310.pyc | Bin 0 -> 18924 bytes .../__pycache__/mcmc.cpython-311.pyc | Bin 0 -> 35893 bytes .../__pycache__/mcmc.cpython-39.pyc | Bin 0 -> 18959 bytes .../bayes_inference/bayes_inference.py | 1532 ++++++++++++ .../bayes_inference/bayes_model_comparison.py | 658 +++++ .../bayes_inference/discrepancy.py | 103 + .../bayesvalidrox/bayes_inference/mcmc.py | 909 +++++++ .../bayesvalidrox/bayesvalidrox.mplstyle | 16 + .../bayesvalidrox/post_processing/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 261 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 295 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 326 bytes .../post_processing.cpython-310.pyc | Bin 0 -> 28679 bytes .../post_processing.cpython-311.pyc | Bin 0 -> 58838 bytes .../post_processing.cpython-39.pyc | Bin 0 -> 28771 bytes .../post_processing/post_processing.py | 1338 ++++++++++ .../bayesvalidrox/pylink/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 247 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 281 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 312 bytes .../pylink/__pycache__/pylink.cpython-310.pyc | Bin 0 -> 18654 bytes .../pylink/__pycache__/pylink.cpython-311.pyc | Bin 0 -> 35406 bytes .../pylink/__pycache__/pylink.cpython-39.pyc | Bin 0 -> 18646 bytes .../bayesvalidrox/pylink/pylink.py | 799 ++++++ .../surrogate_models/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 258 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 292 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 323 bytes .../__pycache__/adaptPlot.cpython-311.pyc | Bin 0 -> 4921 bytes .../apoly_construction.cpython-310.pyc | Bin 0 -> 2815 bytes .../apoly_construction.cpython-311.pyc | Bin 0 -> 5228 bytes .../apoly_construction.cpython-39.pyc | Bin 0 -> 2886 bytes .../__pycache__/bayes_linear.cpython-310.pyc | Bin 0 -> 14412 bytes .../__pycache__/bayes_linear.cpython-311.pyc | Bin 0 -> 21706 bytes .../__pycache__/bayes_linear.cpython-39.pyc | Bin 0 -> 14506 bytes .../__pycache__/engine.cpython-311.pyc | Bin 0 -> 84465 bytes .../__pycache__/eval_rec_rule.cpython-310.pyc | Bin 0 -> 5560 bytes .../__pycache__/eval_rec_rule.cpython-311.pyc | Bin 0 -> 8154 bytes .../__pycache__/eval_rec_rule.cpython-39.pyc | Bin 0 -> 5648 bytes .../__pycache__/exp_designs.cpython-310.pyc | Bin 0 -> 17477 bytes .../__pycache__/exp_designs.cpython-311.pyc | Bin 0 -> 19555 bytes .../__pycache__/exp_designs.cpython-39.pyc | Bin 0 -> 17597 bytes .../__pycache__/exp_designs_.cpython-311.pyc | Bin 0 -> 20552 bytes .../__pycache__/exploration.cpython-310.pyc | Bin 0 -> 8154 bytes .../__pycache__/exploration.cpython-311.pyc | Bin 0 -> 12405 bytes .../__pycache__/exploration.cpython-39.pyc | Bin 0 -> 8190 bytes .../__pycache__/glexindex.cpython-310.pyc | Bin 0 -> 7185 bytes .../__pycache__/glexindex.cpython-311.pyc | Bin 0 -> 7952 bytes .../__pycache__/glexindex.cpython-39.pyc | Bin 0 -> 7232 bytes .../__pycache__/input_space.cpython-311.pyc | Bin 0 -> 16785 bytes .../__pycache__/inputs.cpython-310.pyc | Bin 0 -> 2413 bytes .../__pycache__/inputs.cpython-311.pyc | Bin 0 -> 2860 bytes .../__pycache__/inputs.cpython-39.pyc | Bin 0 -> 2474 bytes .../__pycache__/loss_function.cpython-311.pyc | Bin 0 -> 13488 bytes .../meta_model_engine.cpython-310.pyc | Bin 0 -> 42392 bytes .../meta_model_engine.cpython-311.pyc | Bin 0 -> 87304 bytes .../meta_model_engine.cpython-39.pyc | Bin 0 -> 42705 bytes ...rthogonal_matching_pursuit.cpython-310.pyc | Bin 0 -> 8915 bytes ...rthogonal_matching_pursuit.cpython-311.pyc | Bin 0 -> 14832 bytes ...orthogonal_matching_pursuit.cpython-39.pyc | Bin 0 -> 8930 bytes .../__pycache__/reg_fast_ard.cpython-310.pyc | Bin 0 -> 11629 bytes .../__pycache__/reg_fast_ard.cpython-311.pyc | Bin 0 -> 19787 bytes .../__pycache__/reg_fast_ard.cpython-39.pyc | Bin 0 -> 11717 bytes .../reg_fast_laplace.cpython-310.pyc | Bin 0 -> 9509 bytes .../reg_fast_laplace.cpython-311.pyc | Bin 0 -> 19040 bytes .../reg_fast_laplace.cpython-39.pyc | Bin 0 -> 9581 bytes .../sequential_design.cpython-311.pyc | Bin 0 -> 87535 bytes .../surrogate_models.cpython-310.pyc | Bin 0 -> 35103 bytes .../surrogate_models.cpython-311.pyc | Bin 0 -> 61708 bytes .../surrogate_models.cpython-39.pyc | Bin 0 -> 35188 bytes .../surrogate_models/adaptPlot.py | 109 + .../surrogate_models/apoly_construction.py | 124 + .../surrogate_models/bayes_linear.py | 523 ++++ .../bayesvalidrox/surrogate_models/engine.py | 2195 +++++++++++++++++ .../surrogate_models/eval_rec_rule.py | 197 ++ .../surrogate_models/exp_designs.py | 493 ++++ .../surrogate_models/exploration.py | 364 +++ .../surrogate_models/glexindex.py | 161 ++ .../surrogate_models/input_space.py | 395 +++ .../bayesvalidrox/surrogate_models/inputs.py | 76 + .../orthogonal_matching_pursuit.py | 366 +++ .../surrogate_models/reg_fast_ard.py | 475 ++++ .../surrogate_models/reg_fast_laplace.py | 452 ++++ .../surrogate_models/sequential_design.py | 2187 ++++++++++++++++ .../surrogate_models/surrogate_models.py | 1473 +++++++++++ .../test_umbridge.py | 183 ++ .../test_umbridge_testmodel.py | 80 + .../testmodel.py | 18 + .../tsunami_model.py | 18 + .../tsunami_model1.py | 16 + .../bayesvalidrox/__init__.py | 25 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 795 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 968 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 860 bytes .../bayesvalidrox/bayes_inference/__init__.py | 9 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 303 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 354 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 368 bytes .../bayes_inference.cpython-310.pyc | Bin 0 -> 31276 bytes .../bayes_inference.cpython-311.pyc | Bin 0 -> 60952 bytes .../bayes_inference.cpython-39.pyc | Bin 0 -> 31419 bytes .../bayes_model_comparison.cpython-310.pyc | Bin 0 -> 15645 bytes .../bayes_model_comparison.cpython-311.pyc | Bin 0 -> 27157 bytes .../bayes_model_comparison.cpython-39.pyc | Bin 0 -> 15716 bytes .../__pycache__/discrepancy.cpython-310.pyc | Bin 0 -> 3806 bytes .../__pycache__/discrepancy.cpython-311.pyc | Bin 0 -> 4661 bytes .../__pycache__/discrepancy.cpython-39.pyc | Bin 0 -> 3869 bytes .../__pycache__/mcmc.cpython-310.pyc | Bin 0 -> 18924 bytes .../__pycache__/mcmc.cpython-311.pyc | Bin 0 -> 35893 bytes .../__pycache__/mcmc.cpython-39.pyc | Bin 0 -> 18959 bytes .../bayes_inference/bayes_inference.py | 1532 ++++++++++++ .../bayes_inference/bayes_model_comparison.py | 658 +++++ .../bayes_inference/discrepancy.py | 103 + .../bayesvalidrox/bayes_inference/mcmc.py | 909 +++++++ .../bayesvalidrox/bayesvalidrox.mplstyle | 16 + .../bayesvalidrox/post_processing/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 261 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 295 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 326 bytes .../post_processing.cpython-310.pyc | Bin 0 -> 28679 bytes .../post_processing.cpython-311.pyc | Bin 0 -> 58838 bytes .../post_processing.cpython-39.pyc | Bin 0 -> 28771 bytes .../post_processing/post_processing.py | 1338 ++++++++++ .../bayesvalidrox/pylink/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 247 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 281 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 312 bytes .../pylink/__pycache__/pylink.cpython-310.pyc | Bin 0 -> 18654 bytes .../pylink/__pycache__/pylink.cpython-311.pyc | Bin 0 -> 35776 bytes .../pylink/__pycache__/pylink.cpython-39.pyc | Bin 0 -> 18646 bytes .../bayesvalidrox/pylink/pylink.py | 797 ++++++ .../surrogate_models/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 258 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 292 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 323 bytes .../__pycache__/adaptPlot.cpython-311.pyc | Bin 0 -> 4921 bytes .../apoly_construction.cpython-310.pyc | Bin 0 -> 2815 bytes .../apoly_construction.cpython-311.pyc | Bin 0 -> 5228 bytes .../apoly_construction.cpython-39.pyc | Bin 0 -> 2886 bytes .../__pycache__/bayes_linear.cpython-310.pyc | Bin 0 -> 14412 bytes .../__pycache__/bayes_linear.cpython-311.pyc | Bin 0 -> 21706 bytes .../__pycache__/bayes_linear.cpython-39.pyc | Bin 0 -> 14506 bytes .../__pycache__/engine.cpython-311.pyc | Bin 0 -> 84465 bytes .../__pycache__/eval_rec_rule.cpython-310.pyc | Bin 0 -> 5560 bytes .../__pycache__/eval_rec_rule.cpython-311.pyc | Bin 0 -> 8154 bytes .../__pycache__/eval_rec_rule.cpython-39.pyc | Bin 0 -> 5648 bytes .../__pycache__/exp_designs.cpython-310.pyc | Bin 0 -> 17477 bytes .../__pycache__/exp_designs.cpython-311.pyc | Bin 0 -> 19555 bytes .../__pycache__/exp_designs.cpython-39.pyc | Bin 0 -> 17597 bytes .../__pycache__/exp_designs_.cpython-311.pyc | Bin 0 -> 20552 bytes .../__pycache__/exploration.cpython-310.pyc | Bin 0 -> 8154 bytes .../__pycache__/exploration.cpython-311.pyc | Bin 0 -> 12405 bytes .../__pycache__/exploration.cpython-39.pyc | Bin 0 -> 8190 bytes .../__pycache__/glexindex.cpython-310.pyc | Bin 0 -> 7185 bytes .../__pycache__/glexindex.cpython-311.pyc | Bin 0 -> 7952 bytes .../__pycache__/glexindex.cpython-39.pyc | Bin 0 -> 7232 bytes .../__pycache__/input_space.cpython-311.pyc | Bin 0 -> 16785 bytes .../__pycache__/inputs.cpython-310.pyc | Bin 0 -> 2413 bytes .../__pycache__/inputs.cpython-311.pyc | Bin 0 -> 2860 bytes .../__pycache__/inputs.cpython-39.pyc | Bin 0 -> 2474 bytes .../__pycache__/loss_function.cpython-311.pyc | Bin 0 -> 13488 bytes .../meta_model_engine.cpython-310.pyc | Bin 0 -> 42392 bytes .../meta_model_engine.cpython-311.pyc | Bin 0 -> 87304 bytes .../meta_model_engine.cpython-39.pyc | Bin 0 -> 42705 bytes ...rthogonal_matching_pursuit.cpython-310.pyc | Bin 0 -> 8915 bytes ...rthogonal_matching_pursuit.cpython-311.pyc | Bin 0 -> 14832 bytes ...orthogonal_matching_pursuit.cpython-39.pyc | Bin 0 -> 8930 bytes .../__pycache__/reg_fast_ard.cpython-310.pyc | Bin 0 -> 11629 bytes .../__pycache__/reg_fast_ard.cpython-311.pyc | Bin 0 -> 19787 bytes .../__pycache__/reg_fast_ard.cpython-39.pyc | Bin 0 -> 11717 bytes .../reg_fast_laplace.cpython-310.pyc | Bin 0 -> 9509 bytes .../reg_fast_laplace.cpython-311.pyc | Bin 0 -> 19040 bytes .../reg_fast_laplace.cpython-39.pyc | Bin 0 -> 9581 bytes .../sequential_design.cpython-311.pyc | Bin 0 -> 87535 bytes .../surrogate_models.cpython-310.pyc | Bin 0 -> 35103 bytes .../surrogate_models.cpython-311.pyc | Bin 0 -> 61708 bytes .../surrogate_models.cpython-39.pyc | Bin 0 -> 35188 bytes .../surrogate_models/adaptPlot.py | 109 + .../surrogate_models/apoly_construction.py | 124 + .../surrogate_models/bayes_linear.py | 523 ++++ .../bayesvalidrox/surrogate_models/engine.py | 2195 +++++++++++++++++ .../surrogate_models/eval_rec_rule.py | 197 ++ .../surrogate_models/exp_designs.py | 493 ++++ .../surrogate_models/exploration.py | 364 +++ .../surrogate_models/glexindex.py | 161 ++ .../surrogate_models/input_space.py | 395 +++ .../bayesvalidrox/surrogate_models/inputs.py | 76 + .../orthogonal_matching_pursuit.py | 366 +++ .../surrogate_models/reg_fast_ard.py | 475 ++++ .../surrogate_models/reg_fast_laplace.py | 452 ++++ .../surrogate_models/sequential_design.py | 2187 ++++++++++++++++ .../surrogate_models/surrogate_models.py | 1473 +++++++++++ .../test_umbridge_testmodel.py | 77 + .../umbridge_tsunamitutorial/testmodel.pk1 | Bin 0 -> 12063 bytes .../umbridge_tsunamitutorial/testmodel.py | 20 + setup.cfg | 12 +- src/bayesvalidrox.egg-info/PKG-INFO | 86 + src/bayesvalidrox.egg-info/SOURCES.txt | 44 + .../dependency_links.txt | 1 + src/bayesvalidrox.egg-info/requires.txt | 13 + src/bayesvalidrox.egg-info/top_level.txt | 1 + src/bayesvalidrox/pylink/pylink.py | 66 +- src/bayesvalidrox/surrogate_models/engine.py | 28 +- .../surrogate_models/exp_designs.py | 6 +- 239 files changed, 30643 insertions(+), 130 deletions(-) delete mode 100644 examples/beam/Beam9points_1/SSBeam_Deflection.tpl.inp delete mode 100644 examples/beam/Beam9points_10/SSBeam_Deflection_10.inp delete mode 100644 examples/beam/Beam9points_11/SSBeam_Deflection_11.inp delete mode 100644 examples/beam/Beam9points_12/SSBeam_Deflection_12.inp delete mode 100644 examples/beam/Beam9points_13/SSBeam_Deflection_13.inp delete mode 100644 examples/beam/Beam9points_14/SSBeam_Deflection_14.inp delete mode 100644 examples/beam/Beam9points_15/SSBeam_Deflection_15.inp delete mode 100644 examples/beam/Beam9points_16/SSBeam_Deflection_16.inp delete mode 100644 examples/beam/Beam9points_2/SSBeam_Deflection_2.inp delete mode 100644 examples/beam/Beam9points_3/SSBeam_Deflection_3.inp delete mode 100644 examples/beam/Beam9points_4/SSBeam_Deflection_4.inp delete mode 100644 examples/beam/Beam9points_5/SSBeam_Deflection_5.inp delete mode 100644 examples/beam/Beam9points_6/SSBeam_Deflection_6.inp delete mode 100644 examples/beam/Beam9points_7/SSBeam_Deflection_7.inp delete mode 100644 examples/beam/Beam9points_8/SSBeam_Deflection_8.inp delete mode 100644 examples/beam/Beam9points_9/SSBeam_Deflection_9.inp create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__init__.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__init__.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_inference.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_model_comparison.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/discrepancy.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/mcmc.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayesvalidrox.mplstyle create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__init__.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/post_processing.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__init__.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/pylink.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__init__.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/adaptPlot.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/apoly_construction.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/bayes_linear.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/engine.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/eval_rec_rule.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exp_designs.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exploration.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/glexindex.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/input_space.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/inputs.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_ard.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_laplace.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/sequential_design.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/surrogate_models.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/test_umbridge.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/test_umbridge_testmodel.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/testmodel.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/tsunami_model.py create mode 100644 examples/umbridge_tsunamitutorial - Copy/tsunami_model1.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/__init__.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__init__.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_inference.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_model_comparison.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/discrepancy.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/mcmc.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/bayesvalidrox.mplstyle create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__init__.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/post_processing.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__init__.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/pylink.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__init__.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/adaptPlot.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/apoly_construction.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/bayes_linear.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/engine.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/eval_rec_rule.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exp_designs.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exploration.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/glexindex.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/input_space.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/inputs.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_ard.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_laplace.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/sequential_design.py create mode 100644 examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/surrogate_models.py create mode 100644 examples/umbridge_tsunamitutorial/test_umbridge_testmodel.py create mode 100644 examples/umbridge_tsunamitutorial/testmodel.pk1 create mode 100644 examples/umbridge_tsunamitutorial/testmodel.py create mode 100644 src/bayesvalidrox.egg-info/PKG-INFO create mode 100644 src/bayesvalidrox.egg-info/SOURCES.txt create mode 100644 src/bayesvalidrox.egg-info/dependency_links.txt create mode 100644 src/bayesvalidrox.egg-info/requires.txt create mode 100644 src/bayesvalidrox.egg-info/top_level.txt diff --git a/examples/beam/Beam9points_1/SSBeam_Deflection.tpl.inp b/examples/beam/Beam9points_1/SSBeam_Deflection.tpl.inp deleted file mode 100644 index 6bfc3fe96..000000000 --- a/examples/beam/Beam9points_1/SSBeam_Deflection.tpl.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -<X1> % b in m -<X2> % h in m -5 % L in m -<X3> % E in Pa -<X4> % p in N/m diff --git a/examples/beam/Beam9points_1/SSBeam_Deflection_1.inp b/examples/beam/Beam9points_1/SSBeam_Deflection_1.inp index c806b1487..fec3b20b0 100644 --- a/examples/beam/Beam9points_1/SSBeam_Deflection_1.inp +++ b/examples/beam/Beam9points_1/SSBeam_Deflection_1.inp @@ -1,6 +1,6 @@ % Input file for the simply supported beam model -1.4655e-01 % b in m -3.3846e-01 % h in m +1.5557e-01 % b in m +2.8052e-01 % h in m 5 % L in m -3.3176e+10 % E in Pa -1.0602e+04 % p in N/m +2.2558e+10 % E in Pa +9.2858e+03 % p in N/m diff --git a/examples/beam/Beam9points_10/SSBeam_Deflection_10.inp b/examples/beam/Beam9points_10/SSBeam_Deflection_10.inp deleted file mode 100644 index dbb5f65f2..000000000 --- a/examples/beam/Beam9points_10/SSBeam_Deflection_10.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.5840e-01 % b in m -3.0670e-01 % h in m -5 % L in m -3.2339e+10 % E in Pa -8.4849e+03 % p in N/m diff --git a/examples/beam/Beam9points_11/SSBeam_Deflection_11.inp b/examples/beam/Beam9points_11/SSBeam_Deflection_11.inp deleted file mode 100644 index 93fb9a1be..000000000 --- a/examples/beam/Beam9points_11/SSBeam_Deflection_11.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4481e-01 % b in m -3.1684e-01 % h in m -5 % L in m -3.1333e+10 % E in Pa -1.0731e+04 % p in N/m diff --git a/examples/beam/Beam9points_12/SSBeam_Deflection_12.inp b/examples/beam/Beam9points_12/SSBeam_Deflection_12.inp deleted file mode 100644 index 9cc51dd97..000000000 --- a/examples/beam/Beam9points_12/SSBeam_Deflection_12.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.5144e-01 % b in m -2.9167e-01 % h in m -5 % L in m -2.3100e+10 % E in Pa -1.1144e+04 % p in N/m diff --git a/examples/beam/Beam9points_13/SSBeam_Deflection_13.inp b/examples/beam/Beam9points_13/SSBeam_Deflection_13.inp deleted file mode 100644 index ea35b11ea..000000000 --- a/examples/beam/Beam9points_13/SSBeam_Deflection_13.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.5096e-01 % b in m -3.0226e-01 % h in m -5 % L in m -2.7474e+10 % E in Pa -1.0793e+04 % p in N/m diff --git a/examples/beam/Beam9points_14/SSBeam_Deflection_14.inp b/examples/beam/Beam9points_14/SSBeam_Deflection_14.inp deleted file mode 100644 index 1f44cbc1d..000000000 --- a/examples/beam/Beam9points_14/SSBeam_Deflection_14.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.5213e-01 % b in m -3.3620e-01 % h in m -5 % L in m -2.8416e+10 % E in Pa -9.9956e+03 % p in N/m diff --git a/examples/beam/Beam9points_15/SSBeam_Deflection_15.inp b/examples/beam/Beam9points_15/SSBeam_Deflection_15.inp deleted file mode 100644 index ec40693ef..000000000 --- a/examples/beam/Beam9points_15/SSBeam_Deflection_15.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4885e-01 % b in m -2.9753e-01 % h in m -5 % L in m -2.6591e+10 % E in Pa -1.0295e+04 % p in N/m diff --git a/examples/beam/Beam9points_16/SSBeam_Deflection_16.inp b/examples/beam/Beam9points_16/SSBeam_Deflection_16.inp deleted file mode 100644 index 391f80a57..000000000 --- a/examples/beam/Beam9points_16/SSBeam_Deflection_16.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.6154e-01 % b in m -3.1872e-01 % h in m -5 % L in m -3.3120e+10 % E in Pa -1.0979e+04 % p in N/m diff --git a/examples/beam/Beam9points_2/SSBeam_Deflection_2.inp b/examples/beam/Beam9points_2/SSBeam_Deflection_2.inp deleted file mode 100644 index 7363da8aa..000000000 --- a/examples/beam/Beam9points_2/SSBeam_Deflection_2.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4694e-01 % b in m -2.7683e-01 % h in m -5 % L in m -3.0449e+10 % E in Pa -8.2768e+03 % p in N/m diff --git a/examples/beam/Beam9points_3/SSBeam_Deflection_3.inp b/examples/beam/Beam9points_3/SSBeam_Deflection_3.inp deleted file mode 100644 index 34efcc70e..000000000 --- a/examples/beam/Beam9points_3/SSBeam_Deflection_3.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.2675e-01 % b in m -2.8491e-01 % h in m -5 % L in m -2.1823e+10 % E in Pa -8.3106e+03 % p in N/m diff --git a/examples/beam/Beam9points_4/SSBeam_Deflection_4.inp b/examples/beam/Beam9points_4/SSBeam_Deflection_4.inp deleted file mode 100644 index f74b8d014..000000000 --- a/examples/beam/Beam9points_4/SSBeam_Deflection_4.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4293e-01 % b in m -2.8763e-01 % h in m -5 % L in m -3.4093e+10 % E in Pa -1.1213e+04 % p in N/m diff --git a/examples/beam/Beam9points_5/SSBeam_Deflection_5.inp b/examples/beam/Beam9points_5/SSBeam_Deflection_5.inp deleted file mode 100644 index cda5e69e1..000000000 --- a/examples/beam/Beam9points_5/SSBeam_Deflection_5.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4975e-01 % b in m -3.0996e-01 % h in m -5 % L in m -3.7285e+10 % E in Pa -8.6074e+03 % p in N/m diff --git a/examples/beam/Beam9points_6/SSBeam_Deflection_6.inp b/examples/beam/Beam9points_6/SSBeam_Deflection_6.inp deleted file mode 100644 index 1449607b4..000000000 --- a/examples/beam/Beam9points_6/SSBeam_Deflection_6.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4510e-01 % b in m -2.7309e-01 % h in m -5 % L in m -4.0027e+10 % E in Pa -8.1605e+03 % p in N/m diff --git a/examples/beam/Beam9points_7/SSBeam_Deflection_7.inp b/examples/beam/Beam9points_7/SSBeam_Deflection_7.inp deleted file mode 100644 index 73eae34b8..000000000 --- a/examples/beam/Beam9points_7/SSBeam_Deflection_7.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.4667e-01 % b in m -3.1306e-01 % h in m -5 % L in m -3.3472e+10 % E in Pa -1.0376e+04 % p in N/m diff --git a/examples/beam/Beam9points_8/SSBeam_Deflection_8.inp b/examples/beam/Beam9points_8/SSBeam_Deflection_8.inp deleted file mode 100644 index 02dd6f582..000000000 --- a/examples/beam/Beam9points_8/SSBeam_Deflection_8.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.5249e-01 % b in m -3.2183e-01 % h in m -5 % L in m -3.1622e+10 % E in Pa -9.1722e+03 % p in N/m diff --git a/examples/beam/Beam9points_9/SSBeam_Deflection_9.inp b/examples/beam/Beam9points_9/SSBeam_Deflection_9.inp deleted file mode 100644 index e37301c40..000000000 --- a/examples/beam/Beam9points_9/SSBeam_Deflection_9.inp +++ /dev/null @@ -1,6 +0,0 @@ -% Input file for the simply supported beam model -1.3551e-01 % b in m -2.9724e-01 % h in m -5 % L in m -3.3928e+10 % E in Pa -8.9118e+03 % p in N/m diff --git a/examples/borehole/example_borehole.py b/examples/borehole/example_borehole.py index af4a9642e..869a05320 100644 --- a/examples/borehole/example_borehole.py +++ b/examples/borehole/example_borehole.py @@ -45,7 +45,7 @@ matplotlib.use('agg') from multiprocessing import set_start_method if __name__ == "__main__": - set_start_method('spawn', force = True) + #set_start_method('fork', force = True) # ===================================================== # ============= COMPUTATIONAL MODEL ================ diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__init__.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__init__.py new file mode 100644 index 000000000..8e865af80 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +__version__ = "0.0.5" + +from .pylink.pylink import PyLinkForwardModel +from .surrogate_models.surrogate_models import MetaModel +#from .surrogate_models.meta_model_engine import MetaModelEngine +from .surrogate_models.engine import Engine +from .surrogate_models.inputs import Input +from .post_processing.post_processing import PostProcessing +from .bayes_inference.bayes_inference import BayesInference +from .bayes_inference.bayes_model_comparison import BayesModelComparison +from .bayes_inference.discrepancy import Discrepancy + +__all__ = [ + "__version__", + "PyLinkForwardModel", + "Input", + "Discrepancy", + "MetaModel", + #"MetaModelEngine", + "Engine", + "PostProcessing", + "BayesInference", + "BayesModelComparison" + ] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..beaab3c798a63fcfbc361982388fdf10830a787e GIT binary patch literal 795 zcmZWn%Wl*#6m>Gm%w#4reNc%7iwY!=W|MT&9YUy-LJ>tHAvWGvZenJv`VrYl%kVku z_$5oMSn&(2uy5%A!BI}mJ-L3IBkS30g8WGCJ!aoxguaL3@8LD{+`qQ*P$P`$sE$P> zV;o0;55zzwI02rBR1WbFcq&G6jK{!-B9jw50X`B_nd2PzSj^-c&w*!RNABX?2(3^( z`4Zv1diowM^3Ul}aa0`ti2Ux0$n7sTZ@IcU)8>Yn`a;)Ccs09VExjvtw#7@e;)?nI z>A7mU)|2^C+jePm#jNFO6_gXYVfI{oWQM6KG#`KhtG&>&p@v(nygohUwlb`ts@g0v zHznkn8OyaI#DtJc8XyZW2#^FA1{ehxdw93lHz92|Yc|5$C~iM6-95COF?vN?Mr811 zi@pHsx<`Gvkly|69Kygd?CtLV*T_Q*77pqT8y^K}wpkRt8jkJ`FGD<p-{n*EYVhWs z^wi&7V1rcK5FrEipx<2o$ra*rBSNSUgnUKjAVe47=bKWhwyeqz)~8;YE4>zLN^N<n zt4=c2+VT}|Uw4<~nb0>&+OA93=b8#$8~v#y-UM$6@tM2vQ-8EhuxH^`*|2;P<#8VU H^TfXZNO$QO literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..522dab9e775d3ce6f28ac1ac7102d1843b71523e GIT binary patch literal 968 zcmZuvO>5LZ7@q7$vb)(`Yw-(uC|-nB3_U1_iU(V@1uF~UB?N}qWV#(XA7Lh`T~GTj zyn7KZ`d4yXa$4}@ZK1cGoEf{7geEV~Jnxe?Gw=H(-v@&p(AQ-C6K^#E_-&H))wm?* zQj@PB0U=17q(L3l2pf*!P1<Cwuw{9RwwW8cmba<LI$_6hmv&h%>{;$npY_AO<sCX; z!*FPMm)>9-;f4dIAnAQ`!kdZz5sdm@+B?Bc@br(P&mTGE=6Lp=@RPSfenv7m6bYtU z?H=L`trPbRpAwF>+&<uGo@p{13zdzfh_O<HPmS^#&9FM)M_6JWo8ntmv777)mLf@% z;9B?hh>9gn5szo1Zs|jKilrigLnyUdK)MEugR*6yZNM|oG0@fUVYDfIy_SP?Ms@eW zzs0^@-dDMlVu~^hnHfg~b;0gi-mS|4wsYD8uX#$$?8<gmZl`*Fm|htW)N<QzxjiwS zK(aO^sO5H`@<C0#tg^ks_{upuc)3+CPX3!|Ju5v35v36R0O#5vaKUz;N1v2-IFcvg zm>wgfqCFAk4D(Dy??|?vPa?bPDWW8i;w-{vh@}*(C}$H%k|~Cn$~j^r%QGPfqP2Rc zM<f}9`ZHW~Uh2kkieJfl`gHS?sb3maO~-MT!`pLz2_6^KSb%3mHJ0E}QH=$7SX5&H gUKG{1PT4O&B^KaGQH@p0_uUm(!`w5syrX;m3*dMy2><{9 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5ebaedb4c8b77b5d7dbd0a6945f09079d8b10e4 GIT binary patch literal 860 zcmZWm&x_MQ6i(8gY18gn1P>k-JqSG{?6T}dM8vK_!Ae02G6aU%%(M=jnS`07Zujif zf5Mypf>*&mqE}D;3!Z#4b*sh+`SQIlZ{E!N9vKXJ9;^>vzS3`j=Y6-q-wQPF8N8+d zpdRw5PXpo000q9~4bhNI)O5TlTC$DWj<-Zdc2U>ywg_bp^&IbrzKl@hcvlSM5Dgs< z#gRNl$G*4nXz!Dc?$G`lZyepUPLtE*;)f5XkNw?fzJ0~j`em-)6HRA1WdhW2#!7M< z936reYQ+_U|E;MisuIX>o||&6^Nbn8)ygW*$(EU^S~AU4W|Qwa#Z{Z+vLKq9T!G%d z<R;UsAS&CA!(AWa4bz6_3S(_e(k%<2g@%Qug|>x`g)YGB@km>@(V*B0Xd~Hw+;;T9 zR9fdNQZg)UUnZ#wt}c35mlFxy@AqKlT6Slnd;cYJYlCqYMJEMVfs2C|NiB9)M<-X- z9?Wn3Nouj{4Lz!<zq4E$I6Ii=JV5vB$@Gt}&c0m-V<H5`pFJH}>n!~IIC-2d3^<-@ zw$9H|TFL5qkFkU?Ya;j!DPbP*l995~ES^s0@#SK+czd2)q*oOeG|nVhvy>EtNO@MI z3?P=vbjcMFnwd(JW^?uq+bmtF)LnH0m8s6JQw%=v5@Q(KuKNVKs|0&$M{h;|%^>ps Gd4gX;Q2|8& literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__init__.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__init__.py new file mode 100644 index 000000000..df8d93568 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from .bayes_inference import BayesInference +from .mcmc import MCMC + +__all__ = [ + "BayesInference", + "MCMC" + ] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..430b9885a8c8bd658da24bbc4ac1a6a0a74f69e6 GIT binary patch literal 303 zcmYjNJ5B>J5cMx4LJ1UHffU=|3m}9D;!`9-LNwc0j&0Z#_8Qq<AV=W{T*)mJSD-+Q z7ez4AJilkZnbFwKX1fT29n8%eoF7H}4+7#8G9ChGq_IT~*BBR0EOE4^z^P^rq-J__ zi>jSZ4Au(gy)(Hn@w&S=!F0;N4O=dji%?ny3b3k1d4F9@qTRZN*UX%9YVhQ-5Yk#9 z-ccBr!UA74cU|I&-$fH550AdFjg*m}d(}JBrN}Sabk(o<h4n8tGBtb{^DJ$vgMa;1 ie?z$d-X<ZAo;G=M?7Z%+IVo$z@;g&9#e@<(`ThY0HBIvX literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b22adcbe445e7b81edc8dac6cb9ba03678c61ab9 GIT binary patch literal 354 zcmZ3^%ge<81T4a;sWXA}V-N=hn4pZ$YCy(xh7^Vr#vF!R#wbQc5SuB7DVI5l8OUZ% zVM%9-Vo6~QX3%7N$p}=e$#{#;DX}uO*fTFJwJ0?&ITa|v;_K||T*M5NE@A-^ewwVe z_>(}2;xl2Yz_Pbka+7nD!D?=?$Hyn;<iy9XWcUo!!tg81*(xTqIJKxarYJi<BPSy< zu{g#hKe;qFHLs*N#yzvdqckbTEhoP`Ah9GP25fp+VoqjCQGNx4hp;Oq9>~rtiI3MS zsQkrYlbfGXnv-f*#0|6t<b`58An}2jk&*EO8v~=x1qN+obb~?c0xANkVimo?!u5fb PnVYSF9R!OwfkprT7ZzXr literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..287257c1ca9b3f3a6d7e176e006ad432f8c685bf GIT binary patch literal 368 zcmYk1K}rKL6ow}=(^{m}OStJ`3Ps$Ah&XP#s0cD3Lm;G+HyWDE49TRlE<J%4@Bm)H zt+$x1E3e=}d}$GVkT3tA{CT|a(P%%wdU|^o&$xeh^S?qg7r5*ZLIi@SK$DyhuR|5; zD34G_BEApvSoCg#asQKGbWFN~OTGa+t4c6X6@Vx4Je{Y;w=@yrdfe*{7e2(~Z)$s+ z$GXtPHq-4f#+731H86eu(BtbRJ*AliW2u2<J*C2Fx85<)vI4`EeB`aHtE2?pIs?fp zy-BXJd3JX^IiU+Dl}HNBmq2;bC@PDF0wU2REoH@(0qaz2SJMaPQ^r+vJLw8L3sbLm h?r(0&P|KFFNwet&XSx<n!MXpX9Uz8e7=<MK{sG1iY1;q* literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e89dfb5e6b3a873ac2f40dcc2084aa52caaedcd6 GIT binary patch literal 31276 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f059bde3e71ad6231b8a26e02849bd6298052797 GIT binary patch literal 60952 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a37330680c29bbfdba5a1bfd98041dda24957604 GIT binary patch literal 31419 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57322b839ff7d50ea32d3b36ce011c09cf91e232 GIT binary patch literal 15645 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37d75830876e7d6e44eb45cc242d1f6636c8d2f6 GIT binary patch literal 27157 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%0A5<{ zRV+xD9@IMT29nl=O7?GHp;mJDq-%Sn+TMhTK+Tr7_9gaZ>YEb-8Rw??%W0=4VSdou za_<V(`T1w*U(z)HyyR%7MgPRAqkYBEo_uz}u&{6O@N$c^4T8fV$#LkuIqeww%xrSQ z@d!bpDDf=)n>Qt%zr!bZEc~q<AJqQ1YSFpW{z*sLvmZEQs&l{8asa^Ql{5qN9+tb% zZpy-~VayysQ*7bxMxW@tk@D<V%k}}GsLLbbs@GS+ZF&X^{~@Ee2atlc9BMl76jGN+ z?J~d?ROGCI1vUiU;BQa>H0a^N$vhaRgAwzf9C_3t4c+3c|3zX9TMo9M(NuOZ!scvX z7EZBX>9AV3JNqLuQ_OU9z|Dky_cLMuw*9P)537dX?SB<+;|va9wu*=+uc|&7hs~Ks zzNzVz3aBtD4M+PrZpq5%&6R&6^;oHAmO_)V!YltC`dK7lfa$*;8)J_m8B-J`@Cw~c zP{6dXBJe7(NFi_qp7si>oSE`i6wT`#k>xe7V$!@&DP|GUxS1;&(lCf0qahXAz=nuL zy#acdcHA7eg6F-#r1MA3?>DDgc1kTf(+zzRSVYw>scKie_+hCF-h;NM4G(J@-wwYO z&Q#Rhwa-Ixb|+htmm%}l^+D#Z>-&qoy??lC`PrpiKRNixK}h^|#}`(T%WcUmKi;{x zf9Zw$y{T<O>1{(2Lgz8bc`R;!Sl*yY+Zc}OrApfuFjd|#yita&PB1KMQStobjTxE4 zw{AEa050g{Gj&S8Z<sSpa5v#fI9DVTy$%Q>FQpdZoR|hh3<G|C&JxvNy?N(AJyT%# zaxr9dtt<;SbHVc4kCjFt&3=c)vq5&&=Ap{8Q8MUdFD+UvkW0K8Lom;RMn8@9Z0V*U zX36UpF%4Eo&Sv>HLa|^K;MBHQ@*!Bs$M{n&IH^6aD`DPEu{37c*fmk$3tgAK$Guk| z-NOY-tpy}$6$ghS69($X_{-(5qf^^hC@-XoSvPi1{B^ZtVSc)Dsd%<fu~=D187qDa z&TRZ1Csf5O2&>;K5*&*)`kpLkBXvaR#~(wdU&N?T9R~$7?P~xVF$(68L8yh^q_KAh zwb~IBE2R;njjh*AFj7CgRTkZ*^ah2K>b5>u3k>5%q3(6-O+(=<(zgN7{~ekXR3|~8 z`RWh^M()I3o^>-va0&GR!{Vk7u`qtDE{=2dn0>N7m*&Qfe}(O&i_wsatNj)l^yP-j zojuv8rO4e2jY896b76mhdP8SE!M!o{r0UN16(gkOW|=b2F-}^4m2q<WzX%pA@NGVm zc7cCByTvQ3ofUexF|CP~ezr(Lz1nb#z^@nZ&#tqN-FEW0)%feydD_pXS-iijKFc(* zh&S&LvEw{kpR9hkK1IFZ%Q`5V#vaYV&uJ0Q0@=<v14KvsUVjN#z4YS)V73eHQASY& z^_Qmhu6E=F%yv5H8}s8aA=~0J2qLsBX1%1ui@2YCYC{y1d8;s3U$wC0U8GbD`zm_- z^A4l}2)p*I@>%*$V&?6+x8{=P7B;8rdZfA@^;O<#Jt7;zkC<3P0k+hc$HKv|C|jm{ z;$^=m8{r~k3&IWNYCwoylFdQis6RMcP3o{a2ha-c(d!4?tj6NoNJTDwLGfalb&Z6( zNz2tJZtm$Y+=JkRH0qB;VO%i5-z)2)m5t?{E$WV3nUKv<8i#1U($UfIHSBR4y9Cvg znoZYbBy+PaBP{;A#%!lKV0|#fG!_SR75Cf5n?@~sgwCpg<$;zv#qv<3^v_m2fPYj- z@Lv;Oz<q?|eX=_!64^!k`jvX?P4rfTyv2Tr?y7iJ`7A|Jm2JrZsS;o>`!@u)jLMzr zd)8;N`6wyq*s2I={Son4>M~y_6o&iN*pzQtF1;2Fj9q5k6p>4>Ykt@mnfLP5h-`|6 zr)M|49Q9v|j*h>!zBA_@(ISlAv9g4weZp*gj#@i0N%}u9Cs(Ts<qY$f^^OdBzbxvW z7RKS1W(00vo$_7w3xJB`;wd)1B68XJ{-dXd`oH5HID7i+bLSLCDARN>DqABnqcrL< z@cbccsU#mWxrm-9lJ+=?ChkW-BP1I1i|^3A<vJ^>Y`La<m%!1?%i1C$TY`R!RRPXt z@CP0bU}%j6VF+Q{Iu$v7l9Dh*LMY%RSW?iC;&qn8HS&;@t<;QwAmC9($+8@1n^%Br zrLvNhCfi(5kQI;&Pq`xX(@2tSXa#J`3X9ie^8n2>aTJf0+7}T5B%7#!M&C8XhC-}D zF7{7H0&sp4X^EB%6XM7Cj!+l5FEUgk8z?rFtk;{4XUuMSLgq3`L-PwvGG=3Ob2VGz zwg=Xd+og#U3q|mENn5)lD>=SoDm>raB2{&!Dm-y>rebrdsy$V)Ic|Q)*w3;c9UcL@ zN!Om0YR|??GY;q)l{V*R6aby5b=?i#3Ed6d9EOFY>OliMdzM<3T9;Zs2&WtNNDX_) z$qJ5W2<})DhQ#g%71ejG?>XM{C;OAp4_;g9{lQ$iX}8q0JMG#dx%OmS+ZF~TSMO4b z<l2>K1{QJe+L9^L(6rF9w0o_%sB+V19D-j^u%-rIz*nf^_K8&Ov4z1uIQ@I4m#dfk z>FtBk_CY+tC(RE_{BVjNe!!RCKAE_l=36AbCB?U}->JHtX}(Y5`%-)#Ob~CLxpn5f z_V;E0gA^^6F7<z8PdD$8n)jsZ_e%A9RevKEb$(BZZ%y;965ooO3}61{savNq)eWhN z-S{l*Qoa%1-%AP?n$2jZy<3FeAb?$j%6;?HZFtPxBp*3vgH*R=p?9TjJ2r?VS`sZw zE%D+9HTCno^TNH$3tQ4ny-T~KzJYYjpj0!s##PyzEP!tukf2MM923fNo5RoGCSCEY zRPihzsyfQLt|~r^d@CJyOG#0*B^?XH_cvu4wgB`oE*S5fUAEjeF2!KpsjPx|r;-q# z%Bpxj`D2yc9$w`eR`>=WIuZkQGQ6Fhb*%6mNjR`|Nqkp|hl82@&C|C|r(ApQx5iJW z`5}oPO7TPL<30DQ=rOEugDHNH(m1Z9%bM<Rs^aic&C;tssl$!($uzXVlxJ^5fvEiu zK;uRGSvBnkAH&VL=1@>3Ri(rPBY}W^f9}Q_z?4;!U@X98FlCer_zPh;m_2#p2?Tr< z6@p-`ru`wJ&@@&qrYM@BjH;#y(5mrZ6rggjOE0{ZV<(tk#x4+5X@a0{h!tz-b)_j3 z;pgB4lvEYcTpsitv%)lCDRfJMi<M2#?Cyf<uwxExO&dFE2{xewduVhefVllQYJSnK zuN@TA9^_Z1>JJ?9bHN#^^s)Jsug~vxJ<_NsNCT#!Z=6PDK^jm`9+O6uuwglbY6eS? zq{Xgvy-|kVD9ydqe#h3S%%D`&bS<Ueh?zD}GS#t!aitpjgxbRPMyjfsu1mGxL>Kg; zC8-&6d0PFrMt{}KVaL_RYI~tu9{SsfbX7$=pK9TLwr`QHd1Lhp3Te^zV3>sB<$~f> z4<)o<yz1ufV-<9v0cuyHuNBNd#Z?Q`uB>*I-GQwfr9r#3**2)7XU^dy4j)5cHAXWv zEi$BN^qMC_SXqwW1oX^F6HMzMaRk^b&RkJTLGPb|B*u(Yn&Nyzt?W@Jx>kG(!Flm_ z5$Xhb61JH@-;SHCIB#bRGP?yOKMf(km+4%GOp5D}L68ko`pp>^k=R!W?YgGg$W7=^ zNiuRH70B$)A?5Rf_GC-)+4;)(-g^%9AzMU_Vb?l8?Te0G@?s+!G)+i}m%>-ag8>}u zAe*7k_#?B$ZF_g`?HTQRL{)}z_)qX9{r~~q^p5WL@7)U#+=fjGenly>UcD5EKr4$d zAQ}R{Z<-`(NY=2#A<pPdVSJxY*O;_!u*Uq=6k72gQ_<!rco)GpQeMBdWo5Li_&rLS zAS~IU=z&oDtm8P+fHa-ix@T~vf}fcn&aiz|SzXa%oOt&gx<2}|zy9-oN7vesFOA(h z#AQnEM-(g|7=f$SAJdONq2Ny`_!krmP;ixk>lB<sAQz)=X!t`N@JAKFyj;~Kn2;Y4 z|2<LvOQN>YtLwqQlw3ZMQ#ceNnWtB|8Yr(d>X`ViD2;!OAm@+OMd{hpnTL)??Y&fe zF-5fhfdYw$il%&#%d&ku5Ja0~k4%z{qu4KlvSTBbGD>6<#s?I6HawJy7^3T4u`r_* zwe}Q}{wh5|*N^YhY<LBn64uaGuBI+-d+6{yMpb~=SY3N}`<?E)-8YNlrucItM?##R zZ@kx>uJA||o>aL9Zd7bm{kUymYWe&>e?Gl+P}(|(NtJdENzNg-@L0IAiZ?IZx-f5F z8od9V_=U9nlw>~@H{yk(HZgG*=FlRWhXwJ0hmfg<Zw=3T7G8}Hr}<uq?@jT&xu*eo z)+zCwDfS@&8v9`G{(W-qg6e@FKAhpJNh+TYEcM1urTN_wzdOY~N`B*a4-nx_7Q_cg zhF_l_vIKRVYu<HtiU`>bjNS2L8NTYxlebRJzXUP;WSZY4@w-y&vsT8{J!634v`&Gt zmaJOqSFH8(PpO+}9$HJ@wBNEPE-kp?_O!K6vi7B{eP~=8f7_O-+J*xoB<uE+bvw#n zD}A%{R%zl)+S)2vTT|9nJgai7R<^BFwxugKOO>0ceAqRE08VER#7Az8%<oV0n<aj8 zihVMb)!&Goa^)%448JYmO7Yv~Pase}%XQFeY!2u(HnM-)aE=86$mLY@o29o)<LsZp z5cDSxk<`N^auIUtx0A>xIKd1vk<NMR+gOM7@_MXbNB&%~&U~Os@Yr`<Om07m7X20q zw!~o*gHDz&NE1dY(<^0+5+@^k4W;pw|H&wM0O@p=0k6fr=E`Da8%zF=k>E6%33?!V zZ79K&B~=MGM@Qeka=Lu1L@|0K4B}r!>+)&m_w(zXs&XzgqSCz3fM1%e9(rj{FAvXE z2*s~+bCpqzc_8nUAFB|og=ZbiRmG|{mUZ>D*OgP1cViX${F&=owULWe;+%nMp+qPZ z_zxk;f2>OLa}MOU@dgKnKCQVLI&W~U7OB<7Y6{-fVJwi8u<nXEVs%0pOg1I?_JeLy zp)UorfwH7(n$ji`a|o5Ox`Oysi`5&%*O;&JDd^fs)pvw~%^O0cP|i$ikfS~(S&Ch( zRNo}k0&R$;S_fU~S4*`--_|Tu=LV^kCRL+bt_Ji?rZN2(6*kS{Idsn_q$lb*=VOd> zx}GiQr-qmlT2bSBro|?`!EnMb=R%L?hXfTgdkM`k7tGGZf}8RcT4)T<f*&ll>eGNp z(|G$iIB1q+9X7u&u#I1H^>drDcMWrmx>DEY@`%;P8pe&WO|eFyT`=K9l1;fc!sf*e zy>WZ42_@aw5V%?2Gi<zQW_m77v~|-u%3`7XG9wVpF_W-`>KejnJ#)>-ZDaFbr_c%9 z;tBgq@Ccq*v%WvH^<3QgAy&VS@uys@HUBnYx?Le`n{(^d9o77ZHNd^NT|bt9PW9)~ zKs}4~^@NuFG|(NJ&=o7ut{usie4PB9&<*5aM`8N3@(7i>*sb|E`8%O!qu96mb#-aW z(F?u8&c(jMymYkfD(x=P@P*w>$KUgwS=hU{?<-?&&c)R8Y@DRaL&x9m`-hNyRgIXm zVa<Uk+2a7=eu|@1anLH;OBH~dt^2@~FM8>~#S!n6`{if=+e6&Ay{M*xx9qHut2kH{ zTDMBfTw=*K3sXq;3{urn`^}wNe|49uoYN}P1~liesCtWn7(8YJ6t$Lu9TXnKx@F6^ zhZDsAh#u3x37#UD7ikB+c|!EVQ?&?3zrfxy3J>8B-kC$>DvU2^)i4fWJB{eSmi@l2 z+Z;gaEYqHqQ<-B$H(b%&;J|m@RjHKQ`1v?t#p-H}8OA+{4<aNKQ;u(vPhXzV>c=f4 zSk;M#r44;-{iPqpYT6(~+FJJ|9qt9$7Q;Mu<z1=3lPqxKhXkJYXT+>9jpSX5v4Lv< z5#f#-8kbE|KKSHL1wybT;)I52fEk`*@i*zcarCNeoxowJq~k(c#dfcvu^^6ZD2>ca zPlrV~{32TZhwoa1stbjcF2$3#I^y?@hQ*MVPW8w}n;m$(u}g6_SI&LNqdXfV(uLND zM3CJLF0-k5{@{bnTRwO`IsD`27N1YG?V2Ba(BWBV|AWro>-=cz;?^Z`dEh74(p!(* zcii{=v@YFoLh3j%U;0Ee@Tz@n;i=`)`!A-ON2KPFlygK;d(4rsaFk5sw$ZD!5A0G{ zcqE`ekI?qqhz{j}grbbo-@px>#)@%<yY*M$>3g&?gI3ei`8exnflQ;PjY>~@jA99* z$)@S(G|FhW7NJD4y<$_mzzMn8cwZjl790148g-a@fOs)_z}=GU|IyI<LklfGIR3%$ zAMi_te`@|i^OEl;)=#YI=6xyWKGtSm8oI=Xh#~$Z1vDEb@P{jP1mz`o4aV}|^d+BM zECi;&9IktcL~`twi>_m=G3-r2;oc)!OIX=+XAtww4PP2|%$klK>-^H-@tDN_Ok_4c zj`L**o%lX}&z4~H;sC0ke>}=g26#ja0K`8e;^Iqil*c*1;v;%!%+DIx4BRH_KZX*q zf))YZ31+wL(OD{TG0hEcIP{1l?QFds9+53$*x}$8;RjHS)6N64bP8w?=Q&S==rm%v z@(T6=1mG#EK4Lj5wd_RIb7lCiR301&L|~Rk-mbG{IC!Pq`&w_$TzluyV;=Eu@K7#& zMhuT;PYBOqZ~x{<_U4b#%ChAuo8+?P68jea8^z+;jPxF3XXO@vbDj<jHn$7Z;z0^X zq|!ije?~voDEN$m|4sqpGG>&rw@3U(^nhlD%uo1cA`w8M#1mvYn?(_?GUdgaL}8_^ zl{0WF5bv`H)Y9HjfAlIX7RA16SIFT-aVsch7%n_6%+C;*EB=fk*q(z4AG<Me4vn&{ zvL9$Jtug`Zv&3!)FN=iDneeZmQ>CNRY}<tR=ZMU(L%BTX<KXoPWT@Amfh`&z;m;|; zFDM`cP_{6Sfrx_T6^9rS8ezB~o#ccuMblq4;}{-qKsHP&casb=6#tH1m9lQg_Cghn zdmHghc;cYX@!tku6DL(2C(O_K0ij<I>*<;C!cLrJb4+o2kjoWk3a>w?94C(BgfP%C zdYOZeWfVM%_JLetW)9gfEt|&~e=i+FJ;PHBERD3FG>nUXRiMC<r$IW~!3xeQocH7E zUdKf~M{y%%m~KEN+Ziee5bCim3=b>&QtT7Ad|F#Szwi5p-aYirk$Xp!9TxG@2URtR z%jv3Csj4+z3|OtkdG~at%9X5JaxCLeRbx#V@T(fauWHI}+5l{xC&%d4<hHc4TXJ@< zaRGx3=jc#~{hs~tnNJ(w=a6pLDK!8#oG{q&l0wD90UJH%Td=dD{qBW?@u6$es%zVd zYg^jYCAqo)%T*#h1d0BPqvq|Aw?>lt(~d4|X-%<D<{Q#Ktai*B-r93#531F+`Gd{} z&U*NBcP{MyV8_zF<)KfGq@4qja{$KwwtCdBtv+#Tt=3#~76+x|!!OFXmJZ3iGvjPq zxQg~@sYiRX5PeI1;>21NSKqek>REC1q+L5D*UmqB?vv-2Po;Msmv$ddyN)N0W?FWo zT6Q6J^0|fT1>cebKIg62af={v5_>~jt*g$hE6%M82b2?W68&pdL(P7)LoTo)i+NYF z_nn4&4M@*X`}Xi#!}BNMkT9@x1-oId|GYmjoOX;zj**mOgx;Th>uko^3MUeAsdm}$ ziR*qlfXJG5>PRYh4bHKlfXCo@`{Y|EAJjM8>qPq7?rmG>U#`6GA?oHrYO9WV=R4c) z;S8kZmizmjfV%IUu6x+8y4-tzU_<H>&b|5jbMMYAoLkzAl}>8jhaEX+D0f4qsqOny z?@pnrHR-0kQqx{~x-W4YUFve*voBeeUj4*&|M{Qy|MaEI_CrgZsqKf95015Q9myZy zvt}}FsZX56DL$z4iMLK<8akJDWLmZ^48w`##L}xD9ZI+CgBwLn6Wl1Ml@P#<q6WQ9 zcO_hH9rg=7pLqUZYsZ~aiNX2Jna!R%BZ*`4$7nvdC8sCjYMj3^U$$UgxU&30rm<z= zxy6_7(*edVO2kEJy6UNWsR-1CLw82*jwD!*oqp?dvhvQ^yJr(;A8zkk^8Mbag;Vn< zlB4gOo<F_(Qer6A>jTN^r2j`#?@uiaEZ3wvjz}FxGClh;-Fq^dw=Q)oSAOEjbaZ|Y zT(faC4R8jk*#&2y8f=C}@VB20n`k1goi}lH?s%yJp<5G<`BN!tXWH5+Svzrq$JnEN z^-j}Ww!M1@lfh^kG7wx|k*LDPrkdNQloN(hZGFoD=Hhc);*Y2J<3v%J=ubFqpIqfz zR``}=*RltWM5;3j{8?D8IFdivw-5o2uLAm?T7idW_`QUo@5N`qrhFs3{{p6+jo8rF z!{{FK`4NK5IgyZDW<m5AV5U6AWE31U_`mSjW2dv)$nfj+$|YVpVQnTz_q^9j+kLWc zigBJ>c+Be+NfZ$YVPNNviBHkp7zM)=tWrQ`C6So8a%>&}atdQ7Sze@oFp<b#A-JLb zTQgRhtvJ04!B+0z(}v8k;WbmSdCMB74;(wqwQHOjOd0|PGh@63;fp5jDWtNwW6gBL z+_=W+gF&Omj3KQCFB<BJNFN+HWQNa_8a!<rF_;}|oF*JKdX4nxt3oEGvRZpw;!Cu; znxWWFUl#|cHU1a@4zL>w;DL$maa<l#Z^WO|uPUGdwB`i^qup7#MBGnlRBB!@K@@7O z@-6-|iddm}KTY0=IHixin0zIdD}uOs^qz8NAO4#h{FgVfX(mG6m%uLMqDi>!iYF*R z3=#-U7#OT71wH$v^`J6t4vUviI(*=)h!A|oU|6#h8HzCL5R~9_xfEBWd@`Kv2K$%c z>QeeohO0^CJ{hh(rT=8Owv_&p;hIwVPlnr;(tjWq7>ZuEy<z_?dwlfv#GAoe!TFu{ z_L2y&;7o7YDQ%+T$u{lIY;vbs4}i0lAH>2`eh_Taa0qvXLs*6oSYtK=x_smCGxq!! Kk9o_6!v6ugi7!zA literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b58f792ac36504c702205afc34228600f9bbba77 GIT binary patch literal 15716 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc71688a4cae4f74ec3a67838fca659881c520c9 GIT binary patch literal 3806 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 I`#)>`7Zrzs-v9sr literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f1c5c8635a64bcf45f856426c8597e67374b985 GIT binary patch literal 4661 zcmb7I&u<*J73OHQ@=7aP3hEZM<3_Y2*V;s0#LlG^k^+*IxN>5ph+U)*wi$6}xVw~R zXSO6q(ppkspg#EELxC3Xr3W9<Bt?RvhaU20SjGYo1}IRVryL4w;PjGH-{Z`1SCR`f zv_uU#<oofx_das`$;p!w1X}&xU-|E*3HcWe@-~`1Jo^beJR&~voq)8RHOIl{kzk}< zSSvVWgj^?n;Xd(4KOQ0EGx$y0+Nkf`B9-D-I9#nb$;4aRon@{>GgMx-#{9{5Jfkpt zL^xS<e6lv;J8K31gkQYxfTXeeWUc6rg1k~vUKYxeyu(7T%f2WPGC`pYO;RslO3_9n z=@RRLMix>LHn`-W$7!4ER^(UBrVlvvc|(Mp>K3Px=WAf6<SY=nOLau+obunqEWqcj z7SnW#Qx9aeBcBJ9g+66Qn$N*5VeF!s%Qmge(Hie45kw)aRjL%!c~Pi@&!th=h=L&6 z5+Rz}W_n@5h?$+OX}+!Njh*hEyJMbrGHdqs=$o_#OIscbc5d#?)xd7eD)d#WXnuA! z6|>a>hYy<on%@6#XVu+_Vhy5d74Whnx#FQ##vnw2HyYf7anvx@v^i6;<ZW0(xs-qm zI-I&LLgsm~WL~#Q--b6zv^#<D0JeE5w803lOA+>sG^SuXWxg-8*yQv&i<JqFFH{y$ zx+Qdr-sLg^&9D@dHDPH8$ZawSq4aoa7t>N~8~<*JW}AUG1N<!LV9@}tRlqBIv-{dS zt(kogmK?E_(0~9TLi_;$>*gkxN<a|7M*v>bCDSmRM_;14;&RiBX(tk)Hr8R}2SF6H z2GHBMbq(|aph&aqZn_)vF^h<i0;qtK^%#|<xEM?}SrBtHuQq384&?%b6;XRWUS?P3 zI_6}aa<l`vlxN*;o>oK2hTsh?804U_6f5xmYI(+1a?o!>%H?&?q)`Wb1!N#~*(MVK zs|P%b>nrp<^Oi0y&<`+4?u5}+2oU<h$Lbt7Ou@P|Ino#dB2Zz*P!amP!=Zz89!hPM z0bzA4Wjf;UJ7}3VDmqLuBpE60a-ar<VKS+f`3^OmW#L}s%^L7wn|*lIrpwBnYoypR z1>;Rg3@iZxL4WgdFbXm;7*UMF?G~h$;h-%M1jt|;n43X2CBjr9R(lNfBsGKd6k#XU zG&3IZ-ITNuhU-L_)xbRMMllUJxCV5Xu_vP)DWEvoOg4cOz&63?`U*;1PuaLiS0kNP zu0{$4OsvTiY>h&&jRAv%&45z{RmMPE9B2WI0(6OFj&}HhH6zeq41*v_!I7%6!p$K$ zo&Z^V7j;@tTp0nEZ8Jk-Fdigy0qT0g%psa)9%q0UfyG<EMrg}XANY0$7No!c;^xSK z?6hL?5SVbHfC1QaZaquxrS(d61(+vw9m+h`7?-Au;*O~cD=y<zTJO^Jn|Kse-!p5g zA*7#LpQoI8t&GAlDHt}$i-@+^CQma3{W})E7~^1kJQBp)7y{m4U>!zn{nDlNR18p+ z=jv{U19U)I*2vp9mBlBFgvyQsp#LbW!v6dOxU_DwK*gO-BoRjy(FT*Lf+4IHAPYR; zX9)m?K2z0YrrFzAbXM&<88sX!l|vzeGpfp~HlrwJQ#Z5K3OY_InKLFpCf_utA)em> z4a6NDh*lK&5PUc(z}xH;MU?XhF9KvnenOH`?*FQnU$^j1gjb>h{62dPx<_Q!*(EMK zrEPZvMvfg7V3c2>;9>?>Bxki!NXBh4C*w9a$;1H0%4jmGc+imJAWGsjP?n)nXa}16 z?Y(OYwO_*FrfTv|)CyXRsoHYn#dsA^wd+FvJg(R3c)@}LN%%6_uJLUKHvq0`al0;s z-{h`VF{Go=v5w&I4vwrhyIp%XtD&LUJ)qj@CM6f%3GKRfPh(Z)Z}QnU(A*cHyGIVr zTzD}0@KpZi>@19?9>Bk6@S1oQ9~czj*I+vVvq!Pj_$F(+WW(<J81VjVfH`sPIv--Q zVMnfw;_&Qa)OoD!I{wJ#g~OL-hYauA7|S<7j8Ejx`i1<7kPQr;X@~ZiOFd2>wR^}? z47O?dO#VbryY+eFWIlgbia&bC_$%Eetanf4tMp9%M96oQd04|T`Sq1O$np&<`!Rf+ z9B<FJc6Vgp&_Kdr4GwvD6?R)p@k53E0Rn6b|2hvjT=U>8N>kdNK*Ow`QONMYWN0Kk zl&ma#pC3(^k24Bz1+I7=qd-B}8(_v7Sew5{uNY99R);;wF59Wl&23)*K1wg9xEtFl zR45#)KxX-xIZF*xajo*JAufKO>sW@zbXi5_B){sKJHP_m-6S(Ss#*-lf6kgQPea!z zQ5Cxt#SbHzn=|BWGA4oMqxM%=fAAeyZnJH-<8jyLO^MlBc_A6MN+jl{;k0DjesCsJ z#!EQV-1PG=DL1qDx^FEf&aaZmVIPvB(oCylvYCCKxOaS>lqB17eK=~8;til9ofHBd zCgV4=JC906@!(C0U~Q8pW2}Ss%t}E{qCuyjOUn6L;cqLn6P%Y=WywU7>nvJ#e=y8- zgZU*`r~VDyJ<_M-?90e^{~04^XCE(rw7P%h_1>A+4Fy)N;GbUU#|Nd!ho`<QU3gl$ za4`A($5;9VGXC<{WMur*H`w(}H$i@M{!gpDbMp^Id!;iVk6!G}T>0DV->bc=EBiAy zdNVgtap&OO<kSQG@VC9GOZ(-yUU}}*#i!-VPs*1Met7o5^23#X%*_7z)~BaGf2mhl z+`qWgySTJJbFDXXtxuejH=VTqefePe^dHB+oTg8w>EqKMz0^DZ(=T4_oqxM`{+<2l zcYD+CJ~2Q4ocdmGiase(IRzdAh{%Kz%XPIfhUWr8?YhZ?>%ymK9N_b$>*7~>_U44^ z`jO|l5;;W9LiZP9gc-mkGP3F5{||^lZ135B{gErhQlDVga0<nXeR8;)yjVQnC&#-~ zJW8$<ld|$er&~3NB+tTJ^2(vJvI<|-GHL?Dpa(oqRk%JvN<$uoDotWzV+FPj?Ebd& zM(Xd+<UG8<icn4H`US^v`X%C=dqQ3u{y89vPY(a|$6Ut&`=8%`ZRWrEA8(Bz{{?Rr BCMo~` literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f154800917aeaef9c499abf13d47fcca6ffc639b GIT binary patch literal 3869 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 C(w;v6 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d2122246d54ec5697803cbce28900e077b2306a GIT binary patch literal 18924 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 W6YnAs1G%l!A8`@AH@FHoxc@Kt+VTSc literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e0ec7bf61abc72bc8218d603f606f1eca2cc9ab GIT binary patch literal 35893 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 IcNqr$ACvc7^8f$< literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9fe4689524895c2149048d489b22b08e85026df GIT binary patch literal 18959 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	o4MB>fKYEXpNq!HIDoLFs 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_inference.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_inference.py new file mode 100644 index 000000000..1898a8ae6 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_inference.py @@ -0,0 +1,1532 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import os +import copy +import pandas as pd +from tqdm import tqdm +from scipy import stats +import scipy.linalg as spla +import joblib +import seaborn as sns +import corner +import h5py +import multiprocessing +import gc +from sklearn.metrics import mean_squared_error, r2_score +from sklearn import preprocessing +from matplotlib.patches import Patch +import matplotlib.lines as mlines +from matplotlib.backends.backend_pdf import PdfPages +import matplotlib.pylab as plt + +from .mcmc import MCMC + +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class BayesInference: + """ + A class to perform Bayesian Analysis. + + + Attributes + ---------- + MetaModel : obj + Meta model object. + discrepancy : obj + The discrepancy object for the sigma2s, i.e. the diagonal entries + of the variance matrix for a multivariate normal likelihood. + name : str, optional + The type of analysis, either calibration (`Calib`) or validation + (`Valid`). The default is `'Calib'`. + emulator : bool, optional + Analysis with emulator (MetaModel). The default is `True`. + bootstrap : bool, optional + Bootstrap the analysis. The default is `False`. + req_outputs : list, optional + The list of requested output to be used for the analysis. + The default is `None`. If None, all the defined outputs for the model + object is used. + selected_indices : dict, optional + A dictionary with the selected indices of each model output. The + default is `None`. If `None`, all measurement points are used in the + analysis. + samples : array of shape (n_samples, n_params), optional + The samples to be used in the analysis. The default is `None`. If + None the samples are drawn from the probablistic input parameter + object of the MetaModel object. + n_samples : int, optional + Number of samples to be used in the analysis. The default is `500000`. + If samples is not `None`, this argument will be assigned based on the + number of samples given. + measured_data : dict, optional + A dictionary containing the observation data. The default is `None`. + if `None`, the observation defined in the Model object of the + MetaModel is used. + inference_method : str, optional + A method for approximating the posterior distribution in the Bayesian + inference step. The default is `'rejection'`, which stands for + rejection sampling. A Markov Chain Monte Carlo sampler can be simply + selected by passing `'MCMC'`. + mcmc_params : dict, optional + A dictionary with args required for the Bayesian inference with + `MCMC`. The default is `None`. + + Pass the mcmc_params like the following: + + >>> mcmc_params:{ + 'init_samples': None, # initial samples + 'n_walkers': 100, # number of walkers (chain) + 'n_steps': 100000, # number of maximum steps + 'n_burn': 200, # number of burn-in steps + 'moves': None, # Moves for the emcee sampler + 'multiprocessing': False, # multiprocessing + 'verbose': False # verbosity + } + The items shown above are the default values. If any parmeter is + not defined, the default value will be assigned to it. + bayes_loocv : bool, optional + Bayesian Leave-one-out Cross Validation. The default is `False`. If + `True`, the LOOCV procedure is used to estimate the bayesian Model + Evidence (BME). + n_bootstrap_itrs : int, optional + Number of bootstrap iteration. The default is `1`. If bayes_loocv is + `True`, this is qualt to the total length of the observation data + set. + perturbed_data : array of shape (n_bootstrap_itrs, n_obs), optional + User defined perturbed data. The default is `[]`. + bootstrap_noise : float, optional + A noise level to perturb the data set. The default is `0.05`. + just_analysis : bool, optional + Justifiability analysis. The default is False. + valid_metrics : list, optional + List of the validation metrics. The following metrics are supported: + + 1. log_BME : logarithm of the Bayesian model evidence + 2. KLD : Kullback-Leibler Divergence + 3. inf_entropy: Information entropy + The default is `['log_BME']`. + plot_post_pred : bool, optional + Plot posterior predictive plots. The default is `True`. + plot_map_pred : bool, optional + Plot the model outputs vs the metamodel predictions for the maximum + a posteriori (defined as `max_a_posteriori`) parameter set. The + default is `False`. + max_a_posteriori : str, optional + Maximum a posteriori. `'mean'` and `'mode'` are available. The default + is `'mean'`. + corner_title_fmt : str, optional + Title format for the posterior distribution plot with python + package `corner`. The default is `'.2e'`. + + """ + + def __init__(self, engine, MetaModel = None, discrepancy=None, emulator=True, + name='Calib', bootstrap=False, req_outputs=None, + selected_indices=None, samples=None, n_samples=100000, + measured_data=None, inference_method='rejection', + mcmc_params=None, bayes_loocv=False, n_bootstrap_itrs=1, + perturbed_data=[], bootstrap_noise=0.05, just_analysis=False, + valid_metrics=['BME'], plot_post_pred=True, + plot_map_pred=False, max_a_posteriori='mean', + corner_title_fmt='.2e'): + + self.engine = engine + self.MetaModel = engine.MetaModel + self.Discrepancy = discrepancy + self.emulator = emulator + self.name = name + self.bootstrap = bootstrap + self.req_outputs = req_outputs + self.selected_indices = selected_indices + self.samples = samples + self.n_samples = n_samples + self.measured_data = measured_data + self.inference_method = inference_method + self.mcmc_params = mcmc_params + self.perturbed_data = perturbed_data + self.bayes_loocv = bayes_loocv + self.n_bootstrap_itrs = n_bootstrap_itrs + self.bootstrap_noise = bootstrap_noise + self.just_analysis = just_analysis + self.valid_metrics = valid_metrics + self.plot_post_pred = plot_post_pred + self.plot_map_pred = plot_map_pred + self.max_a_posteriori = max_a_posteriori + self.corner_title_fmt = corner_title_fmt + + # ------------------------------------------------------------------------- + def create_inference(self): + """ + Starts the inference. + + Returns + ------- + BayesInference : obj + The Bayes inference object. + + """ + + # Set some variables + MetaModel = self.MetaModel + Model = self.engine.Model + n_params = MetaModel.n_params + output_names = Model.Output.names + par_names = self.engine.ExpDesign.par_names + + # If the prior is set by the user, take it. + if self.samples is None: + self.samples = self.engine.ExpDesign.generate_samples( + self.n_samples, 'random') + else: + try: + samples = self.samples.values + except AttributeError: + samples = self.samples + + # Take care of an additional Sigma2s + self.samples = samples[:, :n_params] + + # Update number of samples + self.n_samples = self.samples.shape[0] + + # ---------- Preparation of observation data ---------- + # Read observation data and perturb it if requested. + if self.measured_data is None: + self.measured_data = Model.read_observation(case=self.name) + # Convert measured_data to a data frame + if not isinstance(self.measured_data, pd.DataFrame): + self.measured_data = pd.DataFrame(self.measured_data) + + # Extract the total number of measurement points + if self.name.lower() == 'calib': + self.n_tot_measurement = Model.n_obs + else: + self.n_tot_measurement = Model.n_obs_valid + + # Find measurement error (if not given) for post predictive plot + if not hasattr(self, 'measurement_error'): + if isinstance(self.Discrepancy, dict): + Disc = self.Discrepancy['known'] + else: + Disc = self.Discrepancy + if isinstance(Disc.parameters, dict): + self.measurement_error = {k: np.sqrt(Disc.parameters[k]) for k + in Disc.parameters.keys()} + else: + try: + self.measurement_error = np.sqrt(Disc.parameters) + except TypeError: + pass + + # ---------- Preparation of variance for covariance matrix ---------- + # Independent and identically distributed + total_sigma2 = dict() + opt_sigma_flag = isinstance(self.Discrepancy, dict) + opt_sigma = None + for key_idx, key in enumerate(output_names): + + # Find opt_sigma + if opt_sigma_flag and opt_sigma is None: + # Option A: known error with unknown bias term + opt_sigma = 'A' + known_discrepancy = self.Discrepancy['known'] + self.Discrepancy = self.Discrepancy['infer'] + sigma2 = np.array(known_discrepancy.parameters[key]) + + elif opt_sigma == 'A' or self.Discrepancy.parameters is not None: + # Option B: The sigma2 is known (no bias term) + if opt_sigma == 'A': + sigma2 = np.array(known_discrepancy.parameters[key]) + else: + opt_sigma = 'B' + sigma2 = np.array(self.Discrepancy.parameters[key]) + + elif not isinstance(self.Discrepancy.InputDisc, str): + # Option C: The sigma2 is unknown (bias term including error) + opt_sigma = 'C' + self.Discrepancy.opt_sigma = opt_sigma + n_measurement = self.measured_data[key].values.shape + sigma2 = np.zeros((n_measurement[0])) + + total_sigma2[key] = sigma2 + + self.Discrepancy.opt_sigma = opt_sigma + self.Discrepancy.total_sigma2 = total_sigma2 + + # If inferred sigma2s obtained from e.g. calibration are given + try: + self.sigma2s = self.Discrepancy.get_sample(self.n_samples) + except: + pass + + # ---------------- Bootstrap & TOM -------------------- + if self.bootstrap or self.bayes_loocv or self.just_analysis: + if len(self.perturbed_data) == 0: + # zero mean noise Adding some noise to the observation function + self.perturbed_data = self._perturb_data( + self.measured_data, output_names + ) + else: + self.n_bootstrap_itrs = len(self.perturbed_data) + + # -------- Model Discrepancy ----------- + if hasattr(self, 'error_model') and self.error_model \ + and self.name.lower() != 'calib': + # Select posterior mean as MAP + MAP_theta = self.samples.mean(axis=0).reshape((1, n_params)) + # MAP_theta = stats.mode(self.samples,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_MAP, y_std_MAP = MetaModel.eval_metamodel(samples=MAP_theta) + + # Train a GPR meta-model using MAP + self.error_MetaModel = MetaModel.create_model_error( + self.bias_inputs, y_MAP, Name=self.name + ) + + # ----------------------------------------------------- + # ----- Loop over the perturbed observation data ------ + # ----------------------------------------------------- + # Initilize arrays + logLikelihoods = np.zeros((self.n_samples, self.n_bootstrap_itrs), + dtype=np.float16) + BME_Corr = np.zeros((self.n_bootstrap_itrs)) + log_BME = np.zeros((self.n_bootstrap_itrs)) + KLD = np.zeros((self.n_bootstrap_itrs)) + inf_entropy = np.zeros((self.n_bootstrap_itrs)) + + # Compute the prior predtions + # Evaluate the MetaModel + if self.emulator: + y_hat, y_std = MetaModel.eval_metamodel(samples=self.samples) + self.__mean_pce_prior_pred = y_hat + self._std_pce_prior_pred = y_std + + # Correct the predictions with Model discrepancy + if hasattr(self, 'error_model') and self.error_model: + y_hat_corr, y_std = self.error_MetaModel.eval_model_error( + self.bias_inputs, self.__mean_pce_prior_pred + ) + self.__mean_pce_prior_pred = y_hat_corr + self._std_pce_prior_pred = y_std + + # Surrogate model's error using RMSE of test data + if hasattr(MetaModel, 'rmse'): + surrError = MetaModel.rmse + else: + surrError = None + + else: + # Evaluate the original model + self.__model_prior_pred = self._eval_model( + samples=self.samples, key='PriorPred' + ) + surrError = None + + # Start the likelihood-BME computations for the perturbed data + for itr_idx, data in tqdm( + enumerate(self.perturbed_data), + total=self.n_bootstrap_itrs, + desc="Bootstrapping the BME calculations", ascii=True + ): + + # ---------------- Likelihood calculation ---------------- + if self.emulator: + model_evals = self.__mean_pce_prior_pred + else: + model_evals = self.__model_prior_pred + + # Leave one out + if self.bayes_loocv or self.just_analysis: + self.selected_indices = np.nonzero(data)[0] + + # Prepare data dataframe + nobs = list(self.measured_data.count().values[1:]) + numbers = list(np.cumsum(nobs)) + indices = list(zip([0] + numbers, numbers)) + data_dict = { + output_names[i]: data[j:k] for i, (j, k) in + enumerate(indices) + } + #print(output_names) + #print(indices) + #print(numbers) + #print(nobs) + #print(self.measured_data) + #for i, (j, k) in enumerate(indices): + # print(i,j,k) + #print(data) + #print(data_dict) + #stop + + # Unknown sigma2 + if opt_sigma == 'C' or hasattr(self, 'sigma2s'): + logLikelihoods[:, itr_idx] = self.normpdf( + model_evals, data_dict, total_sigma2, + sigma2=self.sigma2s, std=surrError + ) + else: + # known sigma2 + logLikelihoods[:, itr_idx] = self.normpdf( + model_evals, data_dict, total_sigma2, + std=surrError + ) + + # ---------------- BME Calculations ---------------- + # BME (log) + log_BME[itr_idx] = np.log( + np.nanmean(np.exp(logLikelihoods[:, itr_idx], + dtype=np.longdouble))#float128)) + ) + + # BME correction when using Emulator + if self.emulator: + BME_Corr[itr_idx] = self.__corr_factor_BME( + data_dict, total_sigma2, log_BME[itr_idx] + ) + + # Rejection Step + if 'kld' in list(map(str.lower, self.valid_metrics)) and\ + 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + # Random numbers between 0 and 1 + unif = np.random.rand(1, self.n_samples)[0] + + # Reject the poorly performed prior + Likelihoods = np.exp(logLikelihoods[:, itr_idx], + dtype=np.float64) + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + posterior = self.samples[accepted] + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean( + logLikelihoods[:, itr_idx][accepted] + ) + + # Calculate Kullback-Leibler Divergence + KLD[itr_idx] = postExpLikelihoods - log_BME[itr_idx] + + # Posterior-based expectation of prior densities + if 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + n_thread = int(0.875 * multiprocessing.cpu_count()) + with multiprocessing.Pool(n_thread) as p: + postExpPrior = np.mean(np.concatenate( + p.map( + self.engine.ExpDesign.JDist.pdf, + np.array_split(posterior.T, n_thread, axis=1)) + ) + ) + # Information Entropy based on Entropy paper Eq. 38 + inf_entropy[itr_idx] = log_BME[itr_idx] - postExpPrior - \ + postExpLikelihoods + + # Clear memory + gc.collect(generation=2) + + # ---------- Store metrics for perturbed data set ---------------- + # Likelihoods (Size: n_samples, n_bootstrap_itr) + self.log_likes = logLikelihoods + + # BME (log), KLD, infEntropy (Size: 1,n_bootstrap_itr) + self.log_BME = log_BME + + # BMECorrFactor (log) (Size: 1,n_bootstrap_itr) + if self.emulator: + self.log_BME_corr_factor = BME_Corr + + if 'kld' in list(map(str.lower, self.valid_metrics)): + self.KLD = KLD + if 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + self.inf_entropy = inf_entropy + + # BME = BME + BMECorrFactor + if self.emulator: + self.log_BME += self.log_BME_corr_factor + + # ---------------- Parameter Bayesian inference ---------------- + if self.inference_method.lower() == 'mcmc': + # Instantiate the MCMC object + MCMC_Obj = MCMC(self) + self.posterior_df = MCMC_Obj.run_sampler( + self.measured_data, total_sigma2 + ) + + elif self.name.lower() == 'valid': + # Convert to a dataframe if samples are provided after calibration. + self.posterior_df = pd.DataFrame(self.samples, columns=par_names) + + else: + # Rejection sampling + self.posterior_df = self._rejection_sampling() + + # Provide posterior's summary + print('\n') + print('-'*15 + 'Posterior summary' + '-'*15) + pd.options.display.max_columns = None + pd.options.display.max_rows = None + print(self.posterior_df.describe()) + print('-'*50) + + # -------- Model Discrepancy ----------- + if hasattr(self, 'error_model') and self.error_model \ + and self.name.lower() == 'calib': + if self.inference_method.lower() == 'mcmc': + self.error_MetaModel = MCMC_Obj.error_MetaModel + else: + # Select posterior mean as MAP + if opt_sigma == "B": + posterior_df = self.posterior_df.values + else: + posterior_df = self.posterior_df.values[:, :-Model.n_outputs] + + # Select posterior mean as Maximum a posteriori + map_theta = posterior_df.mean(axis=0).reshape((1, n_params)) + # map_theta = stats.mode(Posterior_df,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_MAP, y_std_MAP = MetaModel.eval_metamodel(samples=map_theta) + + # Train a GPR meta-model using MAP + self.error_MetaModel = MetaModel.create_model_error( + self.bias_inputs, y_MAP, Name=self.name + ) + + # -------- Posterior perdictive ----------- + self._posterior_predictive() + + # ----------------------------------------------------- + # ------------------ Visualization -------------------- + # ----------------------------------------------------- + # Create Output directory, if it doesn't exist already. + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + os.makedirs(out_dir, exist_ok=True) + + # -------- Posteior parameters -------- + if opt_sigma != "B": + par_names.extend( + [self.Discrepancy.InputDisc.Marginals[i].name for i + in range(len(self.Discrepancy.InputDisc.Marginals))] + ) + # Pot with corner + figPosterior = corner.corner(self.posterior_df.to_numpy(), + labels=par_names, + quantiles=[0.15, 0.5, 0.85], + show_titles=True, + title_fmt=self.corner_title_fmt, + labelpad=0.2, + use_math_text=True, + title_kwargs={"fontsize": 28}, + plot_datapoints=False, + plot_density=False, + fill_contours=True, + smooth=0.5, + smooth1d=0.5) + + # Loop over axes and set x limits + if opt_sigma == "B": + axes = np.array(figPosterior.axes).reshape( + (len(par_names), len(par_names)) + ) + for yi in range(len(par_names)): + ax = axes[yi, yi] + ax.set_xlim(self.engine.ExpDesign.bound_tuples[yi]) + for xi in range(yi): + ax = axes[yi, xi] + ax.set_xlim(self.engine.ExpDesign.bound_tuples[xi]) + plt.close() + + # Turn off gridlines + for ax in figPosterior.axes: + ax.grid(False) + + if self.emulator: + plotname = f'/Posterior_Dist_{Model.name}_emulator' + else: + plotname = f'/Posterior_Dist_{Model.name}' + + figPosterior.set_size_inches((24, 16)) + figPosterior.savefig(f'./{out_dir}{plotname}.pdf', + bbox_inches='tight') + + # -------- Plot MAP -------- + if self.plot_map_pred: + self._plot_max_a_posteriori() + + # -------- Plot log_BME dist -------- + if self.bootstrap: + + # Computing the TOM performance + self.log_BME_tom = stats.chi2.rvs( + self.n_tot_measurement, size=self.log_BME.shape[0] + ) + + fig, ax = plt.subplots() + sns.kdeplot(self.log_BME_tom, ax=ax, color="green", shade=True) + sns.kdeplot( + self.log_BME, ax=ax, color="blue", shade=True, + label='Model BME') + + ax.set_xlabel('log$_{10}$(BME)') + ax.set_ylabel('Probability density') + + legend_elements = [ + Patch(facecolor='green', edgecolor='green', label='TOM BME'), + Patch(facecolor='blue', edgecolor='blue', label='Model BME') + ] + ax.legend(handles=legend_elements) + + if self.emulator: + plotname = f'/BME_hist_{Model.name}_emulator' + else: + plotname = f'/BME_hist_{Model.name}' + + plt.savefig(f'./{out_dir}{plotname}.pdf', bbox_inches='tight') + plt.show() + plt.close() + + # -------- Posteior perdictives -------- + if self.plot_post_pred: + # Plot the posterior predictive + self._plot_post_predictive() + + return self + + # ------------------------------------------------------------------------- + def _perturb_data(self, data, output_names): + """ + Returns an array with n_bootstrap_itrs rowsof perturbed data. + The first row includes the original observation data. + If `self.bayes_loocv` is True, a 2d-array will be returned with + repeated rows and zero diagonal entries. + + Parameters + ---------- + data : pandas DataFrame + Observation data. + output_names : list + List of the output names. + + Returns + ------- + final_data : array + Perturbed data set. + + """ + noise_level = self.bootstrap_noise + obs_data = data[output_names].values + n_measurement, n_outs = obs_data.shape + self.n_tot_measurement = obs_data[~np.isnan(obs_data)].shape[0] + # Number of bootstrap iterations + if self.bayes_loocv: + self.n_bootstrap_itrs = self.n_tot_measurement + + # Pass loocv dataset + if self.bayes_loocv: + obs = obs_data.T[~np.isnan(obs_data.T)] + final_data = np.repeat(np.atleast_2d(obs), self.n_bootstrap_itrs, + axis=0) + np.fill_diagonal(final_data, 0) + return final_data + + else: + final_data = np.zeros( + (self.n_bootstrap_itrs, self.n_tot_measurement) + ) + final_data[0] = obs_data.T[~np.isnan(obs_data.T)] + for itrIdx in range(1, self.n_bootstrap_itrs): + data = np.zeros((n_measurement, n_outs)) + for idx in range(len(output_names)): + std = np.nanstd(obs_data[:, idx]) + if std == 0: + std = 0.001 + noise = std * noise_level + data[:, idx] = np.add( + obs_data[:, idx], + np.random.normal(0, 1, obs_data.shape[0]) * noise, + ) + + final_data[itrIdx] = data.T[~np.isnan(data.T)] + + return final_data + + # ------------------------------------------------------------------------- + def _logpdf(self, x, mean, cov): + """ + computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = spla.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(spla.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + return log_lik + + # ------------------------------------------------------------------------- + def _eval_model(self, samples=None, key='MAP'): + """ + Evaluates Forward Model. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Parameter sets. The default is None. + key : str, optional + Key string to be passed to the run_model_parallel method. + The default is 'MAP'. + + Returns + ------- + model_outputs : dict + Model outputs. + + """ + MetaModel = self.MetaModel + Model = self.engine.Model + + if samples is None: + self.samples = self.engine.ExpDesign.generate_samples( + self.n_samples, 'random') + else: + self.samples = samples + self.n_samples = len(samples) + + model_outputs, _ = Model.run_model_parallel( + self.samples, key_str=key+self.name) + + # Clean up + # Zip the subdirectories + try: + dir_name = f'{Model.name}MAP{self.name}' + key = dir_name + '_' + Model.zip_subdirs(dir_name, key) + except: + pass + + return model_outputs + + # ------------------------------------------------------------------------- + def _kernel_rbf(self, X, hyperparameters): + """ + Isotropic squared exponential kernel. + + Higher l values lead to smoother functions and therefore to coarser + approximations of the training data. Lower l values make functions + more wiggly with wide uncertainty regions between training data points. + + sigma_f controls the marginal variance of b(x) + + Parameters + ---------- + X : ndarray of shape (n_samples_X, n_features) + + hyperparameters : Dict + Lambda characteristic length + sigma_f controls the marginal variance of b(x) + sigma_0 unresolvable error nugget term, interpreted as random + error that cannot be attributed to measurement error. + Returns + ------- + var_cov_matrix : ndarray of shape (n_samples_X,n_samples_X) + Kernel k(X, X). + + """ + from sklearn.gaussian_process.kernels import RBF + min_max_scaler = preprocessing.MinMaxScaler() + X_minmax = min_max_scaler.fit_transform(X) + + nparams = len(hyperparameters) + # characteristic length (0,1] + Lambda = hyperparameters[0] + # sigma_f controls the marginal variance of b(x) + sigma2_f = hyperparameters[1] + + # cov_matrix = sigma2_f*rbf_kernel(X_minmax, gamma = 1/Lambda**2) + + rbf = RBF(length_scale=Lambda) + cov_matrix = sigma2_f * rbf(X_minmax) + if nparams > 2: + # (unresolvable error) nugget term that is interpreted as random + # error that cannot be attributed to measurement error. + sigma2_0 = hyperparameters[2:] + for i, j in np.ndindex(cov_matrix.shape): + cov_matrix[i, j] += np.sum(sigma2_0) if i == j else 0 + + return cov_matrix + + # ------------------------------------------------------------------------- + def normpdf(self, outputs, obs_data, total_sigma2s, sigma2=None, std=None): + """ + Calculates the likelihood of simulation outputs compared with + observation data. + + Parameters + ---------- + outputs : dict + A dictionary containing the simulation outputs as array of shape + (n_samples, n_measurement) for each model output. + obs_data : dict + A dictionary/dataframe containing the observation data. + total_sigma2s : dict + A dictionary with known values of the covariance diagonal entries, + a.k.a sigma^2. + sigma2 : array, optional + An array of the sigma^2 samples, when the covariance diagonal + entries are unknown and are being jointly inferred. The default is + None. + std : dict, optional + A dictionary containing the root mean squared error as array of + shape (n_samples, n_measurement) for each model output. The default + is None. + + Returns + ------- + logLik : array of shape (n_samples) + Likelihoods. + + """ + Model = self.engine.Model + logLik = 0.0 + + # Extract the requested model outputs for likelihood calulation + if self.req_outputs is None: + req_outputs = Model.Output.names + else: + req_outputs = list(self.req_outputs) + + # Loop over the outputs + for idx, out in enumerate(req_outputs): + + # (Meta)Model Output + nsamples, nout = outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Add the std of the PCE is chosen as emulator. + if self.emulator: + if std is not None: + tot_sigma2s += std[out]**2 + + # Covariance Matrix + covMatrix = np.diag(tot_sigma2s) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + + # If sigma2 is not given, use given total_sigma2s + if sigma2 is None: + logLik += stats.multivariate_normal.logpdf( + outputs[out][:, indices], data[indices], covMatrix) + continue + + # Loop over each run/sample and calculate logLikelihood + logliks = np.zeros(nsamples) + for s_idx in range(nsamples): + + # Simulation run + tot_outputs = outputs[out] + + # Covariance Matrix + covMatrix = np.diag(tot_sigma2s) + + if sigma2 is not None: + # Check the type error term + if hasattr(self, 'bias_inputs') and \ + not hasattr(self, 'error_model'): + # Infer a Bias model usig Gaussian Process Regression + bias_inputs = np.hstack( + (self.bias_inputs[out], + tot_outputs[s_idx].reshape(-1, 1))) + + params = sigma2[s_idx, idx*3:(idx+1)*3] + covMatrix = self._kernel_rbf(bias_inputs, params) + else: + # Infer equal sigma2s + try: + sigma_2 = sigma2[s_idx, idx] + except TypeError: + sigma_2 = 0.0 + + covMatrix += sigma_2 * np.eye(nout) + # covMatrix = np.diag(sigma2 * total_sigma2s) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + + # Compute loglikelihood + logliks[s_idx] = self._logpdf( + tot_outputs[s_idx, indices], data[indices], covMatrix + ) + + logLik += logliks + return logLik + + # ------------------------------------------------------------------------- + def _corr_factor_BME_old(self, Data, total_sigma2s, posterior): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + OrigModelOutput = self.engine.ExpDesign.Y + Model = self.engine.Model + + # Posterior with guassian-likelihood + postDist = stats.gaussian_kde(posterior.T) + + # Remove NaN + Data = Data[~np.isnan(Data)] + total_sigma2s = total_sigma2s[~np.isnan(total_sigma2s)] + + # Covariance Matrix + covMatrix = np.diag(total_sigma2s[:self.n_tot_measurement]) + + # Extract the requested model outputs for likelihood calulation + if self.req_outputs is None: + OutputType = Model.Output.names + else: + OutputType = list(self.req_outputs) + + # SampleSize = OrigModelOutput[OutputType[0]].shape[0] + + + # Flatten the OutputType for OrigModel + TotalOutputs = np.concatenate([OrigModelOutput[x] for x in OutputType], 1) + + NrofBayesSamples = self.n_samples + # Evaluate MetaModel on the experimental design + Samples = self.engine.ExpDesign.X + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=Samples) + + # Reset the NrofSamples to NrofBayesSamples + self.n_samples = NrofBayesSamples + + # Flatten the OutputType for MetaModel + TotalPCEOutputs = np.concatenate([OutputRS[x] for x in OutputRS], 1) + TotalPCEstdOutputRS= np.concatenate([stdOutputRS[x] for x in stdOutputRS], 1) + + logweight = 0 + for i, sample in enumerate(Samples): + # Compute likelilhood output vs RS + covMatrix = np.diag(TotalPCEstdOutputRS[i]**2) + logLik = self._logpdf(TotalOutputs[i], TotalPCEOutputs[i], covMatrix) + # Compute posterior likelihood of the collocation points + logpostLik = np.log(postDist.pdf(sample[:, None]))[0] + if logpostLik != -np.inf: + logweight += logLik + logpostLik + return logweight + + # ------------------------------------------------------------------------- + def __corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = self.engine.ExpDesign.X + model_outputs = self.engine.ExpDesign.Y + Model = self.engine.Model + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = Model.Output.names + + # Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + covMatrix = np.eye(len(y_m)) * 1/(2*np.pi) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + covMatrix_data = np.diag(covMatrix_data[indices, indices]) + + # Compute likelilhood output vs data + logLik_data[i] += self._logpdf( + y_m_hat[indices], data[indices], + covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += self._logpdf( + y_m_hat[indices], y_m[indices], + covMatrix + ) + + # Weight + logLik_data -= logBME + weights = np.mean(np.exp(logLik_model+logLik_data)) + + return np.log(weights) + + # ------------------------------------------------------------------------- + def _rejection_sampling(self): + """ + Performs rejection sampling to update the prior distribution on the + input parameters. + + Returns + ------- + posterior : pandas.dataframe + Posterior samples of the input parameters. + + """ + + MetaModel = self.MetaModel + try: + sigma2_prior = self.Discrepancy.sigma2_prior + except: + sigma2_prior = None + + # Check if the discrepancy is defined as a distribution: + samples = self.samples + + if sigma2_prior is not None: + samples = np.hstack((samples, sigma2_prior)) + + # Take the first column of Likelihoods (Observation data without noise) + if self.just_analysis or self.bayes_loocv: + index = self.n_tot_measurement-1 + likelihoods = np.exp(self.log_likes[:, index], dtype=np.longdouble)#np.float128) + else: + likelihoods = np.exp(self.log_likes[:, 0], dtype=np.longdouble)#np.float128) + + n_samples = len(likelihoods) + norm_ikelihoods = likelihoods / np.max(likelihoods) + + # Normalize based on min if all Likelihoods are zero + if all(likelihoods == 0.0): + likelihoods = self.log_likes[:, 0] + norm_ikelihoods = likelihoods / np.min(likelihoods) + + # Random numbers between 0 and 1 + unif = np.random.rand(1, n_samples)[0] + + # Reject the poorly performed prior + accepted_samples = samples[norm_ikelihoods >= unif] + + # Output the Posterior + par_names = self.engine.ExpDesign.par_names + if sigma2_prior is not None: + for name in self.Discrepancy.name: + par_names.append(name) + + return pd.DataFrame(accepted_samples, columns=sigma2_prior) + + # ------------------------------------------------------------------------- + def _posterior_predictive(self): + """ + Stores the prior- and posterior predictive samples, i.e. model + evaluations using the samples, into hdf5 files. + + priorPredictive.hdf5 : Prior predictive samples. + postPredictive_wo_noise.hdf5 : Posterior predictive samples without + the additive noise. + postPredictive.hdf5 : Posterior predictive samples with the additive + noise. + + Returns + ------- + None. + + """ + + MetaModel = self.MetaModel + Model = self.engine.Model + + # Make a directory to save the prior/posterior predictive + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + os.makedirs(out_dir, exist_ok=True) + + # Read observation data and perturb it if requested + if self.measured_data is None: + self.measured_data = Model.read_observation(case=self.name) + + if not isinstance(self.measured_data, pd.DataFrame): + self.measured_data = pd.DataFrame(self.measured_data) + + # X_values + x_values = self.engine.ExpDesign.x_values + + try: + sigma2_prior = self.Discrepancy.sigma2_prior + except: + sigma2_prior = None + + # Extract posterior samples + posterior_df = self.posterior_df + + # Take care of the sigma2 + if sigma2_prior is not None: + try: + sigma2s = posterior_df[self.Discrepancy.name].values + posterior_df = posterior_df.drop( + labels=self.Discrepancy.name, axis=1 + ) + except: + sigma2s = self.sigma2s + + # Posterior predictive + if self.emulator: + if self.inference_method == 'rejection': + prior_pred = self.__mean_pce_prior_pred + if self.name.lower() != 'calib': + post_pred = self.__mean_pce_prior_pred + post_pred_std = self._std_pce_prior_pred + else: + post_pred, post_pred_std = MetaModel.eval_metamodel( + samples=posterior_df.values + ) + + else: + if self.inference_method == 'rejection': + prior_pred = self.__model_prior_pred + if self.name.lower() != 'calib': + post_pred = self.__mean_pce_prior_pred, + post_pred_std = self._std_pce_prior_pred + else: + post_pred = self._eval_model( + samples=posterior_df.values, key='PostPred' + ) + # Correct the predictions with Model discrepancy + if hasattr(self, 'error_model') and self.error_model: + y_hat, y_std = self.error_MetaModel.eval_model_error( + self.bias_inputs, post_pred + ) + post_pred, post_pred_std = y_hat, y_std + + # Add discrepancy from likelihood Sample to the current posterior runs + total_sigma2 = self.Discrepancy.total_sigma2 + post_pred_withnoise = copy.deepcopy(post_pred) + for varIdx, var in enumerate(Model.Output.names): + for i in range(len(post_pred[var])): + pred = post_pred[var][i] + + # Known sigma2s + clean_sigma2 = total_sigma2[var][~np.isnan(total_sigma2[var])] + tot_sigma2 = clean_sigma2[:len(pred)] + cov = np.diag(tot_sigma2) + + # Check the type error term + if sigma2_prior is not None: + # Inferred sigma2s + if hasattr(self, 'bias_inputs') and \ + not hasattr(self, 'error_model'): + # TODO: Infer a Bias model usig GPR + bias_inputs = np.hstack(( + self.bias_inputs[var], pred.reshape(-1, 1))) + params = sigma2s[i, varIdx*3:(varIdx+1)*3] + cov = self._kernel_rbf(bias_inputs, params) + else: + # Infer equal sigma2s + try: + sigma2 = sigma2s[i, varIdx] + except TypeError: + sigma2 = 0.0 + + # Convert biasSigma2s to a covMatrix + cov += sigma2 * np.eye(len(pred)) + + if self.emulator: + if hasattr(MetaModel, 'rmse') and \ + MetaModel.rmse is not None: + stdPCE = MetaModel.rmse[var] + else: + stdPCE = post_pred_std[var][i] + # Expected value of variance (Assump: i.i.d stds) + cov += np.diag(stdPCE**2) + + # Sample a multivariate normal distribution with mean of + # prediction and variance of cov + post_pred_withnoise[var][i] = np.random.multivariate_normal( + pred, cov, 1 + ) + + # ----- Prior Predictive ----- + if self.inference_method.lower() == 'rejection': + # Create hdf5 metadata + hdf5file = f'{out_dir}/priorPredictive.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=prior_pred[var]) + + # ----- Posterior Predictive only model evaluations ----- + # Create hdf5 metadata + hdf5file = out_dir+'/postPredictive_wo_noise.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=post_pred[var]) + + # ----- Posterior Predictive with noise ----- + # Create hdf5 metadata + hdf5file = out_dir+'/postPredictive.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=post_pred_withnoise[var]) + + return + + # ------------------------------------------------------------------------- + def _plot_max_a_posteriori(self): + """ + Plots the response of the model output against that of the metamodel at + the maximum a posteriori sample (mean or mode of posterior.) + + Returns + ------- + None. + + """ + + MetaModel = self.MetaModel + Model = self.engine.Model + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + opt_sigma = self.Discrepancy.opt_sigma + + # -------- Find MAP and run MetaModel and origModel -------- + # Compute the MAP + if self.max_a_posteriori.lower() == 'mean': + if opt_sigma == "B": + Posterior_df = self.posterior_df.values + else: + Posterior_df = self.posterior_df.values[:, :-Model.n_outputs] + map_theta = Posterior_df.mean(axis=0).reshape( + (1, MetaModel.n_params)) + else: + map_theta = stats.mode(Posterior_df.values, axis=0)[0] + # Prin report + print("\nPoint estimator:\n", map_theta[0]) + + # Run the models for MAP + # MetaModel + map_metamodel_mean, map_metamodel_std = MetaModel.eval_metamodel( + samples=map_theta) + self.map_metamodel_mean = map_metamodel_mean + self.map_metamodel_std = map_metamodel_std + + # origModel + map_orig_model = self._eval_model(samples=map_theta) + self.map_orig_model = map_orig_model + + # Extract slicing index + x_values = map_orig_model['x_values'] + + # List of markers and colors + Color = ['k', 'b', 'g', 'r'] + Marker = 'x' + + # Create a PdfPages object + pdf = PdfPages(f'./{out_dir}MAP_PCE_vs_Model_{self.name}.pdf') + fig = plt.figure() + for i, key in enumerate(Model.Output.names): + + y_val = map_orig_model[key] + y_pce_val = map_metamodel_mean[key] + y_pce_val_std = map_metamodel_std[key] + + plt.plot(x_values, y_val, color=Color[i], marker=Marker, + lw=2.0, label='$Y_{MAP}^{M}$') + + plt.plot( + x_values, y_pce_val[i], color=Color[i], lw=2.0, + marker=Marker, linestyle='--', label='$Y_{MAP}^{PCE}$' + ) + # plot the confidence interval + plt.fill_between( + x_values, y_pce_val[i] - 1.96*y_pce_val_std[i], + y_pce_val[i] + 1.96*y_pce_val_std[i], + color=Color[i], alpha=0.15 + ) + + # Calculate the adjusted R_squared and RMSE + R2 = r2_score(y_pce_val.reshape(-1, 1), y_val.reshape(-1, 1)) + rmse = np.sqrt(mean_squared_error(y_pce_val, y_val)) + + plt.ylabel(key) + plt.xlabel("Time [s]") + plt.title(f'Model vs MetaModel {key}') + + ax = fig.axes[0] + leg = ax.legend(loc='best', frameon=True) + fig.canvas.draw() + p = leg.get_window_extent().inverse_transformed(ax.transAxes) + ax.text( + p.p0[1]-0.05, p.p1[1]-0.25, + f'RMSE = {rmse:.3f}\n$R^2$ = {R2:.3f}', + transform=ax.transAxes, color='black', + bbox=dict(facecolor='none', edgecolor='black', + boxstyle='round,pad=1')) + + plt.show() + + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + pdf.close() + + # ------------------------------------------------------------------------- + def _plot_post_predictive(self): + """ + Plots the posterior predictives against the observation data. + + Returns + ------- + None. + + """ + + Model = self.engine.Model + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + # Plot the posterior predictive + for out_idx, out_name in enumerate(Model.Output.names): + fig, ax = plt.subplots() + with sns.axes_style("ticks"): + x_key = list(self.measured_data)[0] + + # --- Read prior and posterior predictive --- + if self.inference_method == 'rejection' and \ + self.name.lower() != 'valid': + # --- Prior --- + # Load posterior predictive + f = h5py.File( + f'{out_dir}/priorPredictive.hdf5', 'r+') + + try: + x_coords = np.array(f[f"x_values/{out_name}"]) + except: + x_coords = np.array(f["x_values"]) + + X_values = np.repeat(x_coords, 10000) + + prior_pred_df = {} + prior_pred_df[x_key] = X_values + prior_pred_df[out_name] = np.array( + f[f"EDY/{out_name}"])[:10000].flatten('F') + prior_pred_df = pd.DataFrame(prior_pred_df) + + tags_post = ['prior'] * len(prior_pred_df) + prior_pred_df.insert( + len(prior_pred_df.columns), "Tags", tags_post, + True) + f.close() + + # --- Posterior --- + f = h5py.File(f"{out_dir}/postPredictive.hdf5", 'r+') + + X_values = np.repeat( + x_coords, np.array(f[f"EDY/{out_name}"]).shape[0]) + + post_pred_df = {} + post_pred_df[x_key] = X_values + post_pred_df[out_name] = np.array( + f[f"EDY/{out_name}"]).flatten('F') + + post_pred_df = pd.DataFrame(post_pred_df) + + tags_post = ['posterior'] * len(post_pred_df) + post_pred_df.insert( + len(post_pred_df.columns), "Tags", tags_post, True) + f.close() + # Concatenate two dataframes based on x_values + frames = [prior_pred_df, post_pred_df] + all_pred_df = pd.concat(frames) + + # --- Plot posterior predictive --- + sns.violinplot( + x_key, y=out_name, data=all_pred_df, hue="Tags", + legend=False, ax=ax, split=True, inner=None, + color=".8") + + # --- Plot Data --- + # Find the x,y coordinates for each point + x_coords = np.arange(x_coords.shape[0]) + first_header = list(self.measured_data)[0] + obs_data = self.measured_data.round({first_header: 6}) + sns.pointplot( + x=first_header, y=out_name, color='g', markers='x', + linestyles='', capsize=16, data=obs_data, ax=ax) + + ax.errorbar( + x_coords, obs_data[out_name].values, + yerr=1.96*self.measurement_error[out_name], + ecolor='g', fmt=' ', zorder=-1) + + # Add labels to the legend + handles, labels = ax.get_legend_handles_labels() + labels.append('Data') + + data_marker = mlines.Line2D( + [], [], color='lime', marker='+', linestyle='None', + markersize=10) + handles.append(data_marker) + + # Add legend + ax.legend(handles=handles, labels=labels, loc='best', + fontsize='large', frameon=True) + + else: + # Load posterior predictive + f = h5py.File(f"{out_dir}/postPredictive.hdf5", 'r+') + + try: + x_coords = np.array(f[f"x_values/{out_name}"]) + except: + x_coords = np.array(f["x_values"]) + + mu = np.mean(np.array(f[f"EDY/{out_name}"]), axis=0) + std = np.std(np.array(f[f"EDY/{out_name}"]), axis=0) + + # --- Plot posterior predictive --- + plt.plot( + x_coords, mu, marker='o', color='b', + label='Mean Post. Predictive') + plt.fill_between( + x_coords, mu-1.96*std, mu+1.96*std, color='b', + alpha=0.15) + + # --- Plot Data --- + ax.plot( + x_coords, self.measured_data[out_name].values, + 'ko', label='data', markeredgecolor='w') + + # --- Plot ExpDesign --- + orig_ED_Y = self.engine.ExpDesign.Y[out_name] + for output in orig_ED_Y: + plt.plot( + x_coords, output, color='grey', alpha=0.15 + ) + + # Add labels for axes + plt.xlabel('Time [s]') + plt.ylabel(out_name) + + # Add labels to the legend + handles, labels = ax.get_legend_handles_labels() + + patch = Patch(color='b', alpha=0.15) + handles.insert(1, patch) + labels.insert(1, '95 $\\%$ CI') + + # Add legend + ax.legend(handles=handles, labels=labels, loc='best', + frameon=True) + + # Save figure in pdf format + if self.emulator: + plotname = f'/Post_Prior_Perd_{Model.name}_emulator' + else: + plotname = f'/Post_Prior_Perd_{Model.name}' + + fig.savefig(f'./{out_dir}{plotname}_{out_name}.pdf', + bbox_inches='tight') diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_model_comparison.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_model_comparison.py new file mode 100644 index 000000000..b946281c5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/bayes_model_comparison.py @@ -0,0 +1,658 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sat Aug 24 16:04:06 2019 + +@author: farid +""" +import numpy as np +import os +from scipy import stats +import seaborn as sns +import matplotlib.patches as patches +import matplotlib.colors as mcolors +import matplotlib.pylab as plt +from .bayes_inference import BayesInference + +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class BayesModelComparison: + """ + A class to perform Bayesian Analysis. + + + Attributes + ---------- + justifiability : bool, optional + Whether to perform the justifiability analysis. The default is + `True`. + perturbed_data : array of shape (n_bootstrap_itrs, n_obs), optional + User defined perturbed data. The default is `None`. + n_bootstarp : int + Number of bootstrap iteration. The default is `1000`. + data_noise_level : float + A noise level to perturb the data set. The default is `0.01`. + just_n_meas : int + Number of measurements considered for visualization of the + justifiability results. + + """ + + def __init__(self, justifiability=True, perturbed_data=None, + n_bootstarp=1000, data_noise_level=0.01, just_n_meas=2): + + self.justifiability = justifiability + self.perturbed_data = perturbed_data + self.n_bootstarp = n_bootstarp + self.data_noise_level = data_noise_level + self.just_n_meas = just_n_meas + + # -------------------------------------------------------------------------- + def create_model_comparison(self, model_dict, opts_dict): + """ + Starts the two-stage model comparison. + Stage I: Compare models using Bayes factors. + Stage II: Compare models via justifiability analysis. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + opts_dict : dict + A dictionary given the `BayesInference` options. + + Example: + + >>> opts_bootstrap = { + "bootstrap": True, + "n_samples": 10000, + "Discrepancy": DiscrepancyOpts, + "emulator": True, + "plot_post_pred": True + } + + Returns + ------- + output : dict + A dictionary containing the objects and the model weights for the + comparison using Bayes factors and justifiability analysis. + + """ + + # Bayes factor + bayes_dict_bf, model_weights_dict_bf = self.compare_models( + model_dict, opts_dict + ) + + output = { + 'Bayes objects BF': bayes_dict_bf, + 'Model weights BF': model_weights_dict_bf + } + + # Justifiability analysis + if self.justifiability: + bayes_dict_ja, model_weights_dict_ja = self.compare_models( + model_dict, opts_dict, justifiability=True + ) + + output['Bayes objects JA'] = bayes_dict_ja + output['Model weights JA'] = model_weights_dict_ja + + return output + + # -------------------------------------------------------------------------- + def compare_models(self, model_dict, opts_dict, justifiability=False): + """ + Passes the options to instantiates the BayesInference class for each + model and passes the options from `opts_dict`. Then, it starts the + computations. + It also creates a folder and saves the diagrams, e.g., Bayes factor + plot, confusion matrix, etc. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + opts_dict : dict + A dictionary given the `BayesInference` options. + justifiability : bool, optional + Whether to perform the justifiability analysis. The default is + `False`. + + Returns + ------- + bayes_dict : dict + A dictionary with `BayesInference` objects. + model_weights_dict : dict + A dictionary containing the model weights. + + """ + + if not isinstance(model_dict, dict): + raise Exception("To run model comparsion, you need to pass a " + "dictionary of models.") + + # Extract model names + self.model_names = [*model_dict] + + # Compute total number of the measurement points + Engine = list(model_dict.items())[0][1] + Engine.Model.read_observation() + self.n_meas = Engine.Model.n_obs + + # ----- Generate data ----- + # Find n_bootstrap + if self.perturbed_data is None: + n_bootstarp = self.n_bootstarp + else: + n_bootstarp = self.perturbed_data.shape[0] + + # Create dataset + justData = self.generate_dataset( + model_dict, justifiability, n_bootstarp=n_bootstarp) + + # Run create Interface for each model + bayes_dict = {} + for model in model_dict.keys(): + print("-"*20) + print("Bayesian inference of {}.\n".format(model)) + + BayesOpts = BayesInference(model_dict[model]) + + # Set BayesInference options + for key, value in opts_dict.items(): + if key in BayesOpts.__dict__.keys(): + if key == "Discrepancy" and isinstance(value, dict): + setattr(BayesOpts, key, value[model]) + else: + setattr(BayesOpts, key, value) + + # Pass justifiability data as perturbed data + BayesOpts.perturbed_data = justData + BayesOpts.just_analysis = justifiability + + bayes_dict[model] = BayesOpts.create_inference() + print("-"*20) + + # Compute model weights + BME_Dict = dict() + for modelName, bayesObj in bayes_dict.items(): + BME_Dict[modelName] = np.exp(bayesObj.log_BME, dtype=np.longdouble)#float128) + + # BME correction in BayesInference class + model_weights = self.cal_model_weight( + BME_Dict, justifiability, n_bootstarp=n_bootstarp) + + # Plot model weights + if justifiability: + model_names = self.model_names + model_names.insert(0, 'Observation') + + # Split the model weights and save in a dict + list_ModelWeights = np.split( + model_weights, model_weights.shape[1]/self.n_meas, axis=1) + model_weights_dict = {key: weights for key, weights in + zip(model_names, list_ModelWeights)} + + #self.plot_just_analysis(model_weights_dict) + else: + # Create box plot for model weights + self.plot_model_weights(model_weights, 'model_weights') + + # Create kde plot for bayes factors + self.plot_bayes_factor(BME_Dict, 'kde_plot') + + # Store model weights in a dict + model_weights_dict = {key: weights for key, weights in + zip(self.model_names, model_weights)} + + return bayes_dict, model_weights_dict + + # ------------------------------------------------------------------------- + def generate_dataset(self, model_dict, justifiability=False, + n_bootstarp=1): + """ + Generates the perturbed data set for the Bayes factor calculations and + the data set for the justifiability analysis. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + bool, optional + Whether to perform the justifiability analysis. The default is + `False`. + n_bootstarp : int, optional + Number of bootstrap iterations. The default is `1`. + + Returns + ------- + all_just_data: array + Created data set. + + """ + # Compute some variables + all_just_data = [] + Engine = list(model_dict.items())[0][1] + out_names = Engine.Model.Output.names + + # Perturb observations for Bayes Factor + if self.perturbed_data is None: + self.perturbed_data = self.__perturb_data( + Engine.Model.observations, out_names, n_bootstarp, + noise_level=self.data_noise_level) + + # Only for Bayes Factor + if not justifiability: + return self.perturbed_data + + # Evaluate metamodel + runs = {} + for key, metaModel in model_dict.items(): + y_hat, _ = metaModel.eval_metamodel(nsamples=n_bootstarp) + runs[key] = y_hat + + # Generate data + for i in range(n_bootstarp): + y_data = self.perturbed_data[i].reshape(1, -1) + justData = np.tril(np.repeat(y_data, y_data.shape[1], axis=0)) + # Use surrogate runs for data-generating process + for key, metaModel in model_dict.items(): + model_data = np.array( + [runs[key][out][i] for out in out_names]).reshape(y_data.shape) + justData = np.vstack(( + justData, + np.tril(np.repeat(model_data, model_data.shape[1], axis=0)) + )) + # Save in a list + all_just_data.append(justData) + + # Squeeze the array + all_just_data = np.array(all_just_data).transpose(1, 0, 2).reshape( + -1, np.array(all_just_data).shape[2] + ) + + return all_just_data + + # ------------------------------------------------------------------------- + def __perturb_data(self, data, output_names, n_bootstrap, noise_level): + """ + Returns an array with n_bootstrap_itrs rowsof perturbed data. + The first row includes the original observation data. + If `self.bayes_loocv` is True, a 2d-array will be returned with + repeated rows and zero diagonal entries. + + Parameters + ---------- + data : pandas DataFrame + Observation data. + output_names : list + List of the output names. + + Returns + ------- + final_data : array + Perturbed data set. + + """ + obs_data = data[output_names].values + n_measurement, n_outs = obs_data.shape + n_tot_measurement = obs_data[~np.isnan(obs_data)].shape[0] + final_data = np.zeros( + (n_bootstrap, n_tot_measurement) + ) + final_data[0] = obs_data.T[~np.isnan(obs_data.T)] + for itrIdx in range(1, n_bootstrap): + data = np.zeros((n_measurement, n_outs)) + for idx in range(len(output_names)): + std = np.nanstd(obs_data[:, idx]) + if std == 0: + std = 0.001 + noise = std * noise_level + data[:, idx] = np.add( + obs_data[:, idx], + np.random.normal(0, 1, obs_data.shape[0]) * noise, + ) + + final_data[itrIdx] = data.T[~np.isnan(data.T)] + + return final_data + + # ------------------------------------------------------------------------- + def cal_model_weight(self, BME_Dict, justifiability=False, n_bootstarp=1): + """ + Normalize the BME (Asumption: Model Prior weights are equal for models) + + Parameters + ---------- + BME_Dict : dict + A dictionary containing the BME values. + + Returns + ------- + model_weights : array + Model weights. + + """ + # Stack the BME values for all models + all_BME = np.vstack(list(BME_Dict.values())) + + if justifiability: + # Compute expected log_BME for justifiabiliy analysis + all_BME = all_BME.reshape( + all_BME.shape[0], -1, n_bootstarp).mean(axis=2) + + # Model weights + model_weights = np.divide(all_BME, np.nansum(all_BME, axis=0)) + + return model_weights + + # ------------------------------------------------------------------------- + def plot_just_analysis(self, model_weights_dict): + """ + Visualizes the confusion matrix and the model wights for the + justifiability analysis. + + Parameters + ---------- + model_weights_dict : dict + Model weights. + + Returns + ------- + None. + + """ + + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + Color = [*mcolors.TABLEAU_COLORS] + names = [*model_weights_dict] + + model_names = [model.replace('_', '$-$') for model in self.model_names] + for name in names: + fig, ax = plt.subplots() + for i, model in enumerate(model_names[1:]): + plt.plot(list(range(1, self.n_meas+1)), + model_weights_dict[name][i], + color=Color[i], marker='o', + ms=10, linewidth=2, label=model + ) + + plt.title(f"Data generated by: {name.replace('_', '$-$')}") + plt.ylabel("Weights") + plt.xlabel("No. of measurement points") + ax.set_xticks(list(range(1, self.n_meas+1))) + plt.legend(loc="best") + fig.savefig( + f'{directory}modelWeights_{name}.svg', bbox_inches='tight' + ) + plt.close() + + # Confusion matrix for some measurement points + epsilon = 1 if self.just_n_meas != 1 else 0 + for index in range(0, self.n_meas+epsilon, self.just_n_meas): + weights = np.array( + [model_weights_dict[key][:, index] for key in model_weights_dict] + ) + g = sns.heatmap( + weights.T, annot=True, cmap='Blues', xticklabels=model_names, + yticklabels=model_names[1:], annot_kws={"size": 24} + ) + + # x axis on top + g.xaxis.tick_top() + g.xaxis.set_label_position('top') + g.set_xlabel(r"\textbf{Data generated by:}", labelpad=15) + g.set_ylabel(r"\textbf{Model weight for:}", labelpad=15) + g.figure.savefig( + f"{directory}confusionMatrix_ND_{index+1}.pdf", + bbox_inches='tight' + ) + plt.close() + + # ------------------------------------------------------------------------- + def plot_model_weights(self, model_weights, plot_name): + """ + Visualizes the model weights resulting from BMS via the observation + data. + + Parameters + ---------- + model_weights : array + Model weights. + plot_name : str + Plot name. + + Returns + ------- + None. + + """ + font_size = 40 + # mkdir for plots + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + + # Create figure + fig, ax = plt.subplots() + + # Filter data using np.isnan + mask = ~np.isnan(model_weights.T) + filtered_data = [d[m] for d, m in zip(model_weights, mask.T)] + + # Create the boxplot + bp = ax.boxplot(filtered_data, patch_artist=True, showfliers=False) + + # change outline color, fill color and linewidth of the boxes + for box in bp['boxes']: + # change outline color + box.set(color='#7570b3', linewidth=4) + # change fill color + box.set(facecolor='#1b9e77') + + # change color and linewidth of the whiskers + for whisker in bp['whiskers']: + whisker.set(color='#7570b3', linewidth=2) + + # change color and linewidth of the caps + for cap in bp['caps']: + cap.set(color='#7570b3', linewidth=2) + + # change color and linewidth of the medians + for median in bp['medians']: + median.set(color='#b2df8a', linewidth=2) + + # change the style of fliers and their fill + # for flier in bp['fliers']: + # flier.set(marker='o', color='#e7298a', alpha=0.75) + + # Custom x-axis labels + model_names = [model.replace('_', '$-$') for model in self.model_names] + ax.set_xticklabels(model_names) + + ax.set_ylabel('Weight', fontsize=font_size) + + # Title + plt.title('Posterior Model Weights') + + # Set y lim + ax.set_ylim((-0.05, 1.05)) + + # Set size of the ticks + for t in ax.get_xticklabels(): + t.set_fontsize(font_size) + for t in ax.get_yticklabels(): + t.set_fontsize(font_size) + + # Save the figure + fig.savefig( + f'./{directory}{plot_name}.pdf', bbox_inches='tight' + ) + + plt.close() + + # ------------------------------------------------------------------------- + def plot_bayes_factor(self, BME_Dict, plot_name=''): + """ + Plots the Bayes factor distibutions in a :math:`N_m \\times N_m` + matrix, where :math:`N_m` is the number of the models. + + Parameters + ---------- + BME_Dict : dict + A dictionary containing the BME values of the models. + plot_name : str, optional + Plot name. The default is ''. + + Returns + ------- + None. + + """ + + font_size = 40 + + # mkdir for plots + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + + Colors = ["blue", "green", "gray", "brown"] + + model_names = list(BME_Dict.keys()) + nModels = len(model_names) + + # Plots + fig, axes = plt.subplots( + nrows=nModels, ncols=nModels, sharex=True, sharey=True + ) + + for i, key_i in enumerate(model_names): + + for j, key_j in enumerate(model_names): + ax = axes[i, j] + # Set size of the ticks + for t in ax.get_xticklabels(): + t.set_fontsize(font_size) + for t in ax.get_yticklabels(): + t.set_fontsize(font_size) + + if j != i: + + # Null hypothesis: key_j is the better model + BayesFactor = np.log10( + np.divide(BME_Dict[key_i], BME_Dict[key_j]) + ) + + # sns.kdeplot(BayesFactor, ax=ax, color=Colors[i], shade=True) + # sns.histplot(BayesFactor, ax=ax, stat="probability", + # kde=True, element='step', + # color=Colors[j]) + + # taken from seaborn's source code (utils.py and + # distributions.py) + def seaborn_kde_support(data, bw, gridsize, cut, clip): + if clip is None: + clip = (-np.inf, np.inf) + support_min = max(data.min() - bw * cut, clip[0]) + support_max = min(data.max() + bw * cut, clip[1]) + return np.linspace(support_min, support_max, gridsize) + + kde_estim = stats.gaussian_kde( + BayesFactor, bw_method='scott' + ) + + # manual linearization of data + # linearized = np.linspace( + # quotient.min(), quotient.max(), num=500) + + # or better: mimic seaborn's internal stuff + bw = kde_estim.scotts_factor() * np.std(BayesFactor) + linearized = seaborn_kde_support( + BayesFactor, bw, 100, 3, None) + + # computes values of the estimated function on the + # estimated linearized inputs + Z = kde_estim.evaluate(linearized) + + # https://stackoverflow.com/questions/29661574/normalize- + # numpy-array-columns-in-python + def normalize(x): + return (x - x.min(0)) / x.ptp(0) + + # normalize so it is between 0;1 + Z2 = normalize(Z) + ax.plot(linearized, Z2, "-", color=Colors[i], linewidth=4) + ax.fill_between( + linearized, 0, Z2, color=Colors[i], alpha=0.25 + ) + + # Draw BF significant levels according to Jeffreys 1961 + # Strong evidence for both models + ax.axvline( + x=np.log10(3), ymin=0, linewidth=4, color='dimgrey' + ) + # Strong evidence for one model + ax.axvline( + x=np.log10(10), ymin=0, linewidth=4, color='orange' + ) + # Decisive evidence for one model + ax.axvline( + x=np.log10(100), ymin=0, linewidth=4, color='r' + ) + + # legend + BF_label = key_i.replace('_', '$-$') + \ + '/' + key_j.replace('_', '$-$') + legend_elements = [ + patches.Patch(facecolor=Colors[i], edgecolor=Colors[i], + label=f'BF({BF_label})') + ] + ax.legend( + loc='upper left', handles=legend_elements, + fontsize=font_size-(nModels+1)*5 + ) + + elif j == i: + # build a rectangle in axes coords + left, width = 0, 1 + bottom, height = 0, 1 + + # axes coordinates are 0,0 is bottom left and 1,1 is upper + # right + p = patches.Rectangle( + (left, bottom), width, height, color='white', + fill=True, transform=ax.transAxes, clip_on=False + ) + ax.grid(False) + ax.add_patch(p) + # ax.text(0.5*(left+right), 0.5*(bottom+top), key_i, + fsize = font_size+20 if nModels < 4 else font_size + ax.text(0.5, 0.5, key_i.replace('_', '$-$'), + horizontalalignment='center', + verticalalignment='center', + fontsize=fsize, color=Colors[i], + transform=ax.transAxes) + + # Defining custom 'ylim' values. + custom_ylim = (0, 1.05) + + # Setting the values for all axes. + plt.setp(axes, ylim=custom_ylim) + + # set labels + for i in range(nModels): + axes[-1, i].set_xlabel('log$_{10}$(BF)', fontsize=font_size) + axes[i, 0].set_ylabel('Probability', fontsize=font_size) + + # Adjust subplots + plt.subplots_adjust(wspace=0.2, hspace=0.1) + + plt.savefig( + f'./{directory}Bayes_Factor{plot_name}.pdf', bbox_inches='tight' + ) + + plt.close() diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/discrepancy.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/discrepancy.py new file mode 100644 index 000000000..ac1b400c1 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/discrepancy.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import scipy.stats as stats +from bayesvalidrox.surrogate_models.exp_designs import ExpDesigns + + +class Discrepancy: + """ + Discrepancy class for Bayesian inference method. + We define the reference or reality to be equal to what we can model and a + descripancy term \\( \\epsilon \\). We consider the followin format: + + $$\\textbf{y}_{\\text{reality}} = \\mathcal{M}(\\theta) + \\epsilon,$$ + + where \\( \\epsilon \\in R^{N_{out}} \\) represents the the effects of + measurement error and model inaccuracy. For simplicity, it can be defined + as an additive Gaussian disrepancy with zeromean and given covariance + matrix \\( \\Sigma \\): + + $$\\epsilon \\sim \\mathcal{N}(\\epsilon|0, \\Sigma). $$ + + In the context of model inversion or calibration, an observation point + \\( \\textbf{y}_i \\in \\mathcal{y} \\) is a realization of a Gaussian + distribution with mean value of \\(\\mathcal{M}(\\theta) \\) and covariance + matrix of \\( \\Sigma \\). + + $$ p(\\textbf{y}|\\theta) = \\mathcal{N}(\\textbf{y}|\\mathcal{M} + (\\theta))$$ + + The following options are available: + + * Option A: With known redidual covariance matrix \\(\\Sigma\\) for + independent measurements. + + * Option B: With unknown redidual covariance matrix \\(\\Sigma\\), + paramethrized as \\(\\Sigma(\\theta_{\\epsilon})=\\sigma^2 \\textbf{I}_ + {N_{out}}\\) with unknown residual variances \\(\\sigma^2\\). + This term will be jointly infer with the uncertain input parameters. For + the inversion, you need to define a prior marginal via `Input` class. Note + that \\(\\sigma^2\\) is only a single scalar multiplier for the diagonal + entries of the covariance matrix \\(\\Sigma\\). + + Attributes + ---------- + InputDisc : obj + Input object. When the \\(\\sigma^2\\) is expected to be inferred + jointly with the parameters (`Option B`).If multiple output groups are + defined by `Model.Output.names`, each model output needs to have. + a prior marginal using the `Input` class. The default is `''`. + disc_type : str + Type of the noise definition. `'Gaussian'` is only supported so far. + parameters : dict or pandas.DataFrame + Known residual variance \\(\\sigma^2\\), i.e. diagonal entry of the + covariance matrix of the multivariate normal likelihood in case of + `Option A`. + + """ + + def __init__(self, InputDisc='', disc_type='Gaussian', parameters=None): + self.InputDisc = InputDisc + self.disc_type = disc_type + self.parameters = parameters + + # ------------------------------------------------------------------------- + def get_sample(self, n_samples): + """ + Generate samples for the \\(\\sigma^2\\), i.e. the diagonal entries of + the variance-covariance matrix in the multivariate normal distribution. + + Parameters + ---------- + n_samples : int + Number of samples (parameter sets). + + Returns + ------- + sigma2_prior: array of shape (n_samples, n_params) + \\(\\sigma^2\\) samples. + + """ + self.n_samples = n_samples # TODO: not used again in here - needed from the outside? + + # Create and store BoundTuples + self.ExpDesign = ExpDesigns(self.InputDisc) + self.ExpDesign.sampling_method = 'random' + self.ExpDesign.generate_ED( + n_samples, max_pce_deg=1 + ) + # TODO: need to recheck the following line + # This used to simply be the return from the call above + self.sigma2_prior = self.ExpDesign.X + + # Naive approach: Fit a gaussian kernel to the provided data + self.ExpDesign.JDist = stats.gaussian_kde(self.ExpDesign.raw_data) + + # Save the names of sigmas + if len(self.InputDisc.Marginals) != 0: + self.name = [] + for Marginalidx in range(len(self.InputDisc.Marginals)): + self.name.append(self.InputDisc.Marginals[Marginalidx].name) + + return self.sigma2_prior diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/mcmc.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/mcmc.py new file mode 100644 index 000000000..fe22a152f --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayes_inference/mcmc.py @@ -0,0 +1,909 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import numpy as np +import emcee +import pandas as pd +import matplotlib.pyplot as plt +from matplotlib.backends.backend_pdf import PdfPages +import multiprocessing +import scipy.stats as st +from scipy.linalg import cholesky as chol +import warnings +import shutil +os.environ["OMP_NUM_THREADS"] = "1" + + +class MCMC: + """ + A class for bayesian inference via a Markov-Chain Monte-Carlo (MCMC) + Sampler to approximate the posterior distribution of the Bayes theorem: + $$p(\\theta|\\mathcal{y}) = \\frac{p(\\mathcal{y}|\\theta) p(\\theta)} + {p(\\mathcal{y})}.$$ + + This class make inference with emcee package [1] using an Affine Invariant + Ensemble sampler (AIES) [2]. + + [1] Foreman-Mackey, D., Hogg, D.W., Lang, D. and Goodman, J., 2013.emcee: + the MCMC hammer. Publications of the Astronomical Society of the + Pacific, 125(925), p.306. https://emcee.readthedocs.io/en/stable/ + + [2] Goodman, J. and Weare, J., 2010. Ensemble samplers with affine + invariance. Communications in applied mathematics and computational + science, 5(1), pp.65-80. + + + Attributes + ---------- + BayesOpts : obj + Bayes object. + """ + + def __init__(self, BayesOpts): + + self.BayesOpts = BayesOpts + + def run_sampler(self, observation, total_sigma2): + + BayesObj = self.BayesOpts + MetaModel = BayesObj.engine.MetaModel + Model = BayesObj.engine.Model + Discrepancy = self.BayesOpts.Discrepancy + n_cpus = Model.n_cpus + priorDist = BayesObj.engine.ExpDesign.JDist + ndim = MetaModel.n_params + self.counter = 0 + output_dir = f'Outputs_Bayes_{Model.name}_{self.BayesOpts.name}' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + self.observation = observation + self.total_sigma2 = total_sigma2 + + # Unpack mcmc parameters given to BayesObj.mcmc_params + self.initsamples = None + self.nwalkers = 100 + self.nburn = 200 + self.nsteps = 100000 + self.moves = None + self.mp = False + self.verbose = False + + # Extract initial samples + if 'init_samples' in BayesObj.mcmc_params: + self.initsamples = BayesObj.mcmc_params['init_samples'] + if isinstance(self.initsamples, pd.DataFrame): + self.initsamples = self.initsamples.values + + # Extract number of steps per walker + if 'n_steps' in BayesObj.mcmc_params: + self.nsteps = int(BayesObj.mcmc_params['n_steps']) + # Extract number of walkers (chains) + if 'n_walkers' in BayesObj.mcmc_params: + self.nwalkers = int(BayesObj.mcmc_params['n_walkers']) + # Extract moves + if 'moves' in BayesObj.mcmc_params: + self.moves = BayesObj.mcmc_params['moves'] + # Extract multiprocessing + if 'multiprocessing' in BayesObj.mcmc_params: + self.mp = BayesObj.mcmc_params['multiprocessing'] + # Extract verbose + if 'verbose' in BayesObj.mcmc_params: + self.verbose = BayesObj.mcmc_params['verbose'] + + # Set initial samples + np.random.seed(0) + if self.initsamples is None: + try: + initsamples = priorDist.sample(self.nwalkers).T + except: + # when aPCE selected - gaussian kernel distribution + inputSamples = MetaModel.ExpDesign.raw_data.T + random_indices = np.random.choice( + len(inputSamples), size=self.nwalkers, replace=False + ) + initsamples = inputSamples[random_indices] + + else: + if self.initsamples.ndim == 1: + # When MAL is given. + theta = self.initsamples + initsamples = [theta + 1e-1*np.multiply( + np.random.randn(ndim), theta) for i in + range(self.nwalkers)] + else: + # Pick samples based on a uniform dist between min and max of + # each dim + initsamples = np.zeros((self.nwalkers, ndim)) + bound_tuples = [] + for idx_dim in range(ndim): + lower = np.min(self.initsamples[:, idx_dim]) + upper = np.max(self.initsamples[:, idx_dim]) + bound_tuples.append((lower, upper)) + dist = st.uniform(loc=lower, scale=upper-lower) + initsamples[:, idx_dim] = dist.rvs(size=self.nwalkers) + + # Update lower and upper + MetaModel.ExpDesign.bound_tuples = bound_tuples + + # Check if sigma^2 needs to be inferred + if Discrepancy.opt_sigma != 'B': + sigma2_samples = Discrepancy.get_sample(self.nwalkers) + + # Update initsamples + initsamples = np.hstack((initsamples, sigma2_samples)) + + # Update ndim + ndim = initsamples.shape[1] + + # Discrepancy bound + disc_bound_tuple = Discrepancy.ExpDesign.bound_tuples + + # Update bound_tuples + BayesObj.engine.ExpDesign.bound_tuples += disc_bound_tuple + + print("\n>>>> Bayesian inference with MCMC for " + f"{self.BayesOpts.name} started. <<<<<<") + + # Set up the backend + filename = f"{output_dir}/emcee_sampler.h5" + backend = emcee.backends.HDFBackend(filename) + # Clear the backend in case the file already exists + backend.reset(self.nwalkers, ndim) + + # Define emcee sampler + # Here we'll set up the computation. emcee combines multiple "walkers", + # each of which is its own MCMC chain. The number of trace results will + # be nwalkers * nsteps. + if self.mp: + # Run in parallel + if n_cpus is None: + n_cpus = multiprocessing.cpu_count() + + with multiprocessing.Pool(n_cpus) as pool: + sampler = emcee.EnsembleSampler( + self.nwalkers, ndim, self.log_posterior, moves=self.moves, + pool=pool, backend=backend + ) + + # Check if a burn-in phase is needed! + if self.initsamples is None: + # Burn-in + print("\n Burn-in period is starting:") + pos = sampler.run_mcmc( + initsamples, self.nburn, progress=True + ) + + # Reset sampler + sampler.reset() + pos = pos.coords + else: + pos = initsamples + + # Production run + print("\n Production run is starting:") + pos, prob, state = sampler.run_mcmc( + pos, self.nsteps, progress=True + ) + + else: + # Run in series and monitor the convergence + sampler = emcee.EnsembleSampler( + self.nwalkers, ndim, self.log_posterior, moves=self.moves, + backend=backend, vectorize=True + ) + + # Check if a burn-in phase is needed! + if self.initsamples is None: + # Burn-in + print("\n Burn-in period is starting:") + pos = sampler.run_mcmc( + initsamples, self.nburn, progress=True + ) + + # Reset sampler + sampler.reset() + pos = pos.coords + else: + pos = initsamples + + # Production run + print("\n Production run is starting:") + + # Track how the average autocorrelation time estimate changes + autocorrIdx = 0 + autocorr = np.empty(self.nsteps) + tauold = np.inf + autocorreverynsteps = 50 + + # sample step by step using the generator sampler.sample + for sample in sampler.sample(pos, + iterations=self.nsteps, + tune=True, + progress=True): + + # only check convergence every autocorreverynsteps steps + if sampler.iteration % autocorreverynsteps: + continue + + # Train model discrepancy/error + if hasattr(BayesObj, 'errorModel') and BayesObj.errorModel \ + and not sampler.iteration % 3 * autocorreverynsteps: + try: + self.error_MetaModel = self.train_error_model(sampler) + except: + pass + + # Print the current mean acceptance fraction + if self.verbose: + print("\nStep: {}".format(sampler.iteration)) + acc_fr = np.mean(sampler.acceptance_fraction) + print(f"Mean acceptance fraction: {acc_fr:.3f}") + + # compute the autocorrelation time so far + # using tol=0 means that we'll always get an estimate even if + # it isn't trustworthy + tau = sampler.get_autocorr_time(tol=0) + # average over walkers + autocorr[autocorrIdx] = np.nanmean(tau) + autocorrIdx += 1 + + # output current autocorrelation estimate + if self.verbose: + print(f"Mean autocorr. time estimate: {np.nanmean(tau):.3f}") + list_gr = np.round(self.gelman_rubin(sampler.chain), 3) + print("Gelman-Rubin Test*: ", list_gr) + + # check convergence + converged = np.all(tau*autocorreverynsteps < sampler.iteration) + converged &= np.all(np.abs(tauold - tau) / tau < 0.01) + converged &= np.all(self.gelman_rubin(sampler.chain) < 1.1) + + if converged: + break + tauold = tau + + # Posterior diagnostics + try: + tau = sampler.get_autocorr_time(tol=0) + except emcee.autocorr.AutocorrError: + tau = 5 + + if all(np.isnan(tau)): + tau = 5 + + burnin = int(2*np.nanmax(tau)) + thin = int(0.5*np.nanmin(tau)) if int(0.5*np.nanmin(tau)) != 0 else 1 + finalsamples = sampler.get_chain(discard=burnin, flat=True, thin=thin) + acc_fr = np.nanmean(sampler.acceptance_fraction) + list_gr = np.round(self.gelman_rubin(sampler.chain[:, burnin:]), 3) + + # Print summary + print('\n') + print('-'*15 + 'Posterior diagnostics' + '-'*15) + print(f"Mean auto-correlation time: {np.nanmean(tau):.3f}") + print(f"Thin: {thin}") + print(f"Burn-in: {burnin}") + print(f"Flat chain shape: {finalsamples.shape}") + print(f"Mean acceptance fraction*: {acc_fr:.3f}") + print("Gelman-Rubin Test**: ", list_gr) + + print("\n* This value must lay between 0.234 and 0.5.") + print("** These values must be smaller than 1.1.") + print('-'*50) + + print(f"\n>>>> Bayesian inference with MCMC for {self.BayesOpts.name} " + "successfully completed. <<<<<<\n") + + # Extract parameter names and their prior ranges + par_names = self.BayesOpts.engine.ExpDesign.par_names + + if Discrepancy.opt_sigma != 'B': + for i in range(len(Discrepancy.InputDisc.Marginals)): + par_names.append(Discrepancy.InputDisc.Marginals[i].name) + + params_range = self.BayesOpts.engine.ExpDesign.bound_tuples + + # Plot traces + if self.verbose and self.nsteps < 10000: + pdf = PdfPages(output_dir+'/traceplots.pdf') + fig = plt.figure() + for parIdx in range(ndim): + # Set up the axes with gridspec + fig = plt.figure() + grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2) + main_ax = fig.add_subplot(grid[:-1, :3]) + y_hist = fig.add_subplot(grid[:-1, -1], xticklabels=[], + sharey=main_ax) + + for i in range(self.nwalkers): + samples = sampler.chain[i, :, parIdx] + main_ax.plot(samples, '-') + + # histogram on the attached axes + y_hist.hist(samples[burnin:], 40, histtype='stepfilled', + orientation='horizontal', color='gray') + + main_ax.set_ylim(params_range[parIdx]) + main_ax.set_title('traceplot for ' + par_names[parIdx]) + main_ax.set_xlabel('step number') + + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + pdf.close() + + # plot development of autocorrelation estimate + if not self.mp: + fig1 = plt.figure() + steps = autocorreverynsteps*np.arange(1, autocorrIdx+1) + taus = autocorr[:autocorrIdx] + plt.plot(steps, steps / autocorreverynsteps, "--k") + plt.plot(steps, taus) + plt.xlim(0, steps.max()) + plt.ylim(0, np.nanmax(taus)+0.1*(np.nanmax(taus)-np.nanmin(taus))) + plt.xlabel("number of steps") + plt.ylabel(r"mean $\hat{\tau}$") + fig1.savefig(f"{output_dir}/autocorrelation_time.pdf", + bbox_inches='tight') + + # logml_dict = self.marginal_llk_emcee(sampler, self.nburn, logp=None, + # maxiter=5000) + # print('\nThe Bridge Sampling Estimation is " + # f"{logml_dict['logml']:.5f}.') + + # # Posterior-based expectation of posterior probablity + # postExpPostLikelihoods = np.mean(sampler.get_log_prob(flat=True) + # [self.nburn*self.nwalkers:]) + + # # Posterior-based expectation of prior densities + # postExpPrior = np.mean(self.log_prior(emcee_trace.T)) + + # # Posterior-based expectation of likelihoods + # postExpLikelihoods_emcee = postExpPostLikelihoods - postExpPrior + + # # Calculate Kullback-Leibler Divergence + # KLD_emcee = postExpLikelihoods_emcee - logml_dict['logml'] + # print("Kullback-Leibler divergence: %.5f"%KLD_emcee) + + # # Information Entropy based on Entropy paper Eq. 38 + # infEntropy_emcee = logml_dict['logml'] - postExpPrior - + # postExpLikelihoods_emcee + # print("Information Entropy: %.5f" %infEntropy_emcee) + + Posterior_df = pd.DataFrame(finalsamples, columns=par_names) + + return Posterior_df + + # ------------------------------------------------------------------------- + def log_prior(self, theta): + """ + Calculates the log prior likelihood \\( p(\\theta)\\) for the given + parameter set(s) \\( \\theta \\). + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter sets, i.e. proposals of MCMC chains. + + Returns + ------- + logprior: float or array of shape n_samples + Log prior likelihood. If theta has only one row, a single value is + returned otherwise an array. + + """ + + MetaModel = self.BayesOpts.MetaModel + Discrepancy = self.BayesOpts.Discrepancy + + # Find the number of sigma2 parameters + if Discrepancy.opt_sigma != 'B': + disc_bound_tuples = Discrepancy.ExpDesign.bound_tuples + disc_marginals = Discrepancy.ExpDesign.InputObj.Marginals + disc_prior_space = Discrepancy.ExpDesign.prior_space + n_sigma2 = len(disc_bound_tuples) + else: + n_sigma2 = -len(theta) + prior_dist = self.BayesOpts.engine.ExpDesign.prior_space + params_range = self.BayesOpts.engine.ExpDesign.bound_tuples + theta = theta if theta.ndim != 1 else theta.reshape((1, -1)) + nsamples = theta.shape[0] + logprior = -np.inf*np.ones(nsamples) + + for i in range(nsamples): + # Check if the sample is within the parameters' range + if self._check_ranges(theta[i], params_range): + # Check if all dists are uniform, if yes priors are equal. + if all(MetaModel.input_obj.Marginals[i].dist_type == 'uniform' + for i in range(MetaModel.n_params)): + logprior[i] = 0.0 + else: + logprior[i] = np.log( + prior_dist.pdf(theta[i, :-n_sigma2].T) + ) + + # Check if bias term needs to be inferred + if Discrepancy.opt_sigma != 'B': + if self._check_ranges(theta[i, -n_sigma2:], + disc_bound_tuples): + if all('unif' in disc_marginals[i].dist_type for i in + range(Discrepancy.ExpDesign.ndim)): + logprior[i] = 0.0 + else: + logprior[i] += np.log( + disc_prior_space.pdf(theta[i, -n_sigma2:]) + ) + + if nsamples == 1: + return logprior[0] + else: + return logprior + + # ------------------------------------------------------------------------- + def log_likelihood(self, theta): + """ + Computes likelihood \\( p(\\mathcal{Y}|\\theta)\\) of the performance + of the (meta-)model in reproducing the observation data. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + log_like : array of shape (n_samples) + Log likelihood. + + """ + + BayesOpts = self.BayesOpts + MetaModel = BayesOpts.MetaModel + Discrepancy = self.BayesOpts.Discrepancy + + # Find the number of sigma2 parameters + if Discrepancy.opt_sigma != 'B': + disc_bound_tuples = Discrepancy.ExpDesign.bound_tuples + n_sigma2 = len(disc_bound_tuples) + else: + n_sigma2 = -len(theta) + # Check if bias term needs to be inferred + if Discrepancy.opt_sigma != 'B': + sigma2 = theta[:, -n_sigma2:] + theta = theta[:, :-n_sigma2] + else: + sigma2 = None + theta = theta if theta.ndim != 1 else theta.reshape((1, -1)) + + # Evaluate Model/MetaModel at theta + mean_pred, BayesOpts._std_pce_prior_pred = self.eval_model(theta) + + # Surrogate model's error using RMSE of test data + surrError = MetaModel.rmse if hasattr(MetaModel, 'rmse') else None + + # Likelihood + log_like = BayesOpts.normpdf( + mean_pred, self.observation, self.total_sigma2, sigma2, + std=surrError + ) + return log_like + + # ------------------------------------------------------------------------- + def log_posterior(self, theta): + """ + Computes the posterior likelihood \\(p(\\theta| \\mathcal{Y})\\) for + the given parameterset. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + log_like : array of shape (n_samples) + Log posterior likelihood. + + """ + + nsamples = 1 if theta.ndim == 1 else theta.shape[0] + + if nsamples == 1: + if self.log_prior(theta) == -np.inf: + return -np.inf + else: + # Compute log prior + log_prior = self.log_prior(theta) + # Compute log Likelihood + log_likelihood = self.log_likelihood(theta) + + return log_prior + log_likelihood + else: + # Compute log prior + log_prior = self.log_prior(theta) + + # Initialize log_likelihood + log_likelihood = -np.inf*np.ones(nsamples) + + # find the indices for -inf sets + non_inf_idx = np.where(log_prior != -np.inf)[0] + + # Compute loLikelihoods + if non_inf_idx.size != 0: + log_likelihood[non_inf_idx] = self.log_likelihood( + theta[non_inf_idx] + ) + + return log_prior + log_likelihood + + # ------------------------------------------------------------------------- + def eval_model(self, theta): + """ + Evaluates the (meta-) model at the given theta. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + mean_pred : dict + Mean model prediction. + std_pred : dict + Std of model prediction. + + """ + + BayesObj = self.BayesOpts + MetaModel = BayesObj.MetaModel + Model = BayesObj.engine.Model + + if BayesObj.emulator: + # Evaluate the MetaModel + mean_pred, std_pred = MetaModel.eval_metamodel(samples=theta) + else: + # Evaluate the origModel + mean_pred, std_pred = dict(), dict() + + model_outs, _ = Model.run_model_parallel( + theta, prevRun_No=self.counter, + key_str='_MCMC', mp=False, verbose=False) + + # Save outputs in respective dicts + for varIdx, var in enumerate(Model.Output.names): + mean_pred[var] = model_outs[var] + std_pred[var] = np.zeros((mean_pred[var].shape)) + + # Remove the folder + if Model.link_type.lower() != 'function': + shutil.rmtree(f"{Model.name}_MCMC_{self.counter+1}") + + # Add one to the counter + self.counter += 1 + + if hasattr(self, 'error_MetaModel') and BayesObj.error_model: + meanPred, stdPred = self.error_MetaModel.eval_model_error( + BayesObj.BiasInputs, mean_pred + ) + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + def train_error_model(self, sampler): + """ + Trains an error model using a Gaussian Process Regression. + + Parameters + ---------- + sampler : obj + emcee sampler. + + Returns + ------- + error_MetaModel : obj + A error model. + + """ + BayesObj = self.BayesOpts + MetaModel = BayesObj.MetaModel + + # Prepare the poster samples + try: + tau = sampler.get_autocorr_time(tol=0) + except emcee.autocorr.AutocorrError: + tau = 5 + + if all(np.isnan(tau)): + tau = 5 + + burnin = int(2*np.nanmax(tau)) + thin = int(0.5*np.nanmin(tau)) if int(0.5*np.nanmin(tau)) != 0 else 1 + finalsamples = sampler.get_chain(discard=burnin, flat=True, thin=thin) + posterior = finalsamples[:, :MetaModel.n_params] + + # Select posterior mean as MAP + map_theta = posterior.mean(axis=0).reshape((1, MetaModel.n_params)) + # MAP_theta = st.mode(Posterior_df,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_map, y_std_map = MetaModel.eval_metamodel(samples=map_theta) + + # Train a GPR meta-model using MAP + error_MetaModel = MetaModel.create_model_error( + BayesObj.BiasInputs, y_map, name='Calib') + + return error_MetaModel + + # ------------------------------------------------------------------------- + def gelman_rubin(self, chain, return_var=False): + """ + The potential scale reduction factor (PSRF) defined by the variance + within one chain, W, with the variance between chains B. + Both variances are combined in a weighted sum to obtain an estimate of + the variance of a parameter \\( \\theta \\).The square root of the + ratio of this estimates variance to the within chain variance is called + the potential scale reduction. + For a well converged chain it should approach 1. Values greater than + 1.1 typically indicate that the chains have not yet fully converged. + + Source: http://joergdietrich.github.io/emcee-convergence.html + + https://github.com/jwalton3141/jwalton3141.github.io/blob/master/assets/posts/ESS/rwmh.py + + Parameters + ---------- + chain : array (n_walkers, n_steps, n_params) + The emcee ensamples. + + Returns + ------- + R_hat : float + The Gelman-Robin values. + + """ + m_chains, n_iters = chain.shape[:2] + + # Calculate between-chain variance + θb = np.mean(chain, axis=1) + θbb = np.mean(θb, axis=0) + B_over_n = ((θbb - θb)**2).sum(axis=0) + B_over_n /= (m_chains - 1) + + # Calculate within-chain variances + ssq = np.var(chain, axis=1, ddof=1) + W = np.mean(ssq, axis=0) + + # (over) estimate of variance + var_θ = W * (n_iters - 1) / n_iters + B_over_n + + if return_var: + return var_θ + else: + # The square root of the ratio of this estimates variance to the + # within chain variance + R_hat = np.sqrt(var_θ / W) + return R_hat + + # ------------------------------------------------------------------------- + def marginal_llk_emcee(self, sampler, nburn=None, logp=None, maxiter=1000): + """ + The Bridge Sampling Estimator of the Marginal Likelihood based on + https://gist.github.com/junpenglao/4d2669d69ddfe1d788318264cdcf0583 + + Parameters + ---------- + sampler : TYPE + MultiTrace, result of MCMC run. + nburn : int, optional + Number of burn-in step. The default is None. + logp : TYPE, optional + Model Log-probability function. The default is None. + maxiter : int, optional + Maximum number of iterations. The default is 1000. + + Returns + ------- + marg_llk : dict + Estimated Marginal log-Likelihood. + + """ + r0, tol1, tol2 = 0.5, 1e-10, 1e-4 + + if logp is None: + logp = sampler.log_prob_fn + + # Split the samples into two parts + # Use the first 50% for fiting the proposal distribution + # and the second 50% in the iterative scheme. + if nburn is None: + mtrace = sampler.chain + else: + mtrace = sampler.chain[:, nburn:, :] + + nchain, len_trace, nrofVars = mtrace.shape + + N1_ = len_trace // 2 + N1 = N1_*nchain + N2 = len_trace*nchain - N1 + + samples_4_fit = np.zeros((nrofVars, N1)) + samples_4_iter = np.zeros((nrofVars, N2)) + effective_n = np.zeros((nrofVars)) + + # matrix with already transformed samples + for var in range(nrofVars): + + # for fitting the proposal + x = mtrace[:, :N1_, var] + + samples_4_fit[var, :] = x.flatten() + # for the iterative scheme + x2 = mtrace[:, N1_:, var] + samples_4_iter[var, :] = x2.flatten() + + # effective sample size of samples_4_iter, scalar + effective_n[var] = self._my_ESS(x2) + + # median effective sample size (scalar) + neff = np.median(effective_n) + + # get mean & covariance matrix and generate samples from proposal + m = np.mean(samples_4_fit, axis=1) + V = np.cov(samples_4_fit) + L = chol(V, lower=True) + + # Draw N2 samples from the proposal distribution + gen_samples = m[:, None] + np.dot( + L, st.norm.rvs(0, 1, size=samples_4_iter.shape) + ) + + # Evaluate proposal distribution for posterior & generated samples + q12 = st.multivariate_normal.logpdf(samples_4_iter.T, m, V) + q22 = st.multivariate_normal.logpdf(gen_samples.T, m, V) + + # Evaluate unnormalized posterior for posterior & generated samples + q11 = logp(samples_4_iter.T) + q21 = logp(gen_samples.T) + + # Run iterative scheme: + tmp = self._iterative_scheme( + N1, N2, q11, q12, q21, q22, r0, neff, tol1, maxiter, 'r' + ) + if ~np.isfinite(tmp['logml']): + warnings.warn( + "Logml could not be estimated within maxiter, rerunning with " + "adjusted starting value. Estimate might be more variable than" + " usual.") + # use geometric mean as starting value + r0_2 = np.sqrt(tmp['r_vals'][-2]*tmp['r_vals'][-1]) + tmp = self._iterative_scheme( + q11, q12, q21, q22, r0_2, neff, tol2, maxiter, 'logml' + ) + + marg_llk = dict( + logml=tmp['logml'], niter=tmp['niter'], method="normal", + q11=q11, q12=q12, q21=q21, q22=q22 + ) + return marg_llk + + # ------------------------------------------------------------------------- + def _iterative_scheme(self, N1, N2, q11, q12, q21, q22, r0, neff, tol, + maxiter, criterion): + """ + Iterative scheme as proposed in Meng and Wong (1996) to estimate the + marginal likelihood + + """ + l1 = q11 - q12 + l2 = q21 - q22 + # To increase numerical stability, + # subtracting the median of l1 from l1 & l2 later + lstar = np.median(l1) + s1 = neff/(neff + N2) + s2 = N2/(neff + N2) + r = r0 + r_vals = [r] + logml = np.log(r) + lstar + criterion_val = 1 + tol + + i = 0 + while (i <= maxiter) & (criterion_val > tol): + rold = r + logmlold = logml + numi = np.exp(l2 - lstar)/(s1 * np.exp(l2 - lstar) + s2 * r) + deni = 1/(s1 * np.exp(l1 - lstar) + s2 * r) + if np.sum(~np.isfinite(numi))+np.sum(~np.isfinite(deni)) > 0: + warnings.warn( + """Infinite value in iterative scheme, returning NaN. + Try rerunning with more samples.""") + r = (N1/N2) * np.sum(numi)/np.sum(deni) + r_vals.append(r) + logml = np.log(r) + lstar + i += 1 + if criterion == 'r': + criterion_val = np.abs((r - rold)/r) + elif criterion == 'logml': + criterion_val = np.abs((logml - logmlold)/logml) + + if i >= maxiter: + return dict(logml=np.NaN, niter=i, r_vals=np.asarray(r_vals)) + else: + return dict(logml=logml, niter=i) + + # ------------------------------------------------------------------------- + def _my_ESS(self, x): + """ + Compute the effective sample size of estimand of interest. + Vectorised implementation. + https://github.com/jwalton3141/jwalton3141.github.io/blob/master/assets/posts/ESS/rwmh.py + + + Parameters + ---------- + x : array of shape (n_walkers, n_steps) + MCMC Samples. + + Returns + ------- + int + Effective sample size. + + """ + m_chains, n_iters = x.shape + + def variogram(t): + variogram = ((x[:, t:] - x[:, :(n_iters - t)])**2).sum() + variogram /= (m_chains * (n_iters - t)) + return variogram + + post_var = self.gelman_rubin(x, return_var=True) + + t = 1 + rho = np.ones(n_iters) + negative_autocorr = False + + # Iterate until the sum of consecutive estimates of autocorrelation is + # negative + while not negative_autocorr and (t < n_iters): + rho[t] = 1 - variogram(t) / (2 * post_var) + + if not t % 2: + negative_autocorr = sum(rho[t-1:t+1]) < 0 + + t += 1 + + return int(m_chains*n_iters / (1 + 2*rho[1:t].sum())) + + # ------------------------------------------------------------------------- + def _check_ranges(self, theta, ranges): + """ + This function checks if theta lies in the given ranges. + + Parameters + ---------- + theta : array + Proposed parameter set. + ranges : nested list + List of the praremeter ranges. + + Returns + ------- + c : bool + If it lies in the given range, it return True else False. + + """ + c = True + # traverse in the list1 + for i, bounds in enumerate(ranges): + x = theta[i] + # condition check + if x < bounds[0] or x > bounds[1]: + c = False + return c + return c diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayesvalidrox.mplstyle b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayesvalidrox.mplstyle new file mode 100644 index 000000000..1f31c01f2 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/bayesvalidrox.mplstyle @@ -0,0 +1,16 @@ +figure.titlesize : 30 +axes.titlesize : 30 +axes.labelsize : 30 +axes.linewidth : 3 +axes.grid : True +lines.linewidth : 3 +lines.markersize : 10 +xtick.labelsize : 30 +ytick.labelsize : 30 +legend.fontsize : 30 +font.family : serif +font.serif : Arial +font.size : 30 +text.usetex : True +grid.linestyle : - +figure.figsize : 24, 16 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__init__.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__init__.py new file mode 100644 index 000000000..81c982542 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .post_processing import PostProcessing + +__all__ = [ + "PostProcessing" + ] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8590a242166b2e8d40de7ee2eece71980bd1571 GIT binary patch literal 261 zcmZ8bu};G<5Vf5GRYl8y)IVUz!u<fM7!d7*A|aM6CpWel3nz|z4z!=dFJ)!o7g*rZ ziSnd-r+4q2?!tUN6O76AjZNG?NAVYm#XT1-nT#;fi$<1G3Zr(iR3>{C`Q%Honag2O z1WH8=l_hfRE{@Ajc{W^iJjd?T7%mXC_lO@No^kL<-z79{f(l;9MuPYnYF}$j@DQrL zv27w)yR_-I@aV&Pp;HZ8eX#VVy)!ZF;ol`dbgfH>x7}fw-ZjDW-mb=X>740Oscic5 E3kw-WVE_OC literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d21ad3c9193151d5353eea7e29d38f3b43e4b39 GIT binary patch literal 295 zcmZ3^%ge<81T4a;sU<-AF^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%zJUDVl7OQ8<kaHg%)Im>W}vX2Ci5-+0-$(&0jk6;_W1b3oSgXhl?<Oj z*8B={wu%WYPAw{qDay{z$jL}dERJ!>PcF?(%_}L6anCIAC{2oS%gHYfNG!>SNlL6t zEiOyU$xJEAuZTgjASOOOGcU6wK3=b&@)w6qZhlH>PO4oIC(s&@Q;Ri$#0O?ZM#c|p d42(J#7_^ZQP>fad12YphTLU`?7O?|W0{}&mQW5|F literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58a0eb24635d0b97a14d13708e616de6a0659976 GIT binary patch literal 326 zcmZ9G&q@O^5XO_;ibbs6e1|=xP{fOf2=(GYS&#)Ofsk&pH8lT7Hl_9IbNB$hg4e#q zUOo8=UUarz)Pea8Gv7DE@X_c1K|H^0g@O9sH@_o;<_a>N00a_PBZFrcBatoeEED-X zDh3}I!~%CmrHgGDTrFc%b`kpJyCUz7J<OT^D|GveajhA9MPUz&JAA%O&uJB9h&0Hh zn^2KVTK|w3Wo6)6J@HmKOB%`B6ePKsmgKs+tsYLtXLO#F7Nj<ODJl0}Q&oE^0mL-4 zQI_i<W72J0O&(eA3dzzr-^jRv%Obcn{r4<oOj*@3HujrtcwwAKT3+VxaU1{+^X%&z DlmueV literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0924d8afac04d4fe82ebe791bc55a8ae48d7c117 GIT binary patch literal 28679 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2922ed407a89b026bf4d9e031464e011a7ad4a9b GIT binary patch literal 58838 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 C=CgqS literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..312575d7655db85df423489051f494f3dce62692 GIT binary patch literal 28771 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/post_processing.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/post_processing.py new file mode 100644 index 000000000..6520a40f9 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/post_processing/post_processing.py @@ -0,0 +1,1338 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import math +import os +from itertools import combinations, cycle +import pandas as pd +import scipy.stats as stats +from sklearn.linear_model import LinearRegression +from sklearn.metrics import mean_squared_error, r2_score +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +from matplotlib.offsetbox import AnchoredText +from matplotlib.patches import Patch +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class PostProcessing: + """ + This class provides many helper functions to post-process the trained + meta-model. + + Attributes + ---------- + MetaModel : obj + MetaModel object to do postprocessing on. + name : str + Type of the anaylsis. The default is `'calib'`. If a validation is + expected to be performed change this to `'valid'`. + """ + + def __init__(self, engine, name='calib'): + self.engine = engine + self.MetaModel = engine.MetaModel + self.ExpDesign = engine.ExpDesign + self.ModelObj = engine.Model + self.name = name + + # ------------------------------------------------------------------------- + def plot_moments(self, xlabel='Time [s]', plot_type=None): + """ + Plots the moments in a pdf format in the directory + `Outputs_PostProcessing`. + + Parameters + ---------- + xlabel : str, optional + String to be displayed as x-label. The default is `'Time [s]'`. + plot_type : str, optional + Options: bar or line. The default is `None`. + + Returns + ------- + pce_means: dict + Mean of the model outputs. + pce_means: dict + Standard deviation of the model outputs. + + """ + + bar_plot = True if plot_type == 'bar' else False + meta_model_type = self.MetaModel.meta_model_type + Model = self.ModelObj + + # Read Monte-Carlo reference + self.mc_reference = Model.read_observation('mc_ref') + + # Set the x values + x_values_orig = self.engine.ExpDesign.x_values + + # Compute the moments with the PCEModel object + self.pce_means, self.pce_stds = self.compute_pce_moments() + + # Get the variables + out_names = Model.Output.names + + # Open a pdf for the plots + newpath = (f'Outputs_PostProcessing_{self.name}/') + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Plot the best fit line, set the linewidth (lw), color and + # transparency (alpha) of the line + for key in out_names: + fig, ax = plt.subplots(nrows=1, ncols=2) + + # Extract mean and std + mean_data = self.pce_means[key] + std_data = self.pce_stds[key] + + # Extract a list of x values + if type(x_values_orig) is dict: + x = x_values_orig[key] + else: + x = x_values_orig + + # Plot: bar plot or line plot + if bar_plot: + ax[0].bar(list(map(str, x)), mean_data, color='b', + width=0.25) + ax[1].bar(list(map(str, x)), std_data, color='b', + width=0.25) + ax[0].legend(labels=[meta_model_type]) + ax[1].legend(labels=[meta_model_type]) + else: + ax[0].plot(x, mean_data, lw=3, color='k', marker='x', + label=meta_model_type) + ax[1].plot(x, std_data, lw=3, color='k', marker='x', + label=meta_model_type) + + if self.mc_reference is not None: + if bar_plot: + ax[0].bar(list(map(str, x)), self.mc_reference['mean'], + color='r', width=0.25) + ax[1].bar(list(map(str, x)), self.mc_reference['std'], + color='r', width=0.25) + ax[0].legend(labels=[meta_model_type]) + ax[1].legend(labels=[meta_model_type]) + else: + ax[0].plot(x, self.mc_reference['mean'], lw=3, marker='x', + color='r', label='Ref.') + ax[1].plot(x, self.mc_reference['std'], lw=3, marker='x', + color='r', label='Ref.') + + # Label the axes and provide a title + ax[0].set_xlabel(xlabel) + ax[1].set_xlabel(xlabel) + ax[0].set_ylabel(key) + ax[1].set_ylabel(key) + + # Provide a title + ax[0].set_title('Mean of ' + key) + ax[1].set_title('Std of ' + key) + + if not bar_plot: + ax[0].legend(loc='best') + ax[1].legend(loc='best') + + plt.tight_layout() + + # save the current figure + fig.savefig( + f'./{newpath}Mean_Std_PCE_{key}.pdf', + bbox_inches='tight' + ) + + return self.pce_means, self.pce_stds + + # ------------------------------------------------------------------------- + def valid_metamodel(self, n_samples=1, samples=None, model_out_dict=None, + x_axis='Time [s]'): + """ + Evaluates and plots the meta model and the PCEModel outputs for the + given number of samples or the given samples. + + Parameters + ---------- + n_samples : int, optional + Number of samples to be evaluated. The default is 1. + samples : array of shape (n_samples, n_params), optional + Samples to be evaluated. The default is None. + model_out_dict: dict + The model runs using the samples provided. + x_axis : str, optional + Label of x axis. The default is `'Time [s]'`. + + Returns + ------- + None. + + """ + MetaModel = self.MetaModel + Model = self.ModelObj + + if samples is None: + self.n_samples = n_samples + samples = self._get_sample() + else: + self.n_samples = samples.shape[0] + + # Extract x_values + x_values = self.engine.ExpDesign.x_values + + if model_out_dict is not None: + self.model_out_dict = model_out_dict + else: + self.model_out_dict = self._eval_model(samples, key_str='valid') + self.pce_out_mean, self.pce_out_std = MetaModel.eval_metamodel(samples) + + try: + key = Model.Output.names[1] + except IndexError: + key = Model.Output.names[0] + + n_obs = self.model_out_dict[key].shape[1] + + if n_obs == 1: + self._plot_validation() + else: + self._plot_validation_multi(x_values=x_values, x_axis=x_axis) + + # ------------------------------------------------------------------------- + def check_accuracy(self, n_samples=None, samples=None, outputs=None): + """ + Checks accuracy of the metamodel by computing the root mean square + error and validation error for all outputs. + + Parameters + ---------- + n_samples : int, optional + Number of samples. The default is None. + samples : array of shape (n_samples, n_params), optional + Parameter sets to be checked. The default is None. + outputs : dict, optional + Output dictionary with model outputs for all given output types in + `Model.Output.names`. The default is None. + + Raises + ------ + Exception + When neither n_samples nor samples are provided. + + Returns + ------- + rmse: dict + Root mean squared error for each output. + valid_error : dict + Validation error for each output. + + """ + MetaModel = self.MetaModel + Model = self.ModelObj + + # Set the number of samples + if n_samples: + self.n_samples = n_samples + elif samples is not None: + self.n_samples = samples.shape[0] + else: + raise Exception("Please provide either samples or pass the number" + " of samples!") + + # Generate random samples if necessary + Samples = self._get_sample() if samples is None else samples + + # Run the original model with the generated samples + if outputs is None: + outputs = self._eval_model(Samples, key_str='validSet') + + # Run the PCE model with the generated samples + pce_outputs, _ = MetaModel.eval_metamodel(samples=Samples) + + self.rmse = {} + self.valid_error = {} + # Loop over the keys and compute RMSE error. + for key in Model.Output.names: + # Root mena square + self.rmse[key] = mean_squared_error(outputs[key], pce_outputs[key], + squared=False, + multioutput='raw_values') + # Validation error + self.valid_error[key] = (self.rmse[key]**2) / \ + np.var(outputs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(self.rmse[key], + self.valid_error[key])))) + # Save error dicts in PCEModel object + self.MetaModel.rmse = self.rmse + self.MetaModel.valid_error = self.valid_error + + return + + # ------------------------------------------------------------------------- + def plot_seq_design_diagnostics(self, ref_BME_KLD=None): + """ + Plots the Bayesian Model Evidence (BME) and Kullback-Leibler divergence + (KLD) for the sequential design. + + Parameters + ---------- + ref_BME_KLD : array, optional + Reference BME and KLD . The default is `None`. + + Returns + ------- + None. + + """ + engine = self.engine + PCEModel = self.MetaModel + n_init_samples = engine.ExpDesign.n_init_samples + n_total_samples = engine.ExpDesign.X.shape[0] + + newpath = f'Outputs_PostProcessing_{self.name}/seq_design_diagnostics/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + plotList = ['Modified LOO error', 'Validation error', 'KLD', 'BME', + 'RMSEMean', 'RMSEStd', 'Hellinger distance'] + seqList = [engine.SeqModifiedLOO, engine.seqValidError, + engine.SeqKLD, engine.SeqBME, engine.seqRMSEMean, + engine.seqRMSEStd, engine.SeqDistHellinger] + + markers = ('x', 'o', 'd', '*', '+') + colors = ('k', 'darkgreen', 'b', 'navy', 'darkred') + + # Plot the evolution of the diagnostic criteria of the + # Sequential Experimental Design. + for plotidx, plot in enumerate(plotList): + fig, ax = plt.subplots() + seq_dict = seqList[plotidx] + name_util = list(seq_dict.keys()) + + if len(name_util) == 0: + continue + + # Box plot when Replications have been detected. + if any(int(name.split("rep_", 1)[1]) > 1 for name in name_util): + # Extract the values from dict + sorted_seq_opt = {} + # Number of replications + n_reps = engine.ExpDesign.n_replication + + # Get the list of utility function names + # Handle if only one UtilityFunction is provided + if not isinstance(engine.ExpDesign.util_func, list): + util_funcs = [engine.ExpDesign.util_func] + else: + util_funcs = engine.ExpDesign.util_func + + for util in util_funcs: + sortedSeq = {} + # min number of runs available from reps + n_runs = min([seq_dict[f'{util}_rep_{i+1}'].shape[0] + for i in range(n_reps)]) + + for runIdx in range(n_runs): + values = [] + for key in seq_dict.keys(): + if util in key: + values.append(seq_dict[key][runIdx].mean()) + sortedSeq['SeqItr_'+str(runIdx)] = np.array(values) + sorted_seq_opt[util] = sortedSeq + + # BoxPlot + def draw_plot(data, labels, edge_color, fill_color, idx): + pos = labels - (idx-1) + bp = plt.boxplot(data, positions=pos, labels=labels, + patch_artist=True, sym='', widths=0.75) + elements = ['boxes', 'whiskers', 'fliers', 'means', + 'medians', 'caps'] + for element in elements: + plt.setp(bp[element], color=edge_color[idx]) + + for patch in bp['boxes']: + patch.set(facecolor=fill_color[idx]) + + if engine.ExpDesign.n_new_samples != 1: + step1 = engine.ExpDesign.n_new_samples + step2 = 1 + else: + step1 = 5 + step2 = 5 + edge_color = ['red', 'blue', 'green'] + fill_color = ['tan', 'cyan', 'lightgreen'] + plot_label = plot + # Plot for different Utility Functions + for idx, util in enumerate(util_funcs): + all_errors = np.empty((n_reps, 0)) + + for key in list(sorted_seq_opt[util].keys()): + errors = sorted_seq_opt.get(util, {}).get(key)[:, None] + all_errors = np.hstack((all_errors, errors)) + + # Special cases for BME and KLD + if plot == 'KLD' or plot == 'BME': + # BME convergence if refBME is provided + if ref_BME_KLD is not None: + if plot == 'BME': + refValue = ref_BME_KLD[0] + plot_label = r'BME/BME$^{Ref.}$' + if plot == 'KLD': + refValue = ref_BME_KLD[1] + plot_label = '$D_{KL}[p(\\theta|y_*),p(\\theta)]'\ + ' / D_{KL}^{Ref.}[p(\\theta|y_*), '\ + 'p(\\theta)]$' + + # Difference between BME/KLD and the ref. values + all_errors = np.divide(all_errors, + np.full((all_errors.shape), + refValue)) + + # Plot baseline for zero, i.e. no difference + plt.axhline(y=1.0, xmin=0, xmax=1, c='green', + ls='--', lw=2) + + # Plot each UtilFuncs + labels = np.arange(n_init_samples, n_total_samples+1, step1) + draw_plot(all_errors[:, ::step2], labels, edge_color, + fill_color, idx) + + plt.xticks(labels, labels) + # Set the major and minor locators + ax.xaxis.set_major_locator(ticker.AutoLocator()) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.xaxis.grid(True, which='major', linestyle='-') + ax.xaxis.grid(True, which='minor', linestyle='--') + + # Legend + legend_elements = [] + for idx, util in enumerate(util_funcs): + legend_elements.append(Patch(facecolor=fill_color[idx], + edgecolor=edge_color[idx], + label=util)) + plt.legend(handles=legend_elements[::-1], loc='best') + + if plot != 'BME' and plot != 'KLD': + plt.yscale('log') + plt.autoscale(True) + plt.xlabel('\\# of training samples') + plt.ylabel(plot_label) + plt.title(plot) + + # save the current figure + plot_name = plot.replace(' ', '_') + fig.savefig( + f'./{newpath}/seq_{plot_name}.pdf', + bbox_inches='tight' + ) + # Destroy the current plot + plt.clf() + # Save arrays into files + f = open(f'./{newpath}/seq_{plot_name}.txt', 'w') + f.write(str(sorted_seq_opt)) + f.close() + else: + for idx, name in enumerate(name_util): + seq_values = seq_dict[name] + if engine.ExpDesign.n_new_samples != 1: + step = engine.ExpDesign.n_new_samples + else: + step = 1 + x_idx = np.arange(n_init_samples, n_total_samples+1, step) + if n_total_samples not in x_idx: + x_idx = np.hstack((x_idx, n_total_samples)) + + if plot == 'KLD' or plot == 'BME': + # BME convergence if refBME is provided + if ref_BME_KLD is not None: + if plot == 'BME': + refValue = ref_BME_KLD[0] + plot_label = r'BME/BME$^{Ref.}$' + if plot == 'KLD': + refValue = ref_BME_KLD[1] + plot_label = '$D_{KL}[p(\\theta|y_*),p(\\theta)]'\ + ' / D_{KL}^{Ref.}[p(\\theta|y_*), '\ + 'p(\\theta)]$' + + # Difference between BME/KLD and the ref. values + values = np.divide(seq_values, + np.full((seq_values.shape), + refValue)) + + # Plot baseline for zero, i.e. no difference + plt.axhline(y=1.0, xmin=0, xmax=1, c='green', + ls='--', lw=2) + + # Set the limits + plt.ylim([1e-1, 1e1]) + + # Create the plots + plt.semilogy(x_idx, values, marker=markers[idx], + color=colors[idx], ls='--', lw=2, + label=name.split("_rep", 1)[0]) + else: + plot_label = plot + + # Create the plots + plt.plot(x_idx, seq_values, marker=markers[idx], + color=colors[idx], ls='--', lw=2, + label=name.split("_rep", 1)[0]) + + else: + plot_label = plot + seq_values = np.nan_to_num(seq_values) + + # Plot the error evolution for each output + plt.semilogy(x_idx, seq_values.mean(axis=1), + marker=markers[idx], ls='--', lw=2, + color=colors[idx], + label=name.split("_rep", 1)[0]) + + # Set the major and minor locators + ax.xaxis.set_major_locator(ticker.AutoLocator()) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.xaxis.grid(True, which='major', linestyle='-') + ax.xaxis.grid(True, which='minor', linestyle='--') + + ax.tick_params(axis='both', which='major', direction='in', + width=3, length=10) + ax.tick_params(axis='both', which='minor', direction='in', + width=2, length=8) + plt.xlabel('Number of runs') + plt.ylabel(plot_label) + plt.title(plot) + plt.legend(frameon=True) + + # save the current figure + plot_name = plot.replace(' ', '_') + fig.savefig( + f'./{newpath}/seq_{plot_name}.pdf', + bbox_inches='tight' + ) + # Destroy the current plot + plt.clf() + + # ---------------- Saving arrays into files --------------- + np.save(f'./{newpath}/seq_{plot_name}.npy', seq_values) + + return + + # ------------------------------------------------------------------------- + def sobol_indices(self, xlabel='Time [s]', plot_type=None): + """ + Provides Sobol indices as a sensitivity measure to infer the importance + of the input parameters. See Eq. 27 in [1] for more details. For the + case with Principal component analysis refer to [2]. + + [1] Global sensitivity analysis: A flexible and efficient framework + with an example from stochastic hydrogeology S. Oladyshkin, F.P. + de Barros, W. Nowak https://doi.org/10.1016/j.advwatres.2011.11.001 + + [2] Nagel, J.B., Rieckermann, J. and Sudret, B., 2020. Principal + component analysis and sparse polynomial chaos expansions for global + sensitivity analysis and model calibration: Application to urban + drainage simulation. Reliability Engineering & System Safety, 195, + p.106737. + + Parameters + ---------- + xlabel : str, optional + Label of the x-axis. The default is `'Time [s]'`. + plot_type : str, optional + Plot type. The default is `None`. This corresponds to line plot. + Bar chart can be selected by `bar`. + + Returns + ------- + sobol_cell: dict + Sobol indices. + total_sobol: dict + Total Sobol indices. + + """ + # Extract the necessary variables + PCEModel = self.MetaModel + basis_dict = PCEModel.basis_dict + coeffs_dict = PCEModel.coeffs_dict + n_params = PCEModel.n_params + max_order = np.max(PCEModel.pce_deg) + sobol_cell_b = {} + total_sobol_b = {} + cov_Z_p_q = np.zeros((n_params)) + + for b_i in range(PCEModel.n_bootstrap_itrs): + + sobol_cell_, total_sobol_ = {}, {} + + for output in self.ModelObj.Output.names: + + n_meas_points = len(coeffs_dict[f'b_{b_i+1}'][output]) + + # Initialize the (cell) array containing the (total) Sobol indices. + sobol_array = dict.fromkeys(range(1, max_order+1), []) + sobol_cell_array = dict.fromkeys(range(1, max_order+1), []) + + for i_order in range(1, max_order+1): + n_comb = math.comb(n_params, i_order) + + sobol_cell_array[i_order] = np.zeros((n_comb, n_meas_points)) + + total_sobol_array = np.zeros((n_params, n_meas_points)) + + # Initialize the cell to store the names of the variables + TotalVariance = np.zeros((n_meas_points)) + # Loop over all measurement points and calculate sobol indices + for pIdx in range(n_meas_points): + + # Extract the basis indices (alpha) and coefficients + Basis = basis_dict[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + + try: + clf_poly = PCEModel.clf_poly[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + PCECoeffs = clf_poly.coef_ + except: + PCECoeffs = coeffs_dict[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + + # Compute total variance + TotalVariance[pIdx] = np.sum(np.square(PCECoeffs[1:])) + + nzidx = np.where(PCECoeffs != 0)[0] + # Set all the Sobol indices equal to zero in the presence of a + # null output. + if len(nzidx) == 0: + # This is buggy. + for i_order in range(1, max_order+1): + sobol_cell_array[i_order][:, pIdx] = 0 + + # Otherwise compute them by summing well-chosen coefficients + else: + nz_basis = Basis[nzidx] + for i_order in range(1, max_order+1): + idx = np.where(np.sum(nz_basis > 0, axis=1) == i_order) + subbasis = nz_basis[idx] + Z = np.array(list(combinations(range(n_params), i_order))) + + for q in range(Z.shape[0]): + Zq = Z[q] + subsubbasis = subbasis[:, Zq] + subidx = np.prod(subsubbasis, axis=1) > 0 + sum_ind = nzidx[idx[0][subidx]] + if TotalVariance[pIdx] == 0.0: + sobol_cell_array[i_order][q, pIdx] = 0.0 + else: + sobol = np.sum(np.square(PCECoeffs[sum_ind])) + sobol /= TotalVariance[pIdx] + sobol_cell_array[i_order][q, pIdx] = sobol + + # Compute the TOTAL Sobol indices. + for ParIdx in range(n_params): + idx = nz_basis[:, ParIdx] > 0 + sum_ind = nzidx[idx] + + if TotalVariance[pIdx] == 0.0: + total_sobol_array[ParIdx, pIdx] = 0.0 + else: + sobol = np.sum(np.square(PCECoeffs[sum_ind])) + sobol /= TotalVariance[pIdx] + total_sobol_array[ParIdx, pIdx] = sobol + + # ----- if PCA selected: Compute covariance ----- + if PCEModel.dim_red_method.lower() == 'pca': + # Extract the basis indices (alpha) and coefficients for + # next component + if pIdx < n_meas_points-1: + nextBasis = basis_dict[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + if PCEModel.bootstrap_method != 'fast' or b_i == 0: + clf_poly = PCEModel.clf_poly[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + nextPCECoeffs = clf_poly.coef_ + else: + nextPCECoeffs = coeffs_dict[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + + # Choose the common non-zero basis + mask = (Basis[:, None] == nextBasis).all(-1).any(-1) + n_mask = (nextBasis[:, None] == Basis).all(-1).any(-1) + + # Compute the covariance in Eq 17. + for ParIdx in range(n_params): + idx = (mask) & (Basis[:, ParIdx] > 0) + n_idx = (n_mask) & (nextBasis[:, ParIdx] > 0) + try: + cov_Z_p_q[ParIdx] += np.sum(np.dot( + PCECoeffs[idx], nextPCECoeffs[n_idx]) + ) + except: + pass + + # Compute the sobol indices according to Ref. 2 + if PCEModel.dim_red_method.lower() == 'pca': + n_c_points = self.engine.ExpDesign.Y[output].shape[1] + PCA = PCEModel.pca[f'b_{b_i+1}'][output] + compPCA = PCA.components_ + nComp = compPCA.shape[0] + var_Z_p = PCA.explained_variance_ + + # Extract the sobol index of the components + for i_order in range(1, max_order+1): + n_comb = math.comb(n_params, i_order) + sobol_array[i_order] = np.zeros((n_comb, n_c_points)) + Z = np.array(list(combinations(range(n_params), i_order))) + + # Loop over parameters + for q in range(Z.shape[0]): + S_Z_i = sobol_cell_array[i_order][q] + + for tIdx in range(n_c_points): + var_Y_t = np.var( + self.engine.ExpDesign.Y[output][:, tIdx]) + if var_Y_t == 0.0: + term1, term2 = 0.0, 0.0 + else: + # Eq. 17 + term1 = 0.0 + for i in range(nComp): + a = S_Z_i[i] * var_Z_p[i] + a *= compPCA[i, tIdx]**2 + term1 += a + + # TODO: Term 2 + # term2 = 0.0 + # for i in range(nComp-1): + # term2 += cov_Z_p_q[q] * compPCA[i, tIdx] + # term2 *= compPCA[i+1, tIdx] + # term2 *= 2 + + sobol_array[i_order][q, tIdx] = term1 #+ term2 + + # Devide over total output variance Eq. 18 + sobol_array[i_order][q, tIdx] /= var_Y_t + + # Compute the TOTAL Sobol indices. + total_sobol = np.zeros((n_params, n_c_points)) + for ParIdx in range(n_params): + S_Z_i = total_sobol_array[ParIdx] + + for tIdx in range(n_c_points): + var_Y_t = np.var(self.engine.ExpDesign.Y[output][:, tIdx]) + if var_Y_t == 0.0: + term1, term2 = 0.0, 0.0 + else: + term1 = 0 + for i in range(nComp): + term1 += S_Z_i[i] * var_Z_p[i] * \ + (compPCA[i, tIdx]**2) + + # Term 2 + term2 = 0 + for i in range(nComp-1): + term2 += cov_Z_p_q[ParIdx] * compPCA[i, tIdx] \ + * compPCA[i+1, tIdx] + term2 *= 2 + + total_sobol[ParIdx, tIdx] = term1 #+ term2 + + # Devide over total output variance Eq. 18 + total_sobol[ParIdx, tIdx] /= var_Y_t + + sobol_cell_[output] = sobol_array + total_sobol_[output] = total_sobol + else: + sobol_cell_[output] = sobol_cell_array + total_sobol_[output] = total_sobol_array + + # Save for each bootsrtap iteration + sobol_cell_b[b_i] = sobol_cell_ + total_sobol_b[b_i] = total_sobol_ + + # Average total sobol indices + total_sobol_all = {} + for i in sorted(total_sobol_b): + for k, v in total_sobol_b[i].items(): + if k not in total_sobol_all: + total_sobol_all[k] = [None] * len(total_sobol_b) + total_sobol_all[k][i] = v + + self.total_sobol = {} + for output in self.ModelObj.Output.names: + self.total_sobol[output] = np.mean(total_sobol_all[output], axis=0) + + # ---------------- Plot ----------------------- + par_names = self.engine.ExpDesign.par_names + x_values_orig = self.engine.ExpDesign.x_values + + newpath = (f'Outputs_PostProcessing_{self.name}/') + if not os.path.exists(newpath): + os.makedirs(newpath) + + fig = plt.figure() + + for outIdx, output in enumerate(self.ModelObj.Output.names): + + # Extract total Sobol indices + total_sobol = self.total_sobol[output] + + # Compute quantiles + q_5 = np.quantile(total_sobol_all[output], q=0.05, axis=0) + q_97_5 = np.quantile(total_sobol_all[output], q=0.975, axis=0) + + # Extract a list of x values + if type(x_values_orig) is dict: + x = x_values_orig[output] + else: + x = x_values_orig + + if plot_type == 'bar': + ax = fig.add_axes([0, 0, 1, 1]) + dict1 = {xlabel: x} + dict2 = {param: sobolIndices for param, sobolIndices + in zip(par_names, total_sobol)} + + df = pd.DataFrame({**dict1, **dict2}) + df.plot(x=xlabel, y=par_names, kind="bar", ax=ax, rot=0, + colormap='Dark2', yerr=q_97_5-q_5) + ax.set_ylabel('Total Sobol indices, $S^T$') + + else: + for i, sobolIndices in enumerate(total_sobol): + plt.plot(x, sobolIndices, label=par_names[i], + marker='x', lw=2.5) + plt.fill_between(x, q_5[i], q_97_5[i], alpha=0.15) + + plt.ylabel('Total Sobol indices, $S^T$') + plt.xlabel(xlabel) + + plt.title(f'Sensitivity analysis of {output}') + if plot_type != 'bar': + plt.legend(loc='best', frameon=True) + + # Save indices + np.savetxt(f'./{newpath}totalsobol_' + + output.replace('/', '_') + '.csv', + total_sobol.T, delimiter=',', + header=','.join(par_names), comments='') + + # save the current figure + fig.savefig( + f'./{newpath}Sobol_indices_{output}.pdf', + bbox_inches='tight' + ) + + # Destroy the current plot + plt.clf() + + return self.total_sobol + + # ------------------------------------------------------------------------- + def check_reg_quality(self, n_samples=1000, samples=None): + """ + Checks the quality of the metamodel for single output models based on: + https://towardsdatascience.com/how-do-you-check-the-quality-of-your-regression-model-in-python-fa61759ff685 + + + Parameters + ---------- + n_samples : int, optional + Number of parameter sets to use for the check. The default is 1000. + samples : array of shape (n_samples, n_params), optional + Parameter sets to use for the check. The default is None. + + Returns + ------- + None. + + """ + MetaModel = self.MetaModel + + if samples is None: + self.n_samples = n_samples + samples = self._get_sample() + else: + self.n_samples = samples.shape[0] + + # Evaluate the original and the surrogate model + y_val = self._eval_model(samples, key_str='valid') + y_pce_val, _ = MetaModel.eval_metamodel(samples=samples) + + # Open a pdf for the plots + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Fit the data(train the model) + for key in y_pce_val.keys(): + + y_pce_val_ = y_pce_val[key] + y_val_ = y_val[key] + residuals = y_val_ - y_pce_val_ + + # ------ Residuals vs. predicting variables ------ + # Check the assumptions of linearity and independence + fig1 = plt.figure() + for i, par in enumerate(self.engine.ExpDesign.par_names): + plt.title(f"{key}: Residuals vs. {par}") + plt.scatter( + x=samples[:, i], y=residuals, color='blue', edgecolor='k') + plt.grid(True) + xmin, xmax = min(samples[:, i]), max(samples[:, i]) + plt.hlines(y=0, xmin=xmin*0.9, xmax=xmax*1.1, color='red', + lw=3, linestyle='--') + plt.xlabel(par) + plt.ylabel('Residuals') + plt.show() + + # save the current figure + fig1.savefig(f'./{newpath}/Residuals_vs_Par_{i+1}.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Fitted vs. residuals ------ + # Check the assumptions of linearity and independence + fig2 = plt.figure() + plt.title(f"{key}: Residuals vs. fitted values") + plt.scatter(x=y_pce_val_, y=residuals, color='blue', edgecolor='k') + plt.grid(True) + xmin, xmax = min(y_val_), max(y_val_) + plt.hlines(y=0, xmin=xmin*0.9, xmax=xmax*1.1, color='red', lw=3, + linestyle='--') + plt.xlabel(key) + plt.ylabel('Residuals') + plt.show() + + # save the current figure + fig2.savefig(f'./{newpath}/Fitted_vs_Residuals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Histogram of normalized residuals ------ + fig3 = plt.figure() + resid_pearson = residuals / (max(residuals)-min(residuals)) + plt.hist(resid_pearson, bins=20, edgecolor='k') + plt.ylabel('Count') + plt.xlabel('Normalized residuals') + plt.title(f"{key}: Histogram of normalized residuals") + + # Normality (Shapiro-Wilk) test of the residuals + ax = plt.gca() + _, p = stats.shapiro(residuals) + if p < 0.01: + annText = "The residuals seem to come from a Gaussian Process." + else: + annText = "The normality assumption may not hold." + at = AnchoredText(annText, prop=dict(size=30), frameon=True, + loc='upper left') + at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") + ax.add_artist(at) + + plt.show() + + # save the current figure + fig3.savefig(f'./{newpath}/Hist_NormResiduals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Q-Q plot of the normalized residuals ------ + plt.figure() + stats.probplot(residuals[:, 0], plot=plt) + plt.xticks() + plt.yticks() + plt.xlabel("Theoretical quantiles") + plt.ylabel("Sample quantiles") + plt.title(f"{key}: Q-Q plot of normalized residuals") + plt.grid(True) + plt.show() + + # save the current figure + plt.savefig(f'./{newpath}/QQPlot_NormResiduals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------------------------------------------------------------------------- + def eval_pce_model_3d(self): + + self.n_samples = 1000 + + PCEModel = self.MetaModel + Model = self.ModelObj + n_samples = self.n_samples + + # Create 3D-Grid + # TODO: Make it general + x = np.linspace(-5, 10, n_samples) + y = np.linspace(0, 15, n_samples) + + X, Y = np.meshgrid(x, y) + PCE_Z = np.zeros((self.n_samples, self.n_samples)) + Model_Z = np.zeros((self.n_samples, self.n_samples)) + + for idxMesh in range(self.n_samples): + sample_mesh = np.vstack((X[:, idxMesh], Y[:, idxMesh])).T + + univ_p_val = PCEModel.univ_basis_vals(sample_mesh) + + for Outkey, ValuesDict in PCEModel.coeffs_dict.items(): + + pce_out_mean = np.zeros((len(sample_mesh), len(ValuesDict))) + pce_out_std = np.zeros((len(sample_mesh), len(ValuesDict))) + model_outs = np.zeros((len(sample_mesh), len(ValuesDict))) + + for Inkey, InIdxValues in ValuesDict.items(): + idx = int(Inkey.split('_')[1]) - 1 + basis_deg_ind = PCEModel.basis_dict[Outkey][Inkey] + clf_poly = PCEModel.clf_poly[Outkey][Inkey] + + PSI_Val = PCEModel.create_psi(basis_deg_ind, univ_p_val) + + # Perdiction with error bar + y_mean, y_std = clf_poly.predict(PSI_Val, return_std=True) + + pce_out_mean[:, idx] = y_mean + pce_out_std[:, idx] = y_std + + # Model evaluation + model_out_dict, _ = Model.run_model_parallel(sample_mesh, + key_str='Valid3D') + model_outs[:, idx] = model_out_dict[Outkey].T + + PCE_Z[:, idxMesh] = y_mean + Model_Z[:, idxMesh] = model_outs[:, 0] + + # ---------------- 3D plot for PCEModel ----------------------- + fig_PCE = plt.figure() + ax = plt.axes(projection='3d') + ax.plot_surface(X, Y, PCE_Z, rstride=1, cstride=1, + cmap='viridis', edgecolor='none') + ax.set_title('PCEModel') + ax.set_xlabel('$x_1$') + ax.set_ylabel('$x_2$') + ax.set_zlabel('$f(x_1,x_2)$') + + plt.grid() + plt.show() + + # Saving the figure + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # save the figure to file + fig_PCE.savefig(f'./{newpath}/3DPlot_PCEModel.pdf', + bbox_inches='tight') + plt.close(fig_PCE) + + # ---------------- 3D plot for Model ----------------------- + fig_Model = plt.figure() + ax = plt.axes(projection='3d') + ax.plot_surface(X, Y, PCE_Z, rstride=1, cstride=1, + cmap='viridis', edgecolor='none') + ax.set_title('Model') + ax.set_xlabel('$x_1$') + ax.set_ylabel('$x_2$') + ax.set_zlabel('$f(x_1,x_2)$') + + plt.grid() + plt.show() + + # Save the figure + fig_Model.savefig(f'./{newpath}/3DPlot_Model.pdf', + bbox_inches='tight') + plt.close(fig_Model) + + return + + # ------------------------------------------------------------------------- + def compute_pce_moments(self): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moments (mean) of outpust. + pce_means: dict + The first moments (mean) of outpust. + + """ + + MetaModel = self.MetaModel + outputs = self.ModelObj.Output.names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(MetaModel.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = MetaModel.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = MetaModel.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = MetaModel.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if MetaModel.dim_red_method.lower() == 'pca': + PCA = MetaModel.pca[f'b_{b_i+1}'][output] + means[output] = PCA.inverse_transform(pce_mean) + stds[output] = np.sqrt(np.dot(pce_var, + PCA.components_**2)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + # Print a report table + print("\n>>>>> Moments of {} <<<<<".format(output)) + print("\nIndex | Mean | Std. deviation") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(pce_means[output], + pce_stds[output])))) + print('-'*40) + + return pce_means, pce_stds + + # ------------------------------------------------------------------------- + def _get_sample(self, n_samples=None): + """ + Generates random samples taken from the input parameter space. + + Returns + ------- + samples : array of shape (n_samples, n_params) + Generated samples. + + """ + if n_samples is None: + n_samples = self.n_samples + self.samples = self.ExpDesign.generate_samples( + n_samples, + sampling_method='random') + return self.samples + + # ------------------------------------------------------------------------- + def _eval_model(self, samples=None, key_str='Valid'): + """ + Evaluates Forward Model for the given number of self.samples or given + samples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate the model at. The default is None. + key_str : str, optional + Key string pass to the model. The default is 'Valid'. + + Returns + ------- + model_outs : dict + Dictionary of results. + + """ + Model = self.ModelObj + + if samples is None: + samples = self._get_sample() + self.samples = samples + else: + self.n_samples = len(samples) + + model_outs, _ = Model.run_model_parallel(samples, key_str=key_str) + + return model_outs + + # ------------------------------------------------------------------------- + def _plot_validation(self): + """ + Plots outputs for visual comparison of metamodel outputs with that of + the (full) original model. + + Returns + ------- + None. + + """ + PCEModel = self.MetaModel + + # get the samples + x_val = self.samples + y_pce_val = self.pce_out_mean + y_val = self.model_out_dict + + # Open a pdf for the plots + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + fig = plt.figure() + # Fit the data(train the model) + for key in y_pce_val.keys(): + + y_pce_val_ = y_pce_val[key] + y_val_ = y_val[key] + + regression_model = LinearRegression() + regression_model.fit(y_pce_val_, y_val_) + + # Predict + x_new = np.linspace(np.min(y_pce_val_), np.max(y_val_), 100) + y_predicted = regression_model.predict(x_new[:, np.newaxis]) + + plt.scatter(y_pce_val_, y_val_, color='gold', linewidth=2) + plt.plot(x_new, y_predicted, color='k') + + # Calculate the adjusted R_squared and RMSE + # the total number of explanatory variables in the model + # (not including the constant term) + length_list = [] + for key, value in PCEModel.coeffs_dict['b_1'][key].items(): + length_list.append(len(value)) + n_predictors = min(length_list) + n_samples = x_val.shape[0] + + R2 = r2_score(y_pce_val_, y_val_) + AdjR2 = 1 - (1 - R2) * (n_samples - 1) / \ + (n_samples - n_predictors - 1) + rmse = mean_squared_error(y_pce_val_, y_val_, squared=False) + + plt.annotate(f'RMSE = {rmse:.3f}\n Adjusted $R^2$ = {AdjR2:.3f}', + xy=(0.05, 0.85), xycoords='axes fraction') + + plt.ylabel("Original Model") + plt.xlabel("PCE Model") + plt.grid() + plt.show() + + # save the current figure + plot_name = key.replace(' ', '_') + fig.savefig(f'./{newpath}/Model_vs_PCEModel_{plot_name}.pdf', + bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + # ------------------------------------------------------------------------- + def _plot_validation_multi(self, x_values=[], x_axis="x [m]"): + """ + Plots outputs for visual comparison of metamodel outputs with that of + the (full) multioutput original model + + Parameters + ---------- + x_values : list or array, optional + List of x values. The default is []. + x_axis : str, optional + Label of the x axis. The default is "x [m]". + + Returns + ------- + None. + + """ + Model = self.ModelObj + + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # List of markers and colors + color = cycle((['b', 'g', 'r', 'y', 'k'])) + marker = cycle(('x', 'd', '+', 'o', '*')) + + fig = plt.figure() + # Plot the model vs PCE model + for keyIdx, key in enumerate(Model.Output.names): + + y_pce_val = self.pce_out_mean[key] + y_pce_val_std = self.pce_out_std[key] + y_val = self.model_out_dict[key] + try: + x = self.model_out_dict['x_values'][key] + except (TypeError, IndexError): + x = x_values + + for idx in range(y_val.shape[0]): + Color = next(color) + Marker = next(marker) + + plt.plot(x, y_val[idx], color=Color, marker=Marker, + label='$Y_{%s}^M$'%(idx+1)) + + plt.plot(x, y_pce_val[idx], color=Color, marker=Marker, + linestyle='--', + label='$Y_{%s}^{PCE}$'%(idx+1)) + plt.fill_between(x, y_pce_val[idx]-1.96*y_pce_val_std[idx], + y_pce_val[idx]+1.96*y_pce_val_std[idx], + color=Color, alpha=0.15) + + # Calculate the RMSE + rmse = mean_squared_error(y_pce_val, y_val, squared=False) + R2 = r2_score(y_pce_val[idx].reshape(-1, 1), + y_val[idx].reshape(-1, 1)) + + plt.annotate(f'RMSE = {rmse:.3f}\n $R^2$ = {R2:.3f}', + xy=(0.85, 0.1), xycoords='axes fraction') + + plt.ylabel(key) + plt.xlabel(x_axis) + plt.legend(loc='best') + plt.grid() + + # save the current figure + plot_name = key.replace(' ', '_') + fig.savefig(f'./{newpath}/Model_vs_PCEModel_{plot_name}.pdf', + bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + # Zip the subdirectories + Model.zip_subdirs(f'{Model.name}valid', f'{Model.name}valid_') diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__init__.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__init__.py new file mode 100644 index 000000000..4bd81739f --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .pylink import PyLinkForwardModel + +__all__ = [ + "PyLinkForwardModel" + ] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b7c1b3926506fb279b856f55ca6120df31b8888 GIT binary patch literal 247 zcmYk0F>V4e5Jhb-0ThKMNZf#88|DHCrHFtcL7*rNjb*UKTFkDI?G5aaa;0rk<q9+~ z3k_eIKl*yo{BgbBGb6S7LlbEKHQ`Z$!W&H(kZGnlvYf9uXIkv|TIl49rLBKXFy-~@ zvih*ae(L;DdHw0MLEju$q)FXAR7mWW>yDHPQOaNDpNQY=yn?)lu!Zknd;q_98D>fa zcz4?}H$@CEvvFQ-V2bXzR562%s!aG%Xtj4IxEFwwwy;sk(V?ol<J{>I&7^rSw8>tC HNV=CRubV&? literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ce3317406e07859bf08a42b738674e05d5c4339 GIT binary patch literal 281 zcmZ3^%ge<81T4a;sl`D0F^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%p@2%C%)D&3{G#&2q7>i!l+>IeW}uXxCi5+}g327A9GHKLJw84$Cnr9B zCBtWs4ZnPytztrpQ;UjYin8-FaxxMVi(_2!lS^|`^Gb?i+%ro&N|R#Ta`MXq5=$~- zk`gOZi^~#oGE<83D`Ft##>B^G=4F<|$LkeT{^GF7%}*)KNwq8D1ey+VT(KsQ_`uA_ g$oPScfl>VegBmgdim^(5U}oZGYhVY#B6gr^0M-CYtpET3 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bbb522855ad250ad55bca46123c0f5023076291 GIT binary patch literal 312 zcmYk0%}N6?6or$S`h(bw3*TWDDHL%dB0@zFtQ2HGN+6_7M#J1>hGbGZZhZw`!dGzX zTg=v#ui!@Sv>Pwn?{YYo!;!<`0l|6w_*8)Rs~7(#L2-#2juDC|3dGVmr9>r<be^d6 zo@9e>ie^T;qgi`vTzOsjXX(|nQW|_8aF?asZruWU8{O>*ApwMVCw>S04SwDxXFLzu z2kv!Qjk$_8uD4{?IPE2v7ulG~u|mrxdd+SoGj^3v^M{ksDPKebiY=`yHJ5b_+$?LZ z5zH36FiwKkAwm;Y<0sL7`RMpUwmPgZS@~+sw;j0<#+gQlQQda?=eAN2^hJtA!vJxZ GCcl4{ja-8O literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6ae7c14b35b60388e38fcbd3af64d04771a947c GIT binary patch literal 18654 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e430ff1341268f5ee1e872f5ce19d674ba50b8c2 GIT binary patch literal 35406 zcmd7532Yl#nkE>$Ns$ss-KQ10tizIg-={3umJi8J+m(kavt?SOEZP#O3{tkNqAJ~m z>?t}SOfjq7NL98I#ca5%m0eD>W{@?bo~@m6_jJ$JET*>^+Q5n+pdAB)1g3z-Lb+K5 z7`Z#x{r(rhU<5^_?dt8tghDTlcf|kx_rL%B@Bjbz_-Dn%MI4TEfBzSOf0*OA|3VMh z!=l`L{RlT7aemHknBXQ2*9-=_H%=I@8QIlz&BU(eYi4$}T(h#P?V62U?bqz=>bO?K zuFh*tTul?M$>M9pN?9e>N?4rxnj2U1glE!w&5Jn8``oosBX@@LTi@sWwm{j>OdR)f z{L9C+a=-Bk*J=MXJ$4#04!<wz8=de)BExvHP5Fdq&^Liw=gmNLWHcO#24<q8YIbBY z<DZ_t<_%Oy2N%UPd)!j*W8BYh|8w<ujtiBya0V`#MG~_34f-@cFwB_V;_ez^+%5Hs ze&cO+FSx%wXUq^Y-X_>Mq;zEA!8c6#-|(B~OffEIkW(i$@Z@s+47Wd5AB9?^H{NE? zFO}Ztx8NHlAlm8+0|iAqj{fn$=<Ns}9OHcx6MS?$z~AvrOb75L#D}M&{6sLo-v~tS z1_B{|G8m#)zL1}v^v&S5h!t_kC-^1<(SQ(Pk3H(a9x2Bm-X{pYdwf_xd66i4PahvZ zGxO0fKT1IGzMH;aC=%rbU+89lrBOb32*BhrT?pR|2>gxkG{6XtF_1Mm7+m<EHph3S zrV8g^AGsWeP75I&?Cd>Y3Hk#l>P9#`p@Mu>m=0vIrN@*{Ktzba6PXH(2FHQ{zfu>L zdv@1VVE1P54lt?YjEsk;C;Y%K@8fq4$VlquZxD`ASSTF*HBsv91<E+Vs!h0`&Q&ME z`@@uu9}5eUC<NsOm5+84B=^u}H^-y&g~;7t6nOTZzS?Qc7(-JT3u}{1NnbQ71o6$l zDM1Je8FR=VoXixxPE;VjF@Z8V%^4F~GGmpS1XqUWj8(=`glL>v^c$i7(A(dMfEL~s zZimMw#(loX+XLaz>B&GS8hQInFgiGW<Lw*1dw~dpRS3_#9hmV=PE7<NZ%<F&5Q6@j zfstrrI^>%SMyI1;0UbXt{nWjQVCeSS@}+m`UdDy0jR!*`j0}V_fKrM7ND{$)ZhfoC za>cM#;+Y>$L>^4ePsUAg)AMzsfxWFyHM}O4T$V~Mr|g%XKYyOK6}>-`*!hFG`*Ulh ze5&a?V(IHr>FX)i>(6Y(3F{BuyZ_!=Np-5`rdTpAm5itC<Ijpq@1IWFo$;{`T&uR4 z6<dvHtCMVX>zu(-nJi1*`IGupe%A`WOXT-R{2ul??X8Gg(@yXGp@<zo{-C^y`^ej2 z8pXYOlq+{%Kf%pMT!6b~@N;0*hHIvPnXytMSg9#s(X&!Lj{pld`z?M;5R8|u__N;R zZqk!Yc}5)ljg|ZD?;F7C%l$>T+Wk(jY=_^4u*hGG(CIHh=yHI!`YZe%q$&1$@utLI ziqP#ZL+J5az+EacrI+qqKogw~3wM2je<<t^O!)p+uflQqh*;@8KS>e%jbO+h5M)+z zbvzj1M|~5K2oD;%12*Kt$&Vr-e^>Ak;rH?^k@7@bD||P?dR<^9FghI#hQYYTSdRm5 z84n8n9vVOH@saRY6rT-jkAx@gfFH<2Blp+Q@Kk`9$w?wikbcmAIXu%V!=&~P9g6^y zW8WZB9EsjT_CtImD&+VCx-5IGuqX}m0p1@N^G#1gc~tg#yG+OJ*OiJ1(;-$JwWLCI zAWrHF@p6rQHzor7bR-zM2~<VK1K{JM;mJv26;wx=<*3C4LsQ@{V?lJdUiIab00vdC z(<z2N2G-bgXq2AXuk&}ugQMeUi3obJ9|-eBm8Kg73}7t)S^mCSo{!IFN3#W^QLwy7 z0L|cw1}5$im-O+M?nTGZRFP33I2Dy4L7&e@<1oEaP{_zdPC0dNgldq7bEQZY!^)!S z)A(~8T;e*g1vnx^9~g2JutAE90<O1b0dBvp)<SKw;cyhKN%f`yk`=AMG$q%9eUcE) z5-D-n64ml1r!l$_D-KQuCnkJZQqHF1S-gOuBXEa47vKqF^2o|?2DH&Is+NcEM8<s} zz3UyJk%-JhyZO)v%NFUp&PHlM9^Qa)e~>k(Pq-)31-_sbH8TQsOv64^0w^OIVIPZ7 zZ&gMu<vrD3p&bH!#3$U0pe3kywY)yRKS<Q$n?Nx)W$w>PV%5qajfh^~AHFwtU2bDW z$q@ErO4j$TD>^Edn^W!#AkbW!X1kWkI~aVd2WaSLgIGc!<+_PNEmNR>qW&;znOwIm zRCY9g0S&Y+)8~fr`*=0MtA9pje?)L9va@tWjB*N6));?1S4VVTVglEXycs-pod;N> z0e(C@0hX&GiX~P{(-0l_R4{}}%gjYCG;*D1l6kjWZV&`boQK*qgaI7ID%_XE0ktf- zopU`i04W2x6agq08l9L1i@)9*otn6g648Wm5Acmfr+qo;E7ygUK9<8@H>-{!OLX(s z<xW5a_Oe6@Rr#i8Uexp?q7o93G&m8Y?m}=!_)s9=e+lve9ij&U<$97mrH)Q45(4+V z@HB8387G<|7D_0Ths4b(SZyWZp%DDWfp32hJOh%_y^Wn|I2;OGM@umVJ{lH;Kx7Jx z9s>*`W3{x=X+({NqWs;kaGM$?S0+m%_k4!95!U@txh$HrquvDtb&MMFS$CGN(Bw@) z>BfqxAZ3}a_WLjUX&H+$(5$Xty3^Eqv)}W9G2M#<6)vXK4ip2SBd^(pH`GE&#%Q@? zlM$v9jfv4h;pMX6K>dO6a(x3b^BMIne~&z0Vm+7gj0FXn7=`c3y-h_D#bsG{Hy`M| z*~`y>34{goF7TfSv7TrUL#RA9VW<wsv@Q4`G!aW9kksNZFinGRF%e200|;ROA4Y#I zN=bfUd;vt5tqp4$$S^cis^u{xuxT9+LX~?oCCrZK42PQyoAPjYLt7e#PUMz{2S6GP zj!X&R(Lf}UH%WVAJb-G+BfAW^ELE{#UmYg^Ju!)i2?(KC!pQM;wGvrE+%QtnR8Zk6 zp^?$4X+WW!bzVi=s2q`}cx5EfQKAZg45thnHGl$<3Puhxb;Q{K(YJMX)Ke|XcgGi; zU}7VIrQkE*i)c8bnwC{V(`J)MH!TEcK8Im!Cfaku$9fi6B=H}}j;vMLm_(Wy%<0v# zvZP8<JsL<M>(TJU^dzw}NFJd8$d^49q&&vq)Z(;aG^=_qe=!94GLKO+p*{#v^=xPi zR2Uk~Qc$+WB>Q06tmoISQ15J8$<uGve|{%G85nZ+V?93$xLV=-3XF~jfw7lqG?nG5 zpbn7|t*757OknT{D0tyJ(7LQ8)K5mDXcwBS`2%-?47N^1d(q3E#XNvSTBVu!>)G}N zL(?>{T9(|h7@O%UYMO{V_s~$m^+?pOMziS;`<6W0P)lRo2;&$eM06sVxq!O`C&Bn= zZpkzbis%9%+SeoZF!XvNy{T{{D$n4UoFcOkCXz%0Qwkx2mcv9(x$Z(lNi-_6aJl1z zZ$w5&_67auMPT+wGB6|v1w~m&>03LIf>yPnFF-FJgfyx49`;bM@2KT5+SJWKN#=f~ zu9K~^+H+pI<{BD*0TNVrUxvnBhy=AXrRg^CPIcZfDfg;ZZPFKXC@2Tyj-&$eyLTwH zvT9icdz4BSh58e*H!c5Et54m5vGJFq{!vw7g&R{=XLU%Yv-%En>ZG*_Sp3E#i1C}Q zSpzmanUyCyd$Pz+q@Vt#VWS4A_aYNXNN1ekGFDj(8_rmm<dG?&QAd_dI~^JO2)i8_ z$rO!@px;j;ZY1Lx8F?483Cb`sBGdqqj0w_f#yv9P3qhD>>@9+*T8c80fGgDD_A~Bl zgq%=HuZwbE2vvCThxm`2L~vj8_pGuyZcUg{_G+A>y*gc48@I%xDSItW(O#RbYm65q z22%D$oFWTxBeb9xp%nqD$CRAILN%VQj#ePd9%LFIM1M_YjgMe5h;bv?I2Z)*q?$Kk z7CafVkuew;MzT%B#msmzt8rF5sYZvG4Nq1z&W<OW`sBb9X)W0iE5?&**oc+jiCLm3 zGR7sHaw>fobH$voq9+Eu;u1Ms*>q9Dx^lqmqQ1XXl6|W;pCGS08xwQm$)i4b@C41H ze8jwXqE=)_tQ1eAEta3k@RU`$a<OtesaW@OAWGwKr-=~_BM(LxP<1*~1t2u%AgoNW zPHzF@m8`1DI8<FprYJW%&y>jbS%pBxo}Hj(?AeKArdTKIW~{QbsSt`xjv3QLASBbR zBQzrOxJbr9ESAX!8Mk^X^X!aM;d9h)GA=N5=v(CukSWzZDal=Oa#?=rtjL%nfr&Ap z9jFsJDCnYK8wH&dbW_knK`#Z{5oEkFSejWRzRUWw+;20*%9Gr+g&mZ0Ck1;c*hj&B z1Q~mF_{o%H@A4`|%sWEON8D_~A$Mf(h+rrf9T}OeE5K~Bkv~Bpk-tU&OF{`(+Y&d= zm!!+9adD&@y5eRDow;fY9$o30W)@l7ii<nFrJEw_($zd3i?f$(mdbj(b%HH?6#j8I zUB;(Nx1_5&)@@wX)~`5oRnc!Kpd`O7;%XZfu0Hy%)X*!|Y?o@b<84XyTaCT+k@|Gq zR=QTF>+x;LUXyO#LD$A~eLH(j*=ukz_L8wcy&k+Vs&WNXjko~gC?BJj6Gutn#l}N# zTJRfgvoaC};apVZD%9(5sbxo19>Q@y!`q*$F~TveIaHfR-?N3TsLD?`?v`3!QsqZl zI5#f`y;=Qs=poXn9PIZmM^%o1FQ{KD%)6p0zd%}*FX=I(EnQ#hIb&4A5pNY|VUHR8 zrYB~7S{=lPH^s0DuNFJ{k_7PRT$||1bw?YrFko1==yCr8GI^_5!@bI5Z>jv122uG) zs$4evhOT<dBsG}MrP8OlrDFJHQlmCGo~?oQ%F9x*byF%<x&JFrv6@GZ$ycW0P0B%S z)fh&_WanhZKM579rR(YG6{$D}aXuBRF@^iM{;Q0N)f_rZyqJnL`TjelViG0Ufqte! z`_fcwlc`wv2jnJ+ksbH9=5Y<Rv%VC*Ap_o0b6nvzElcIeFXZuRY5&OHu}L|g2{k5k zU5kl-lHQ@>Sx=|0*gJ9%+x#TEtIvAu%l=WmVAgGiWSYwXpFgsFN+83ktp3o*ZQHf8 zYjUR|&5t@?WHJD(vCvM)N(?GbjlHCr9o1K=Pft!~G77z4p3aO)p^0VI@U4M|894wj zRHVIpzic-Sz%T_ZZ99Xey<7bl71PcX1?{B3ZkI*RcG(<Hky@7>dRCxQ3!pjTX)>Lv zZzxqCPk0!k_o@MuoDG6EWK6JV#pqAzg?@CS;cpDx%p)x@0jn*XoM!*v(gdVxXpn^P z9dZyNZIZU44B5<WfuvAH{{!8bHWBQsS+5(aVO9~(k4EnFF!d?35ka{%l+(7JhM=Cy zma#Ad!4Ze4D>`d47Um&@$pt(CNZBwN5DuUM88d;AF_RZl#yI8AI8^LlP9lUSnevK> z*coFuk}=b#Gv-_2U?^jSyWQwrf5tAL<wgKp#&K$9G{C$Bgk30Ho^jYPcMeTYOkg%W zJ(;lrFj$f?F&_b1goBifWcQ4dy^tk!Cddn<CcvcXFvXgQo&XU|;|YWa$&}OzBr{|@ z3<3?BXIlyg?fHrR5?Lb^C<wxPE9dh3=+Fm;9vqoJvao-}*(^Gn*W5J=ty1l_&##K^ zU6Om(I_E6z`9*YjKsquc?jM%+53@IGty>>oSZzJD(t2olk97Eg*g7P&4kgTzrzz!W zf-}#<Eh+D|wfZfO&iwSk#}_^?eNyvT-IKZ{{}&;#{*+XID&e3a&M!HhUP-l{6<g0r zt!J~@*SvKL15$m@=fabi=shBNkF0an;+}MCht#?^o9N5R#&yor)cqA_s_OX-1$gxK ztYdPpMXKpq-1FqHwC#vgb9A-l)Jn}MvF40ab7r;X{7TJvv1Ul3^Xh8Nn=3VMiZ$1y znrrca`E%*ADyghB<!XIa?ETTT53W6Ud;aZ(H&%*U#o|^4F*|>;M|2;M+y~Y<S8>l; zNoit_RMsVyY?Dg1t()-b%dYMx-K$+ER=Q3+EtmS<6uaJ%y51tF+f$x)U`Fz`rMx=} zphntvPOLvK)t?7$P{_8W;IDS4x-N=c7p1O?*#Z>Y?Eb~&FWwftCnfJm88=<MQdeI# z(dM|}TcyT*OVKaBC+#1U8qcmazP8f%n%H<nYP_=A_{K`(8)D;I5}nsq8~rPdez9>( zY8;CXNUnN@oUW9sON*R0SBl$G#cgSKndELvx!YCpx%}j9(S1mAA6hqYo{nc#by8JF z%G04XZB+E`k-YHzvKDv#kLAmL>DWc_;3etcCHCfp<Ry8VQr@0|NIWgppONa%d>es1 zYwciUq_+2Z6<4wq^<eYCQB_%lzCx2K>ULkBmQ_pKEj-9a&WCo+p!Io;Y9?Z_JkMD? zWBQPr^vxM>a^&TzDV3(4>=@wQIW%XEnF@QdM%Aenra9^tlj<ZcTMAuKeoi5kH>uJK z9tLjyu!A!)rCDy`7c=ESZ3)%2a8Xql=D1c)C^5+S^89$`EN^ik^IcBy7$$ExgRgSK zpv}e%8aHH3N7gXTI6s-evOYUOIN^{>PHq^J?Sss8mvtLrwh<_6g}}Sh@C1O<*Erm* zsB~uVpa|yRO0RMSZ7}sRk6*BO*)p#g246JTUX(4xhnUM(?gL=mN{muT72e!9-szG@ z5fXYbHVig2Dw4`JI5`y-pqgP?wv3e=|3ZG@5|Rn8QE-_8QYta!Q^s)>4tUI2wbLq( zCLTqV#FTDKFXz;}k&89ch?=p=?;|9}0%jcYh~tz86IQv|Et?KDEdIYCZ-fRLj5F0- zJ^$#iRM!K|@0XPgpWI4y9u&76lC~U59l0P@4oQ_map$v&s(2C9NDt3T<y~+Ib@UnJ zFg}oWRj#@kR$L9A+<0{JrxPDffVm%CZWXs2m$n=iT_+^hi4;56jV4D=x`I!9H(CC; zX7QX@v0tj#A3q&G{d~<`O~ql5$Odw{TCt*As_3RP@zd)jM8f6unY$uh9HCM6ul9IP zTDiZrR-D{o`s)S*LY<Gj${qe(<_^YOKlU4_3FTwX<cDXfZn}`yO9t}P0_gV!^#9N1 zELzSIv%pJU$3OORbJmzONgQg!p;scz+2HqzKYe}!7jm|6JGqGYu2Jrx2JS7+fIpow z${aK5^8vPow*kqVea;cH73NSed(7dt{BhnF=WO#^^6F&Om#x%EGl|MoEoRH-SFcv9 z`9JrY!GUbP_q818H2iJJIt!KoISUePNS20=yt(rjq;tkOLV>$bj=~90HZIFNN%kEB zPa@-VuA>vDL3-IL%#%dPijX~6(D!|lBauK9UIuEGmz!VY!5}*vsbx?{)p{E-Xl34& z6YhO}-xL{xnTaSj(NTfI^hE|!^`wL&C5w%8>b|5x3^!IdtEzD?;*I2$ph+%(h&bJd zOC}dmczw+y_z0faG437b96Y^a2ESnz@BSD|bUrbCXq<PUB~7!&BX0`S55F-S6Pj`T z%$PCu?#LK|5h_~YUEdTPA=?!h#*fV&D!{s?r!YwgC@n14xA(|I7;~Y>G2CSHc7kjo zttj_Cm)g=NpNsD<d@tFT^nKdD@ICrdBV_HeK^UGj@95nV$QbT++A<dApPI2S&-{!T zUe=+EnHX!vG#i}C*f4h`hs2D9yo3XtMKbd)(Kmg@p*C2?G8`Ve<ja(iL&Hck49fBe zqvIn4a>h>MC*$>Ix|5%2HkK*TCuhb(-()0G#BfHWM2F1x%L*W8cI(R_v5F8zb99UY z&78OPp*v}iJk4=SnxXF(r<U9P#f2{}0B7QsJ_+yab<e7|VvgZxV?liIOK(MDJZTcW zt&+DD?7O&q(F|kZPY-^4@F#~K9ZuN6wTs(X1Pi{RB)_2`_pZ<#_<W()zqNDQdQ-i9 zPY;S+LsHier5UE72%+fNnkY$H({(MYb=y|zwk-}X-@y<@qgdULR5z5cC+xqqa;24e zfZG7Dr~IR$9~Uhg5IwDur#0niC8$xwY(P-A5!9M@x!ByD0(E|>=j#<&j73_|g#SZD zU%ln8>dk$;<F8r_2>-gRvfpO;_cn9C)A8?13<z}tnQB2DM^pXKviWi`zcHTyYni!b zIauBR_kl$_pu{a>2EX}zd(4<W@aanz455Bq`KmqEZ;2WHnENCT8d}Wdw<-(K+M=p8 z0h;^`1BWiw9y5WhI6guCSqwaSC?FL7PzQx7Zu^V!Q^LYqPz28#jLk6`hMd0Fz@u`k zQ(5PrEMg#+H!v)=YC&Ejb>kizN8siIN4}hgtQ^Ti+Z;!S%M4pX#ul>CfFuib%6KsD zgFpQZTETWR5DL&D1V4mkIN$~%Y?Ty$D+~wGV9rg`Pd+|0=wYw}qY>bREPKXlL}?~( z!`}$Qi~O;UNGF_V@Nof7y@8xIi<LnuQ{awCpk-^x{311jgF43K;3%YZE9ehT?CUDZ z*025m)=;mkzhe$tSxFd7Qs>R9wha|GOlmU4%UXlY>{zO%ebEq@n`mUs(gjCdsCH=S zg8Zet(f3NeTdG!=xcY072fs1&>c&-iw;TU#T>T@%dB}J$Y;y0|=L|8!1LGa;b?zer zNZmoE{m%@;Y%ql?Y65vO=D<W?GGn1ZB%-LH?z6$+8^;l%pqVM**zC>%Ljt@^vkMk9 z<7qa_Wf~pY@qy?6mHV$Wrj{PZnY^0Vv#>XDRDRNiY($;4^ltC%-OeP3S!dA@AoAS| z@H-F9mO4PfL{LoMMorZ|d!U`x6#1|uFw`>}5W;dCBXZWgrr`F;+<T$C#Hyi5IJk|% z_nR-8HTL$xZ^lf{!WgwD0)Z(u-OAW#XoWYpK<p)Bjobsp12<CwTwP&H9;c|Ah{{g9 zYzlb`<jj+?U6LK^GNl{IK!_tnZrXJsJMGHhu<*1i7k`it`Xx$vj`6nJ>9}B6b9v^^ zCEk57G(Qv{S}U)7cy1x`;l+m+<EPf#rCQvkdXC{yEIlqEbRU=8$JaS~@dZQLQ-Lw9 zuHjK<s&((;83Z`R+I>>(zJx7ZR=eQ)@sY%lwep&UUa`DWD(_5{cj5^{R$ZTAsY<?T z!*u_-uS|xz^9GE06&DN`^bjHeg&4&y7=ByLIh^zMMEQe~`I30ax|Q3~yxP#S($FI| zY?m6g!(r%|yD4RFlGQaN=4B7!%tYv46Tc?A{o8n&GtQaj%-ZG8P>29g@)0#>@A9oR z5wa4i>28u&k@}QZ8hw);FDOk-$4bjRadYrX%6$vdtGjbnzaeJ5!wGem;AvpYehFh* zo^r`=)J!?8G0P^?vdv1%8?pW7Txl^g3EmiUF}lhk_$NlXZVFj`S=L-xlrMkOoS#AM z)d}BbUz@W<Rc|LKz0`3wsVcW}xB+Z=BYvbjs#@!jn*?2U<fk)`x=d|nv_#dMHLBVo zkyBN?#jMB+>dUF~z&@*yTa`P0zjl+Hnlu~B(7~zJcq5$A#%vv!icf_(X3;~1IvmVS z)<IKtMpO3Rfu`&_$W)I9n&|7l2s|8uBvjD<0UmgH$^-)z&;o0uZ(&DL^>@g=p(|3T z{Y6KcaGK0fmmZF}qFB*Ol%}Chs8}>l`K5(+)7A+8RIox(YLb;OQSum54t!0ue(U>9 zq*~V=sybFLYij)hqNE_qmRm@6RV}#LRCJ9M0R|Ptw`#L-dDwBroJ_THRV&lV%O8}5 zv-~I~x+L^Prf;arsZ{@aw&Ds)C}`mqNt#%>7nB7=Rk8{NXlYAs{TakLrnSixChKLG zc7r5=Ni4sCxY{j?t+L3emPV3-EITVB^ec;=Gc%CfqSIKauNF#zB33ifJE)Fm5g&QD zv*|i*2tnGCZd&e|T~(y4hatFcV{-!d*CM?JkQWJ)iXd7@ZKFtz+jcTB@<yHr*#|7M zEhv;_oXX@vDUSfAX-1xxes(znl<>M56Do5nvZyljCRa^Txks=(2~Ce>d6*z5S~W_g zEWp}O9)nJUiEj+sfBpa9m^IT9MkfAc3?oeU(^)5+169iIl}&WljQ~>H)I<<-6?)M@ zfvPUgSOYVV;vyOQr0;eB<P(7)H;$$96OiDrVsw}6r1>MtG)+ZWu}TKwzwrC?hWT^e zp}PwdFs=I)y8Gu8{2>LqC?KC*DD;^z*Elniv5$^S!HA5{T1hSrg)=s^`3Txvm_gEv z4LdfF+iS)Kbq_N-J5*m-xkgUX17+pOG31HRXhbxZJ!F~DL*>K0fi@Lj6T`yB;k-mN zUx@r?bYBRMTe-G&(cTodC$=uMLjd&Dl3lpx^Qh?FBe`kQ2FHPPOS{yvFV(!C41|r$ z_V;M}=P;1&klZ^c#g24i%cJ*FTeicxdhuCJUA%-@0-@hGJBA?hQ5Zjyc9$k@#=jr` ze!8~lr#&C{ESkjHZmG6=@v>CA12U$ocGcCi;%Z8^|5?wU^ekD$=KWIh{$+#Id}#R% zv3UT#oyoDq*FGIj_9lBFTDI&=?>_XekN(S}Pb<aUgVOH7UwNh7=PBX>$(+SQBy%DJ zgt^epl~q0LT(~Kgwk?({o?hDd*&wbZV(GrPZO!eSzx$)_fAD=oySGYi=%);hrZrc| z{P_i&=;9?8pK|e#Q>*KxDpbzs*v5kRnJ-<X^A{GXlI^0aOLCF*lnkg&_x#b6vvrL{ zmOpA(L?JsQ*N&8H2QbZK-zw2w1GiQ9sIIkjES5{1N0vik+mO@-g%pe&ED&8y@w16p zLSHaN=2v*Pw*B<t#}^m-#rhpm{f?zlseTU(p#b!3BABcdUEPwaJH<{w>nL8e^DA~f zxn&6+`G+L?p_Kj5y4B_wG^AlfukBu~-Lq1=XX)w}BTrwG_MS=a?SI-Q?LAG>`yk;E zVf_5F+P2l&o|W33MgNoVvQO$gk?uXR{F>BzoYM8NbbUw{KmUB)Y<#t{S+3{LiTuhF z0}qEpceCVfChT{R?f2|Y&ObU2(i$SHmBepj83CM+F+G5pebw8v;%!Q9TZ}&Wp0xdx z=shiYPsgpYX@>-~|EaRCY_N;_RafuXT9d4XRwYnGlXOY)#@EY`6n|*^VdY1<4V3Z? zyK~kcH%I<q=tA<5L_gYi=*Q-)$FP7^0y*hs&d&Uv)RJDgRHNei)~?mLY5i<bqFPtI zOreWG4RW&W9M(MK49)k;qZ;WhXI|FVZ_W`SoT&OT7>ls|iVR)E6f-9bktew~!VuD` zwSFo5Woznz$=V(>j2VI?ovE_@W5Yi;%oQb!p`UEJ^1|S^sG<$`z!)=)<;`7K{(I3} zBFrjt623OK9+LxH!thSn9Hb(@MQM-k{m%94p!#V&lXE_sFpFqva5HaCSQsOrE&mvN z#ELMZD4%o1T&k|s1sTzmLlI`TcqV<ve8v3x|1`CZIkn%@<Gx_6i@&Yb+R_SAL2;}Y zweHl_x=CN_q&g$g_Is=c(qKjpC+10A3B!B^!)TkX?1oKRTZd<TX)4aQCJZ4SSXX<f z+}DK4Xj=}le2w@f^CXA<8!*liuln73>ET#OQuR&GLBerSS|+0$F?*rb1C^Wnrav%7 z>$B-F6IW+EV;apz-mJtOI;)%Y7~)3Q9_;Vibv@duuVubfB4z?bTW6tD(y!2(^K4cl z;7DE95cA~26tf6jeh1kcJ~7UDqdRkTijs;}IdXF@tl+Z7yibbsU)RGtR}^w<ONzPk z;|YWL4g}xg0I)X;2b+7V>(6efEub$Sz2pC4T87dODx)OwDo3m+N{m1`^q3IpbX2bD zGh#&#Ds#PC|DCzAP+wm8JF=zcYw(2b!sW*+K?6?MpTNoVBbJW7_-wgPTza_Y%5>#6 zWz*^2HWz%`l6@O1)7MM?BvZTJqN8l|x}U2(Z?0VTwN|xUL#*6yc~Y#WmAMLCYLyS@ z-sZ|ED^!La!kFzrCFAh_w@w#Yu1|%rk7;d$%h91MgwQ0G=u^SnL>rq&xp}c3tnVz> zP=`)R$xHjH-+5WO#dxRH6UA(PE8!y46}_mbB{qZGNMZV#3tp6@8NUmaim{qzuNw~F z!G=|trU%BKfiwLa|MCG1l`U2=W`s7T)Yl5tu{yQBOcq8qAJopxndNVCitHp&+RL#+ zSq0sxSV{7x@@i?&A7G9j#a43igr0N;v~`GP&i;}XJY`y3&<wV57q1)unDq9CvEALM zV!~mQYrX?heyn4p&6EPs&YY1C>jLfo10%y>d<fI<Ze@2j&2CCGi@t<p!7%nF!5muI zt_1oc7>mfoo#6s*h1lx@+c09icqDi;M3}?kPi#2^GpY`{tI%&~*Oc#2c1NM_C{usH z0tLV(u=LRv*nV)>BvVliF@+g(b(d=mFe4i`Flfj2c`7JqTzNm3O+GV3JI5#+$B_Do zSx&WZYc_Tv(6L$Ijc_FJt!2K>(gdRg_Fz&<Q^9+Yjtf+kHG`ra<h-wDC1`-8+_D0; zO~{P0AqPl-w)%mAZi+1`Ao}2g{!XS}M5&6MTG{V~%A(^G?e0U$I7RtIhVGnK6r+Gb zd(6RJ+o{1h)70b<whrv?Fqb3JbH0dz$ujTL^jK_h3dJav80gB&TD75F9VIpC7}g)$ zldbtW^&?R$cB={BA!1ca$k?-cjlxSv(bo<$<(jN%vu9O*q*e3X4e4yl;4vI2?Y}17 z@E;izuPxgg?8-6bvjuN0`xTCvl(lwcVG`*xMY)ctvn>lD#Lgbv#H!5L7;{ZyJg0!O zRs}|e2(9LP4$E@mpnNWQlSPX=KXs`uWSep&7z1M&iqcHslAXqkC5mkjCa`7%9kFnw zd3-{xbdhXM&y7#0I`rZjs-7{^W)vCI9c-~hBP7qu2K9ezrQ5ZYZabG^=h8sZzqtEx zP<}$lDvd=v7C$Xa`pl3q`=Af~#!xg{-c{h3-C0DOY>X)N?go8!gwMH?D1>#WNQWvK znn<wy`UC>i^PmQP^Qt%lA=3~A?Ab#va4EhCwd9*1{4=EKG|C#^^SBpoBZyF5#bZr) zfcx14uSz&suY|*dLQ)_rP6?hPDbJBb?;q7J^nHSL3*?7}7kQ_Q(N2M?DQ^OB7I&GF z>7kSI4!(?D1=^QFxK2SA1tj@nBLY49%{Z_J6|}t5p{Trn0EwuAK*75dkZMYBP~fA0 zq+fwBoH1Xb6-{RB_cJ9>mt=ZmYFMVj7MfU^=)3;Oj3WTM1M~aIEn3PUG-LC@$bx+} zGq$mburIoAPsTbO3S!j5W(>kjc+(4Ti3mnQJ}ijBhP5zkWQu%IS_Bpy+2v<y@Qle9 zx|b=1avS>o5sf9Fvx+Iig`X1GpHuKD!DS@1w=%9|ir_SoRh2t6+&^PKt*|B;bHz7> z@bnb6d}6i*nVXovxicob${40HcESbLS78%p+LKfG3;Gn+i3uaYjO`-xRF7nA!@l8> zpnoRg((-KKUm|UU48J^oo!@vU-WjDBerZ3Iz=X<+X4_th^8N*AKf+tVp1_}ed&0m~ z)+|(i_|C(3;0KS*Qk?5{tk0T1w(4wLaW;z1Cdt{9ytd-po^oza(|Ve&_~5gKcBnsx zq08MY<(E}kKABx?ebOy9?w1<(FPHzaUaUGTRh^CxVyP5z9Zos7tW~s16}@7`4yj@X z`N2P{sCoEZxWl8^$_4KS$K%J7%@2;Ju{5mj15(pNQ+{l<tbL`dT`cRA$~qUXt(5Ig zmF-Wrb|(iH-%Pa*;>4%6$ajgM4~MYiX0`R;O6$RNO;fVzQC;%ZQhTcU&{rm7TkUT+ z1e6HAm$i)xGmpN%=#v_Eh&4N<nw{%hxpx3+dkPbM>8k35z8~L7+<^z^qhqUe+gIwg zi*-Atx}8hcR_czY>W-(o_bd)#b<~^7GruzY@_WmZ;@%6=-V3Sj5jrnjl`j3Be7`WX zF!Zc@$7*-qN_StnsdKUEaoysr<@OYR5>WLt1FD|pg&`oJ6+jqk&cR+l;X;49u{n8b zrEy29aYuSz|I>bH-(YI**<|tJsL1bnzHVV@?X>8jFoexr$&Sx=Jvp%S=CbdL?=B6A z+fGW`PNtf_gY&8XZ$k3jLjOYlv*xX<&HGoH_iuo&h2U#xUg#(I;OT0t8DQ`Y<iW@H zERIV2u2ufv3V(39WqI_M9U|W^@%<^j|M^z{71;o4Cra?1r4kS(`qNdl3%6FVVymiS zt-JTh;L<x!cf$Z6b`MJ3gA2vUQL(y<a#I#NS5hh!V=-Q-V|Q}bS9DqP)-SvvdfTwn zZPnYg;_X`8Cwg~DUaThc7Vlp20cI@pC`>|){7>(EeCJPZE{><Rp2fM``paJVF1@vP z@m>1+Me`S3i*wS}qcAY=$6<%yk0%BbgD?WrgL=~0ksc%bF9OTw#C>O^eP{3>He$)! zV481VxVKm<Htq)e^?QNE`n`z(K*TrEhm(G3>*3|AV&h4v@nmA~Sy}BmXYuY%*BxCt zld3z4GcmB%+VOe$lbWRiPY<OJ9DyTm*D;utx{d)7cGpHQwH;3kCCD(**11^y>G0#> z#L#*RYR^!>g0Bb}zo8)auFxHG`Q4c6w;fzvYjWW6c`S;Q-LbGF(NW5R2j}9a61%@d zhwb^iTy*zJ?p{=*c>h{${iCkrJ4?Hzw*6x50jc&t!j`aoiS?F4Fxz=|NM4xjj7mCH zSisHl5CXC7oYZ!1ZClS1tm-q=?MJ2S_LCWCKgy`Aei-~y<74ONCqXW6h}}n}?xP}q zOyZ9%ze|5lo0g*zKOk0~k}6Nd&#b|r>|pZE#k<R|q0@?W$ECXC@e6B>O^@c*Jf#mE z3+>7MOWu@cx9Hg|d3K{m@}+1izBGP*!6drsQ?7dK1LJbX@3PgaJ6D|bDQEqf%bRF@ zaDE=fCc53Kc)hv2snRp)(%OanQfUi_M(b()Wx*_HH&<n1@=vdd&MwIblb*@ZZ%A+5 zy>w36dK@4WiLREEt7Wa&BZ~oxlemhWBND>mBT_L|tQwRYebUx_OS96}lS(#_8X4Xi zSFjn4t2}W#xqtD@(lu1jQGyCOO3(lZ?3|}=;X=yYk+OG0NVNW+t^Ex{+f9GB-8{70 z_ILXX2z5KwsGe_?kS6uEs+_hKT1i#Jg7+BiHTE5&cH!bJk{{SXivhL!ecV#@3`vY# z8;^X;7{006fAn9}YeMEsu%Ma!M&=1eA`UxpmL=#H*Ra@0W8Lwa6uZhV;g^P`O@CmF z>GWke4XjSXV!6%gCVZ&V0B1|EZmw|y1b1NLv+DNZ%JVWK?>1P<$W~UM4tET~K;f9A z>gT0YoLypeJ&s7TgCAO9Z74LNBzHD-4o{m{A@VfbC@EWGOUyQA%FS1>3!0tj_3nlm zb7{0#K?+&h<^J|~_)=MBi-8Zz{Qq9C-B1_k)y<0TtXD^W-fYca3soTX8?{hqT34g} z$BsRq|J?8BWJ_oM_BP)?gUqE)d9$)4lsed%7)yO7$Wiz^iomYS0GTff7VAVXF@$q) z5H2i=iwtxL^3LaKf%4Y#aE4}@Al0!6o5Kp>n{a%R6*6k_ms5_hxjXG9zYD9jrh1uN z4i6%xf#_&awPP)EI{hLonzZHS{_-va3@my3Yf@#%+CWkXOe-5-sPMf=Ewe!pL!X20 zO~w^;f^yl48&Y27F}0B0Q)EBxV*0U$i9ip7(XS{T{v0&WSt=~zl5q@Py?SYg<m`-j z96OcfW<i+cU^`ZttyrUBw(QBtJ}e_7H^0eb*Spe`SDs0+ITcwQ*i0&8y*NFEUsxe$ zA5xECl`UJP)#;FDEcXcx3oBco?uuR4upE%>C1Ju&;lkfjK}@4T{yQU>heT+WrcNE0 zYmTstSF=q8W(fM3;whSh{#%eM<_4{tw+4%*l6xK>Tnvhy1Cr-J+yY@4ZYkr5>BRIW zmmghQZRlNT=v}-cHtdrc_AQ&G1A}7KS*hx*SaMD(ITtsP&{Y|?r%T*%6G`xgvDE>@ z4MznF;{DIq8vf+*75A=`dsn)wGVw0`EtDmuA0Cp*T9SQI+15qFN?B*BtaGiQIk`Le zF8wW*C8r-B5*vE49UB(!R~%%)f+5}9_NSwZO`ncE9{aRw!IrLT#x!J`)O9#jM`s%1 zF*ZBsS*_o*QojchL;X>y{%ETHXu6S4_I-S3;ZB-wee9I@ovZwT75>0-naCfN_@gQQ zXu5m*l7aoTEcupfPcAIjlT~7MXR5k$y_f*-aPXNiu)mf?%j0v2!G$XyLK?%U+SH1r zdh|D%JoUIJVP7cwusH2<Cw4v<jQ7X;k;3JXoOKKDtvGvA&fauuTXJ`NFmVlDK5+5* zvZW18@Y-TzX(#)8ZE5$DnJ3?e*UR=3PrYJGztqyNq^1$PI__p_fl=*1Ny7qI6!-NW z+`&cNtU7_X$nE16qT~Y$l1!hN=By#7-(2XuR$G!A){|8Bh9j28{^3eZq^TUaAsx;b zdCtQa%xsYlwTq>&HJjE&79{#}{L6>dL3^4L-i+A`FNexEKF>L{+sJ7LiyWKR4}}<v zJD9n#2rd?mB)P$DIIyXv4pyy^|A}2MjKCD%8EOE$1xxZ<^(Af0{p#?;JtVHyz!s_5 z6jzRzbEDJzoGVm~92j0V9xyEz%z**9ND&^|HFVb$b8S*<XUt3{YHXpZakki4_s~83 zx}0X)yqs7PvlA?!WEU$*>!_`xo4Mlrlt=X?s;(7qr_ez&mcInBBvg&PDVlRw!QK>3 zh&#Gmb0xZ6DK@KrvAh%^R<g0q8eDd0aM`>mE=yhxmv9Fu#_vhVSaZu*o6~LQrp0c| zofF*j{X>IMrIi0JFzQjTPynN-`3E{GD$TYb44o!_(G#y;w1e}7EmE;*uPN2zBUHX= zZ^=tJ=hd|Bu%>MXW8TgC3H8vJVI!SH+q1Pme4c9=dL!f3_}#+IN(R-il06$s4t)ta zDU<Q}J5fj}`kaz~Q`#tvc?$Hf(hWV#f*$6{>s6c8>05f$OJOUBdYAtr>#gMf|Fzzr zeb$x*Xdkp$&@qZM|36m=2tONI0i%AU&j;qIis?BU-X+>vBKNbCBzP8DFPk$;UVZD* zDYYC*K5*(v|K+onuAaR(oU<Nl6!4gayj&hdrT)_CbH?zOD?ev4eBme53chGQlfN|u zEr!Vyotl{%U{?MSEIb|ekL}GkUZ)?&xPsqZ%@}+FO;TnZS?lO_7}d<Q!@{ij)WBQv zB2}15XjkRgqU~(=4OsF=G7in{Fxy&$Qj~0``&?A9?os%H05Y8#cyqQGL9Vn}FFoqg z4tG}MEqM@rLb=W3d#COR0d~vgL1aM7xa5U7Bg~v4{5!nTOq)uSNU9YaDl#VQN~D>6 zS?|CFWb}5%em-!IZ8#+SE#)UW7}iouz)hgDOk?r+PZasTQSd1RWB|(839W2{iXyrj zVQVvlIf`=K6sAV9$fb?+gtPt`W}3;E5%m@}E1K{F)51ScX&n@-Qa*}&GgFR8jf2P~ z<{!e;X+-RKhde#|6>=9e;B2&Hy+>2DGN{9_Tw)jJDofn>;As44x@r%!vS(9Od*m}d z2s=&HZkoKMs&>m~d~mIz>fsw7{oap%FF7by^hgyw@uD?%+5EkQ>f~<G-7dMYO*Lk0 z9;lz~j$s4h66cdeQu#K~-7UGhe_>9!_u$0(iq*y)uthA@iH%34#-j<>T1)rh)hFMT zdX9-L$E6mm;x&0u3W5*MCr-n9QO>WHZ(k|jp02Kgd;Be_8Fm4w`4~28tJv`sXRIK5 zOa*eNfr$zz;^0&7X<6~KB+o5<_h~KJR6H%BXGro4r97nQu5U|Tef(XiZJ$`TU#i=` z&ec24!Ei(2gY)szuqu=_0FL5rSg%&AI$&N{tXwjERx4KRk*fA2%n36VhkP{i<C&y2 z8TqtGtlB13ZNp1wv0wY(z4&`jl-~H0qsgP#OG5@kvmSZ*{I5(BcH+=L1fbT<7H{`j zL*t`2lm67Ub4x7<a6YY)uhQ1@V#5Wg;X>kcx*9)wdL-G80O!(v`I@ReD(k7o7H<Pb zy~k2*P*tCh>P{pE5(CfIs$lgnc)N1}b{$Vfq`GYs4Wohyk+hvu7U1OhC7al~f7#FA z?3X<KDG%n|o7eB)k}cJG5NEn`&(amC^B@|@+X}tA_b~MC-oy0e!|ZY0YV~%f>y9N` zQgz30F1;aNVXctszqse|EwN#z)UZ>j?Fp*w37kuJ<!h?C@Bh=<rdr8n(s~r<(*aiF zvy$g*%5zrqoCUd5*FL<LtX|x|>`hf27OM_RRfprQ^!9@(_i#MA>gHG6e6m9B3fNe1 zIr{Hr{>{v<EPwglFW-xs)6NRnF1c`bvH9b<g}JoLv+8PGaWy7wi?&bQOXDe5qv$#= zxsIn?$Fa~ovHwAAKDO{K3Qf6rm4dPjGQq$*FL}<VJXoe;wHCLgt9B&srmA+}Oqkc& zJ0H(1nXwY4NNhhWwI9X?F4(IqRkLfc3IUzvyVt5}9^Oke?^|}Inoh|^RwC->Yi0Dy zx5aGl8aYT;wNOmLOq;;85{0PXI~UK0{O)CJLYagA%Y69PjaF|*y6(W@-BjHHoM>bi zWezM2ESG<APTY1}+IBou-oa@4&{9>Z;SinGhgs{UwjNr(kZL<C)}52;&S~kmgQ!Uk z(sk`Q67JBE@WrJwV(a0j@PI()KO=e0q&#PsN#jRF9~3=s&Aa04FLDli^l#hxET^{_ z|HHP@Go0l=95*2Rm8;Kow%qt1%S+F8TK;2)0pWk*4-eIIe^>7s+GhH@E(5~<rT*~6 zYVPl=T^HL;f4|j$P`6nPX)c%sWf0*HjpS`KXTra3iGR-Mp_iesqnfI%fD1WOrK3C! zi>7rmQs@^3*yaJ&IUDIf@O*gA0e>b3mQU}EQWoXNE!-)*q#6sJ^Oi?rS@I^kI>t6E z%AG$le=26e*CTVzO(1t}fc$L@<aXq}GUs|Fh^?`FhiAy_g|`#Hg7V@`3_*Dq)oxF) zQJ(?*%hmaJ=A+sr%`vmSW-$23^QAv4y!Z%<1eA>m^tv4^St!}dVTNJ`E~@6-aM~}* zwx0Hy?=laVsxjBF(x1M>&E4kN@&X%{7ig)>nf*%smJRvt=h*j;V62?;XpK|3<wjUa zprcYiSf!ma`!^Vjw6U~h5;i%?)0kjZVa2SXX!gIUlJd3S6igxTk0c8L+w>*t3rWsj z^b+!V2YwmT5BFL%*UL>mu-KMuu>-jsT6{G#31b7<pY3E@>f|OM_*j9|kT(ee+6hVC z^NcJT8gO1!+<za9lyi8*Dr4-&CQRYwu+Eo_jE7{9{kk53>h_0Sbja874)+(<m;o+- zjsh-!@<yFxC5R9i>plK<6|e{ZfDw7Ad_=Q(j=C9L6-tS0K}qD_SaVK3lY5p&pI%+Q zy?lG2mBQuQOa(3cE2Nukr8>b|FCy>#Bn$R_ox^BTQKws8Cw&DuGUmI!iQAeTMtyiG zEKtA%d>hJRg1hZnaOyO62NLd5+&l$;i~y#T$*2$rFqg1SFPjHs>{$|E78CiA*=^)s ztYTYT%Wv5lXtNLwM>9@jf>|vrU{3(HPfo^>eRB^#b;W+Z_Y&>Xtt4bLCd3E^whJDM zvlB)MUN*U4)rydzaf64KvhxllR~n$;&O4g;U(;k@2Ldz(cDiGx7TVGjk`6ZAIr!n> zhlk_#FFU%P*p}>K$3dwBb`pyN?iL6{S8IGAv29^G-GK4eT#UB}5{_qOl?$-8wBTH8 zYI$7sXZ3$lzc{|^5Sva)O(zrQ(&hCZUHtLI<T<f?yHvhCRlfcCx`VQpaP^QhERHkq z=%Enq5OCu;vvgkUJ|T6VpyDZtLeYc0kl}@}H_c;HIg^*(Q<xb163!TRe;WHZwm7iV zAvPYC8V@H1)8$)M%iC7U+mfS;9e>gL=e^6-V%JHj>*Uj&Qr9VQ>nXAPv{ZgN#m;pb zE6+sV`E3b#Ys@}4K7V|{2Zy$lvvI9z%ft7QGfUP_-&;0`RY#<%Bk{qs7h4CJis6ui z;8{H_wf5oxL1KXFJN)C}<Q}oSLn`lpjDwS;?9O#dHVey#O~H#hu_?GxOs>GZJLXzb zAQd(dKW|XG6nwP~EscJ5{K;{=5^K&$HRs~zo>kL2WJRijgy^Y!SiImDJuQ-_1+o#& zJkOFhQ>6p)DY{Ncu2U)3sb}_*xHUp*&cCUs8#rqEo1^Aa2HW474G238LO&up&CEV3 z|LECO^dRCo0_oZX>iHSl$cR5Yifw_3qhK<8;}$vz`yDLdBqe%>f}0flJ_UbB0SQDx zngXN+&t$}p_RKFTfhNH7Vs?Fb7F;wCbL6!+D?b>r&>i+!DAAwaacvH7lr2YxpM ziPzB_79P!E;lDB=<@;~RX^Xh#t|jxbKV8?bczJmM_P)jF@{M#$+tSIWH!!nZ9Kg$_ zwxvB!o6~&rl5xGb!Givw4^9|P7%ZUN4dI}%%2K(`sllE`N~Q(_hIR{DPz|mc&KoGb zCWLY3q+!62?%uI(x@@$73O9t~=KU6IEUX4m!%c$)7FA7n)wIvzUgtIjGG8Vn<Hy6C zq+MaZA`bROZ7K6$;-SL-i2%PHFg*#)4Qz&-@BszTxT3+Q;Gf`&2t)MdFDV`SQMD-i zfFsNWSopUTvq&*6t(!4(7#3(86Dp|bSz9;LquT!8*pI;0jo%48Ce$GbPA>9)AV7yR z7$EW+np0ep_I$=U?z6u%SA3uSr8(z)_Lt^LQ`uAVvgAJdOLJwZ?3v~&Q`s}kHKg>X sn)ey!zR&)iajhx+xo+nTaD!8W(}ppp0WDBCT&Vnt#r$TIc!rPv7li_rO8@`> literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..746c82eb52be2e437c61bd201433f9d38b8ab177 GIT binary patch literal 18646 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/pylink.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/pylink.py new file mode 100644 index 000000000..11cc11c49 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/pylink/pylink.py @@ -0,0 +1,799 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from dataclasses import dataclass + +import os +import shutil +import h5py +import numpy as np +import time +import zipfile +import pandas as pd +import multiprocessing +from functools import partial +import tqdm + +import umbridge # TODO: add this to the imports!? +#from multiprocessing import get_context +from multiprocess import get_context + + + +def within_range(out, minout, maxout): + """ + Checks if all the values in out lie between minout and maxout + + Parameters + ---------- + out : array or list + Data to check against range + minout : int + Lower bound of the range + maxout : int + Upper bound of the range + + Returns + ------- + inside : bool + True if all values in out are in the specified range + + """ + try: + out = np.array(out) + except: + raise AttributeError('The given values should be a 1D array, but are not') + if out.ndim != 1: + raise AttributeError('The given values should be a 1D array, but are not') + + if minout > maxout: + raise ValueError('The lower and upper bounds do not form a valid range, they might be switched') + + inside = False + if (out > minout).all() and (out < maxout).all(): + inside = True + return inside + + +class PyLinkForwardModel(object): + """ + A forward model binder + + This calss serves as a code wrapper. This wrapper allows the execution of + a third-party software/solver within the scope of BayesValidRox. + + Attributes + ---------- + link_type : str + The type of the wrapper. The default is `'pylink'`. This runs the + third-party software or an executable using a shell command with given + input files. + Second option is `'function'` which assumed that model can be run using + a function written separately in a Python script. + name : str + Name of the model. + py_file : str + Python file name without `.py` extension to be run for the `'function'` + wrapper. Note that the name of the python file and that of the function + must be simillar. This function must recieve the parameters in an array + of shape `(n_samples, n_params)` and returns a dictionary with the + x_values and output arrays for given output names. + func_args : dict + Additional arguments for the python file. The default is `{}`. + shell_command : str + Shell command to be executed for the `'pylink'` wrapper. + input_file : str or list + The input file to be passed to the `'pylink'` wrapper. + input_template : str or list + A template input file to be passed to the `'pylink'` wrapper. This file + must be a copy of `input_file` with `<Xi>` place holder for the input + parameters defined using `inputs` class, with i being the number of + parameter. The file name ending should include `.tpl` before the actual + extension of the input file, for example, `params.tpl.input`. + aux_file : str or list + The list of auxiliary files needed for the `'pylink'` wrapper. + exe_path : str + Execution path if you wish to run the model for the `'pylink'` wrapper + in another directory. The default is `None`, which corresponds to the + currecnt working directory. + output_file_names : list of str + List of the name of the model output text files for the `'pylink'` + wrapper. + output_names : list of str + List of the model outputs to be used for the analysis. + output_parser : str + Name of the model parser file (without `.py` extension) that recieves + the `output_file_names` and returns a 2d-array with the first row being + the x_values, e.g. x coordinates or time and the rest of raws pass the + simulation output for each model output defined in `output_names`. Note + that again here the name of the file and that of the function must be + the same. + multi_process: bool + Whether the model runs to be executed in parallel for the `'pylink'` + wrapper. The default is `True`. + n_cpus: int + The number of cpus to be used for the parallel model execution for the + `'pylink'` wrapper. The default is `None`, which corresponds to all + available cpus. + meas_file : str + The name of the measurement text-based file. This file must contain + x_values as the first column and one column for each model output. The + default is `None`. Only needed for the Bayesian Inference. + meas_file_valid : str + The name of the measurement text-based file for the validation. The + default is `None`. Only needed for the validation with Bayesian + Inference. + mc_ref_file : str + The name of the text file for the Monte-Carlo reference (mean and + standard deviation) values. It must contain `x_values` as the first + column, `mean` as the second column and `std` as the third. It can be + used to compare the estimated moments using meta-model in the post- + processing step. This is only available for one output. + obs_dict : dict + A dictionary containing the measurement text-based file. It must + contain `x_values` as the first item and one item for each model output + . The default is `{}`. Only needed for the Bayesian Inference. + obs_dict_valid : dict + A dictionary containing the validation measurement text-based file. It + must contain `x_values` as the first item and one item for each model + output. The default is `{}`. + mc_ref_dict : dict + A dictionary containing the Monte-Carlo reference (mean and standard + deviation) values. It must contain `x_values` as the first item and + `mean` as the second item and `std` as the third. The default is `{}`. + This is only available for one output. + """ + + # Nested class + @dataclass + class OutputData(object): + parser: str = "" + names: list = None + file_names: list = None + + def __init__(self, link_type='pylink', name=None, py_file=None, + func_args={}, shell_command='', input_file=None, + input_template=None, aux_file=None, exe_path='', + output_file_names=[], output_names=[], output_parser='', + multi_process=True, n_cpus=None, meas_file=None, + meas_file_valid=None, mc_ref_file=None, obs_dict={}, + obs_dict_valid={}, mc_ref_dict={}): + self.link_type = link_type + self.name = name + self.shell_command = shell_command + self.py_file = py_file + self.func_args = func_args + self.input_file = input_file + self.input_template = input_template + self.aux_file = aux_file + self.exe_path = exe_path + self.multi_process = multi_process + self.n_cpus = n_cpus + self.Output = self.OutputData( + parser=output_parser, + names=output_names, + file_names=output_file_names, + ) + self.n_outputs = len(self.Output.names) + self.meas_file = meas_file + self.meas_file_valid = meas_file_valid + self.mc_ref_file = mc_ref_file + self.observations = obs_dict + self.observations_valid = obs_dict_valid + self.mc_reference = mc_ref_dict + + # ------------------------------------------------------------------------- + def read_observation(self, case='calib'): + """ + Reads/prepare the observation/measurement data for + calibration. + + Parameters + ---------- + case : str + The type of observation to read in. Can be either 'calib', + 'valid' or 'mc_ref' + + Returns + ------- + DataFrame + A dataframe with the calibration data. + + """ + # TOOD: check that what is read in/transformed matches the expected form of data/reference + if case.lower() == 'calib': + if isinstance(self.observations, dict) and bool(self.observations): + self.observations = pd.DataFrame.from_dict(self.observations) + elif self.meas_file is not None: + file_path = os.path.join(os.getcwd(), self.meas_file) + self.observations = pd.read_csv(file_path, delimiter=',') + elif isinstance(self.observations, pd.DataFrame): + self.observations = self.observations + else: + raise Exception("Please provide the observation data as a " + "dictionary via observations attribute or pass" + " the csv-file path to MeasurementFile " + "attribute") + # Compute the number of observation + self.n_obs = self.observations[self.Output.names].notnull().sum().values.sum() + return self.observations + + elif case.lower() == 'valid': + if isinstance(self.observations_valid, dict) and \ + bool(self.observations_valid): + self.observations_valid = pd.DataFrame.from_dict(self.observations_valid) + elif self.meas_file_valid is not None: + file_path = os.path.join(os.getcwd(), self.meas_file_valid) + self.observations_valid = pd.read_csv(file_path, delimiter=',') + elif isinstance(self.observations_valid, pd.DataFrame): + self.observations_valid = self.observations_valid + else: + raise Exception("Please provide the observation data as a " + "dictionary via observations attribute or pass" + " the csv-file path to MeasurementFile " + "attribute") + # Compute the number of observation + self.n_obs_valid = self.observations_valid[self.Output.names].notnull().sum().values.sum() + return self.observations_valid + + elif case.lower() == 'mc_ref': + if self.mc_ref_file is None and \ + isinstance(self.mc_reference, pd.DataFrame): + return self.mc_reference + elif isinstance(self.mc_reference, dict) and bool(self.mc_reference): + self.mc_reference = pd.DataFrame.from_dict(self.mc_reference) + elif self.mc_ref_file is not None: + file_path = os.path.join(os.getcwd(), self.mc_ref_file) + self.mc_reference = pd.read_csv(file_path, delimiter=',') + else: + self.mc_reference = None + return self.mc_reference + + + # ------------------------------------------------------------------------- + def read_output(self): + """ + Reads the the parser output file and returns it as an + executable function. It is required when the models returns the + simulation outputs in csv files. + + Returns + ------- + Output : func + Output parser function. + + """ + output_func_name = self.Output.parser + + output_func = getattr(__import__(output_func_name), output_func_name) + + file_names = [] + for File in self.Output.file_names: + file_names.append(os.path.join(self.exe_path, File)) + try: + output = output_func(self.name, file_names) + except TypeError: + output = output_func(file_names) + return output + + # ------------------------------------------------------------------------- + def update_input_params(self, new_input_file, param_set): + """ + Finds this pattern with <X1> in the new_input_file and replace it with + the new value from the array param_sets. + + Parameters + ---------- + new_input_file : list + List of the input files with the adapted names. + param_set : array of shape (n_params) + Parameter set. + + Returns + ------- + None. + + """ + NofPa = param_set.shape[0] + text_to_search_list = [f'<X{i+1}>' for i in range(NofPa)] + + for filename in new_input_file: + # Read in the file + with open(filename, 'r') as file: + filedata = file.read() + + # Replace the target string + for text_to_search, params in zip(text_to_search_list, param_set): + filedata = filedata.replace(text_to_search, f'{params:0.4e}') + + # Write the file out again + with open(filename, 'w') as file: + file.write(filedata) + + # ------------------------------------------------------------------------- + def run_command(self, command, output_file_names): + """ + Runs the execution command given by the user to run the given model. + It checks if the output files have been generated. If yes, the jobe is + done and it extracts and returns the requested output(s). Otherwise, + it executes the command again. + + Parameters + ---------- + command : str + The shell command to be executed. + output_file_names : list + Name of the output file names. + + Returns + ------- + simulation_outputs : array of shape (n_obs, n_outputs) + Simulation outputs. + + """ + + # Check if simulation is finished + while True: + time.sleep(3) + files = os.listdir(".") + if all(elem in files for elem in output_file_names): + break + else: + # Run command + Process = os.system(f'./../{command}') + if Process != 0: + print('\nMessage 1:') + print(f'\tIf the value of \'{Process}\' is a non-zero value' + ', then compilation problems occur \n' % Process) + os.chdir("..") + + # Read the output + simulation_outputs = self.read_output() + + return simulation_outputs + + # ------------------------------------------------------------------------- + def run_forwardmodel(self, xx): + """ + This function creates subdirectory for the current run and copies the + necessary files to this directory and renames them. Next, it executes + the given command. + + Parameters + ---------- + xx : tuple + A tuple including parameter set, simulation number and key string. + + Returns + ------- + output : array of shape (n_outputs+1, n_obs) + An array passed by the output paraser containing the x_values as + the first row and the simulations results stored in the the rest of + the array. + + """ + c_points, run_no, key_str = xx + + # Handle if only one imput file is provided + if not isinstance(self.input_template, list): + self.input_template = [self.input_template] + if not isinstance(self.input_file, list): + self.input_file = [self.input_file] + + new_input_file = [] + # Loop over the InputTemplates: + for in_temp in self.input_template: + if '/' in in_temp: + in_temp = in_temp.split('/')[-1] + new_input_file.append(in_temp.split('.tpl')[0] + key_str + + f"_{run_no+1}" + in_temp.split('.tpl')[1]) + + # Create directories + newpath = self.name + key_str + f'_{run_no+1}' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Copy the necessary files to the directories + for in_temp in self.input_template: + # Input file(s) of the model + shutil.copy2(in_temp, newpath) + # Auxiliary file + if self.aux_file is not None: + shutil.copy2(self.aux_file, newpath) # Auxiliary file + + # Rename the Inputfile and/or auxiliary file + os.chdir(newpath) + for input_tem, input_file in zip(self.input_template, new_input_file): + if '/' in input_tem: + input_tem = input_tem.split('/')[-1] + os.rename(input_tem, input_file) + + # Update the parametrs in Input file + self.update_input_params(new_input_file, c_points) + + # Update the user defined command and the execution path + try: + new_command = self.shell_command.replace(self.input_file[0], + new_input_file[0]) + new_command = new_command.replace(self.input_file[1], + new_input_file[1]) + except: + new_command = self.shell_command.replace(self.input_file[0], + new_input_file[0]) + # Set the exe path if not provided + if not bool(self.exe_path): + self.exe_path = os.getcwd() + + # Run the model + print(new_command) + output = self.run_command(new_command, self.Output.file_names) + + return output + + # ------------------------------------------------------------------------- + def run_model_parallel(self, c_points, prevRun_No=0, key_str='', + mp=True, verbose=True): + """ + Runs model simulations. If mp is true (default), then the simulations + are started in parallel. + + Parameters + ---------- + c_points : array of shape (n_samples, n_params) + Collocation points (training set). + prevRun_No : int, optional + Previous run number, in case the sequential design is selected. + The default is `0`. + key_str : str, optional + A descriptive string for validation runs. The default is `''`. + mp : bool, optional + Multiprocessing. The default is `True`. + verbose: bool, optional + Verbosity. The default is `True`. + + Returns + ------- + all_outputs : dict + A dictionary with x values (time step or point id) and all outputs. + Each key contains an array of the shape `(n_samples, n_obs)`. + new_c_points : array + Updated collocation points (training set). If a simulation does not + executed successfully, the parameter set is removed. + + """ + + # Initilization + n_c_points = len(c_points) + all_outputs = {} + + # TODO: if umbridge, just run, no parallel from here + # If the link type is UM-Bridge, then no parallel needs to be started from here + if self.link_type.lower() == 'umbridge': + Function = self.uMBridge_model + # For now just do same as usual + self.link_type = 'function' + + # Extract the function + if self.link_type.lower() == 'function': + # Prepare the function + Function = getattr(__import__(self.py_file), self.py_file) + # --------------------------------------------------------------- + # -------------- Multiprocessing with Pool Class ---------------- + # --------------------------------------------------------------- + # Start a pool with the number of CPUs + if self.n_cpus is None: + n_cpus = multiprocessing.cpu_count() + else: + n_cpus = self.n_cpus + + # Run forward model + if n_c_points == 1 or not mp: + if n_c_points== 1: + if self.link_type.lower() == 'function': + group_results = Function(c_points, **self.func_args) + else: + group_results = self.run_forwardmodel( + (c_points[0], prevRun_No, key_str) + ) + else: + for i in range(c_points.shape[0]): + if i == 0: + if self.link_type.lower() == 'function': + group_results = Function(np.array([c_points[0]]), **self.func_args) + else: + group_results = self.run_forwardmodel( + (c_points[0], prevRun_No, key_str) + ) + for key in group_results: + if key != 'x_values': + group_results[key] = [group_results[key]] + else: + if self.link_type.lower() == 'function': + res = Function(np.array([c_points[i]]), **self.func_args) + else: + res = self.run_forwardmodel( + (c_points[i], prevRun_No, key_str) + ) + for key in res: + if key != 'x_values': + group_results[key].append(res[key]) + + for key in group_results: + if key != 'x_values': + group_results[key]= np.array(group_results[key]) + + elif self.multi_process or mp: + with get_context('spawn').Pool(n_cpus) as p: + #with multiprocessing.Pool(n_cpus) as p: + + if self.link_type.lower() == 'function': + imap_var = p.imap(partial(Function, **self.func_args), + c_points[:, np.newaxis]) + else: + args = zip(c_points, + [prevRun_No+i for i in range(n_c_points)], + [key_str]*n_c_points) + imap_var = p.imap(self.run_forwardmodel, args) + + if verbose: + desc = f'Running forward model {key_str}' + group_results = list(tqdm.tqdm(imap_var, total=n_c_points, + desc=desc)) + else: + group_results = list(imap_var) + + # Check for NaN + for var_i, var in enumerate(self.Output.names): + # If results are given as one dictionary + if isinstance(group_results, dict): + Outputs = np.asarray(group_results[var]) + # If results are given as list of dictionaries + elif isinstance(group_results, list): + Outputs = np.asarray([item[var] for item in group_results], + dtype=np.float64) + NaN_idx = np.unique(np.argwhere(np.isnan(Outputs))[:, 0]) + new_c_points = np.delete(c_points, NaN_idx, axis=0) + all_outputs[var] = np.atleast_2d( + np.delete(Outputs, NaN_idx, axis=0) + ) + + # Print the collocation points whose simulations crashed + if len(NaN_idx) != 0: + print('\n') + print('*'*20) + print("\nThe following parameter sets have been removed:\n", + c_points[NaN_idx]) + print("\n") + print('*'*20) + + # Save time steps or x-values + if isinstance(group_results, dict): + all_outputs["x_values"] = group_results["x_values"] + elif any(isinstance(i, dict) for i in group_results): + all_outputs["x_values"] = group_results[0]["x_values"] + + # Store simulations in a hdf5 file + self._store_simulations( + c_points, all_outputs, NaN_idx, key_str, prevRun_No + ) + + return all_outputs, new_c_points + + def uMBridge_model(self, params): + """ + Function that calls a UMBridge model and transforms its output into the + shape expected for the surrogate. + + Parameters + ---------- + params : 2d np.array, shape (#samples, #params) + The parameter values for which the model is run. + + Returns + ------- + dict + The transformed model outputs. + + """ + # Init model + #model = umbridge.HTTPModel('http://localhost:4242', 'forward') + model = umbridge.HTTPModel(self.host, 'forward') # TODO: is this always forward? + + # Run the model + #out = np.array(model(np.ndarray.tolist(params), {'level':0})) + out = np.array(model(np.ndarray.tolist(params), self.modelparams)) + + # Sort into dict + out_dict = {} + cnt = 0 + for key in self.Output.names: + # If needed resort into single-value outputs + if self.output_type == 'single-valued': + if out[:,cnt].shape[1] >1: # TODO: this doesn't fully seem correct?? + for i in range(out[:,key]): + new_key = key+str(i) + if new_key not in self.Output.names: + self.Output.names.append(new_key) + if i == 0: + self.Ouptut.names.remove(key) + out_dict[new_key] = out[:,cnt,i] # TODO: not sure about this, need to test + else: + out_dict[key] = out[:,cnt] + + + else: + out_dict[key] = out[:,cnt] + cnt += 1 + + + # TODO: how to deal with the x-values? + if self.output_type == 'single-valued': + out_dict['x_values'] = [0] + else: + out_dict['x_values'] = np.arange(0,out[:,0].shape[0],1) + + #return {'T1':out[:,0], 'T2':out[:,1], 'H1':out[:,2], 'H2':out[:,3], + # 'x_values':[0]} + return out_dict + + # ------------------------------------------------------------------------- + def _store_simulations(self, c_points, all_outputs, NaN_idx, key_str, + prevRun_No): + """ + + + Parameters + ---------- + c_points : TYPE + DESCRIPTION. + all_outputs : TYPE + DESCRIPTION. + NaN_idx : TYPE + DESCRIPTION. + key_str : TYPE + DESCRIPTION. + prevRun_No : TYPE + DESCRIPTION. + + Returns + ------- + None. + + """ + + # Create hdf5 metadata + if key_str == '': + hdf5file = f'ExpDesign_{self.name}.hdf5' + else: + hdf5file = f'ValidSet_{self.name}.hdf5' + hdf5_exist = os.path.exists(hdf5file) + file = h5py.File(hdf5file, 'a') + + # ---------- Save time steps or x-values ---------- + if not hdf5_exist: + if type(all_outputs["x_values"]) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(self.Output.names): + grp_x_values.create_dataset( + var, data=all_outputs["x_values"][var] + ) + else: + file.create_dataset("x_values", data=all_outputs["x_values"]) + + # ---------- Save outputs ---------- + for varIdx, var in enumerate(self.Output.names): + if not hdf5_exist: + grpY = file.create_group("EDY/"+var) + else: + grpY = file.get("EDY/"+var) + + if prevRun_No == 0 and key_str == '': + grpY.create_dataset(f'init_{key_str}', data=all_outputs[var]) + else: + try: + oldEDY = np.array(file[f'EDY/{var}/adaptive_{key_str}']) + del file[f'EDY/{var}/adaptive_{key_str}'] + data = np.vstack((oldEDY, all_outputs[var])) + except KeyError: + data = all_outputs[var] + grpY.create_dataset('adaptive_'+key_str, data=data) + + if prevRun_No == 0 and key_str == '': + grpY.create_dataset(f"New_init_{key_str}", + data=all_outputs[var]) + else: + try: + name = f'EDY/{var}/New_adaptive_{key_str}' + oldEDY = np.array(file[name]) + del file[f'EDY/{var}/New_adaptive_{key_str}'] + data = np.vstack((oldEDY, all_outputs[var])) + except KeyError: + data = all_outputs[var] + grpY.create_dataset(f'New_adaptive_{key_str}', data=data) + + # ---------- Save CollocationPoints ---------- + new_c_points = np.delete(c_points, NaN_idx, axis=0) + grpX = file.create_group("EDX") if not hdf5_exist else file.get("EDX") + if prevRun_No == 0 and key_str == '': + grpX.create_dataset("init_"+key_str, data=c_points) + if len(NaN_idx) != 0: + grpX.create_dataset("New_init_"+key_str, data=new_c_points) + + else: + try: + name = f'EDX/adaptive_{key_str}' + oldCollocationPoints = np.array(file[name]) + del file[f'EDX/adaptive_{key_str}'] + data = np.vstack((oldCollocationPoints, new_c_points)) + except KeyError: + data = new_c_points + grpX.create_dataset('adaptive_'+key_str, data=data) + + if len(NaN_idx) != 0: + try: + name = f'EDX/New_adaptive_{key_str}' + oldCollocationPoints = np.array(file[name]) + del file[f'EDX/New_adaptive_{key_str}'] + data = np.vstack((oldCollocationPoints, new_c_points)) + except KeyError: + data = new_c_points + grpX.create_dataset('New_adaptive_'+key_str, data=data) + + # Close h5py file + file.close() + + # ------------------------------------------------------------------------- + def zip_subdirs(self, dir_name, key): + """ + Zips all the files containing the key(word). + + Parameters + ---------- + dir_name : str + Directory name. + key : str + Keyword to search for. + + Returns + ------- + None. + + """ + # setup file paths variable + dir_list = [] + file_paths = [] + + # Read all directory, subdirectories and file lists + dir_path = os.getcwd() + + for root, directories, files in os.walk(dir_path): + for directory in directories: + # Create the full filepath by using os module. + if key in directory: + folderPath = os.path.join(dir_path, directory) + dir_list.append(folderPath) + + # Loop over the identified directories to store the file paths + for direct_name in dir_list: + for root, directories, files in os.walk(direct_name): + for filename in files: + # Create the full filepath by using os module. + filePath = os.path.join(root, filename) + file_paths.append('.'+filePath.split(dir_path)[1]) + + # writing files to a zipfile + if len(file_paths) != 0: + zip_file = zipfile.ZipFile(dir_name+'.zip', 'w') + with zip_file: + # writing each file one by one + for file in file_paths: + zip_file.write(file) + + file_paths = [path for path in os.listdir('.') if key in path] + + for path in file_paths: + shutil.rmtree(path) + + print("\n") + print(f'{dir_name}.zip has been created successfully!\n') + + return diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__init__.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__init__.py new file mode 100644 index 000000000..70bfb20f5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .surrogate_models import MetaModel + +__all__ = [ + "MetaModel" + ] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c10c82287a57ba1e3b4dd428962e57cdfbc5c58 GIT binary patch literal 258 zcmZ8bL23d)5S*DcQG-Gt;14|P#r}Xu4ncEKgy2OF&FBp7;_ObCo;C4Ferd0s{DPOH z*HcJAS5s6M)xO_<5{%Z%&>nbS8u1s3#VZdDn2a#ei9)WW6h`gkTAAcSq^+xDGnI9B zZlj)iV_j%+i!`a9sS3gGb+lMC2Hl;yji{YNJd5zamv_2tpeQ5kU_~|%goDpqrZvHv z-&KVzBf%_>@6{Hj&VMa+%wVfemX6xxCirjoUj>MHnMcIY=c(?DxxaFD()>z~Og*KN G&d)E$kVM1) literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe3d14f8dfc5304350b98b23bc52ca5b2315a871 GIT binary patch literal 292 zcmZ3^%ge<81T4a;so6mKF^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%PT$m$MBn_B)SMz_popI)^DTkm(xRgL^u&_X_*{@gF<9mndwhIiPELIM zN`}uMD}IGLTg8MHrxq2*6lLdU<YXi!7RR{cCzs}?=9Lu3xM!AllqSWv<>Z$KB$i~v zBqdg+7MCUFWTq75SHz&(5ECDtnU`4-AFo$X`HRB_Xl-dus$CH$&>oOGi#3772WCb_ g#t&=^j2agh)R7TTj8)(RGZQyk13L&7u>(~D0K~CSSO5S3 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1a3fcc2eed66172304cd27ab5fe111ca0198bf5 GIT binary patch literal 323 zcmZ9Hy-EW?5XX1#B7R`N%6GV813_#=M2L;Wi693O7M4wRE-u;KJN6?aw!VkGuV9<E zxYo*7u+h2Lhy(K*hX2g)A2}Qz5sa7jtx{M&`sQzB*j!_VQ-mUl8e-{`Qlhd2on|V3 zAjRO5qFB)Gu!JbfMuGAD-d&M*Cn0&?EMx>>dm-$UZeIv#j1X_c@8RSQU$2u3UIp-h zdssGOu98jbUoxv5cxm*rjJk2G1{sqFc00LeH&t0Zo{i4=ENP?I+{z_z*|vu3dCLL8 zY|U%!r121viD5N<68)4<j?d%<!U``d->mt6w_FJAbQEILZn}d@d?6XQ%F%KdAdd6w F`v>INVKD#z literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2854217e56fecb2456011a91a984951fed9cbcbb GIT binary patch literal 4921 zcmahMTWlN0@s2!_$2Td8)YBIAvLnl8EZK2m=V2)_WjnGRH+F(pkxiVqCyLUMRPRo< z#2f*o2vFJ(U^*3GrcD5%KwSmWha0r0`{&j``_lqsa6pL#1Q=-jVf2SaV!+K$I!lU= zQ{rTGoSogBnVp%PnO*(PZnsd-7*9XnY^SJylR>rVw~?<d0&<%|)Fg#yq!Z{#8hX8; zi|HrzF=mpX$vh(%V#Y~h88--~7(2<9ah+g}SthMC6`_z3nP&8e{fM5lA>9RPz?^)^ zGA8nz%p-py?!P#@=pS8-_=gU`ckJ+yW5b92!v}{CS}Y^nqCA@rkNIafF^VjYiDu^p zbhs(TbMcV$vqetiQHU4Cgos&jI3$G=B0oT5LwGqX5QIICX3ldFUK+m`Hf`HQI<T1{ zc7F8*%-*IHYL3j7+Z<iRQYOv3t~SpiTC-C17&XUKX^^h1ic$)j1aB**BuGfYY|5<R zHdF~y7R4wAkUnLViGJH{uBNwQMa-t*4oKOk=|WSoyGlucrxok3DP&U20NKwBcfgj7 zx;-}8Q>TS<G5?0%L1AyCK$ab=4%u7hSLmFzKB{AP0Ntn!cSvv|Ysw|pT|+5OEd`?I z%eIL=#hGjHLQNorbc$=I56qN8BU@c;iitP%QgUaVtB(>5G^H>p<`NZWu2D<+OVl-5 z?y6JFxvDs_Z#uMErQC9FbrnvMnro_#=4u|DYp%{|c~4Lo-Q`<TU{$Iq<xzBsr$NtV zMXwoq6<Ra)DZaUy&l`N>%lWFiHTIB?POWcJKE<Mu*do7J=TI2=V11<J6wL~w;cSiT zz<;e8PxyA)diif<OWRWI@}at9#jd4Gb!b+1db?9|F6~u0N~_YYbSRz3h1^P;VkWti zG*Z-N(;a{t@T)Y)iN<qn<Zo8m>fYa$<v}ppAkBLRGH#=mbvvYWRCfVwG}4ey@it0N zLSC2i{>Q06q|$*}He2ri&ql2tK)f2nT}sOd>T-K(*K=*!h1yU%@Ivj`sMQ~uTJ2c< zyL_~&E$q;&_)y1Y=N+h48?}m++AY7*Nb{Vyaw1wA9m?|}@H>=RzEqdSj@{M06^}MT zc6hyZo{;;Rnzn<^|9p9hd#<~>+E|@ae#M{bsjf8kXcyGm-CF(OOx$y|T9E5&q_5)I z3J4tjTz_?~u}59VkGkcv^*LoX>e228b-Y(Y(e+)5<r&x3?+<^~pn39Bzbu)Q9$L z?$w_9<_kZVF)vj4zhj9}+^5)b1J(7$UU8#=&3#(!cbv|?D*aBm8QtnHLGEC6y|Ld( zizs+O44!*Tt~HU|71+)pZb6P-<<AQVS-MEBeSRq_$)Uu2QWtnJ+4ADq1mcCzRVj3S zELg##vKUG-fdw=(V8HY=rX!dZF};lGc`~ttY4i;}i0K5T_a)hj(HQT4U%HIhrO;JQ zSmdPv-Q!l+`!TsRU_;YPG$KWl{Nrz-MPQD!k)*BfQs{$zDRt$8v#GuT2HqtJ0iG(x z7$?s2BGw7lutDIac_FDga3JZZQG=R5ZxBi85=q4o$yJ8ULNv}x^0L5-yI>rdy7||q zFHC)VJaVYq9vmOgm07TX6BcGU%tS<fIr6JdNc;2gaiZt;n+Y@1AP8PkdLa=8?L{ue zC*qNR{)4ptR0aO`c+&Lt*$YAcYyQWiVkFI$zPGOo_rVw&rUfoMkC}KP&L^#6Vlj^P zFL3C!p#eQM&v0SBVyc-(k!_TnPArv`Cls>C#if~q7^^7EOv55J$kE8G3~E}*Fcgi4 zXTj6^u{pT3aDtbjkvO);Lvj9ENaA7(0xw}l9H^plZA`z14bm*Pz+?In)+Hp&#<+PN zMMX(85;v0CiWvcd12gmdvIO??acqpnC0>*<JHamp%a2L@f*@lf9O|OTV>2ILjPW8o zS20_Tp0}pwu<@-$d0|n;hB&xR0zaT=44Xv0vb!ZJflQf;hk4APXc)GO^Gg61AVjfk zCMpP_X<oj@^Kp@QRwRWR8<)$$fQ?I)9{eE-Ab?wf9gG4W;o}G!!(99-2RkB>yM`H= zh&7b`zwOmgLJdbBMR45QRUWLs`mitq(I+G%exMs(#oK9s4VOaiasp;AL1vUOTNMjQ zG7`zt0~?9X!4ueY0fdc%FzY!nF>_)21Z>3r=c*$E<kdL{@PvSZCoW+VoYev+&tg3! zT0NRE3(h-N_M34j#6hlNJ<-w#M{*i1VLkNNT+;;GYbYoc!p5@FA#8$OLa>cUk`U{o zXi0Ps%rI8Tva^*eGbSo0#gI_Oy0?e1j$4w*UEu$*_6;|7Z0a3|4QWc8Ps|Fl94Aek zNQ5CA;<7Y#GAf^1oSvHImU#)vLKKOKr71}a@0?kLn2JF7gkq!)NmJ!|MT%8m0qm@e zL>Y8)!cY1Mgu@C|GE$xnwW&{S8eW+w0_y2kJ%?A$6m9lQtLpAm-TkV2aD7yD2kv$j z+^^lY7F-hr+r&!nq1~(6yHtDk%J@T*qeK}Dr|Du-ciObYT2`%@lR1=U2Mg?=$_@hZ z)JQp7@+~K`Cjr2BFIedT796Kk$Ema)NbF5{&;H6+umx0GU?sR!o-5c7sP+RZ<By!4 zOz`%bAHR9)%-WfPvs-m`ube8{TVTaxNx%GI>Z4Sa{?gQzH?<X6*G=aQXO_+$DX={% z+mmN|N;<uvv*>BfwyU1LG@E9hZCO1fiZ*oC0XTuIq}h@l=AS)#26|Z?tNXI=<t=*( zmOZLv&&n9gwRY!P)$U=n`>5J|ywEbDwv3dhR}H==1YEbKjTwEhxifoV?QGgyZ0*Zk zP+JGm_M+RDk=EMN#-i1|`bxI@OKV5o+EMg&+`jVhmE34fEO_^+-hJuuVpD6@vo;9s zw0bkMzhw&6e%0DvqV(prqKhoq)1&FphpyK2=p$cO&RFp6RegI)l-E2;SK#&W^jOBd z)!dr(-kMmONC&sPZP`7yrq-s?<Bx34)l)^6J2R9GuJ0*&eA)PV_-_B_(ZcSRO9s8Y z=?MkkYXV?Pd(%@3Wp`CLj)F<AuY2!a1+H9QKJfZ|{r%uy%!R<4-^<7XqiX9UdzCqJ zeYw=#3+mpZg`T4Y&(Wf*E!(^1$jZ61cYD>oBZaOb1=o>#e9_llGBHFC0ACYODgztk z@|7r^eUvWl25-=AVl9E0@vY{TwNu%j=8Wqz_r~(gBZcM>wRr>(_{br;dU6Bn@7{YS z?;I;Q$5iK7n%S~@Gtqzf_I~NxyRKUwE%*YeFL2lRC&w3#d*c0}!oi?=Fj%mUtM>7< z?h$KUwPX%mcdk0q&aLtQBCB0x+w*KY8Jjb`*Bz^lwBsT8>b(rN`hHqhWGy$%H_Vxt z97>yO*-#|hBsvRho65H3S%_B4P16lihRL9!>y6L)b4-r=B=Bh<?|K8iKL+ph+~a<K z<_~8o<6?W~r~B6<aG<&IV&7n~_h8AO^9?_t0DMhA$wZl5Pbi}qd<URJz*7fhwym<) zEvuHa<)IZO4QAg%oAc(xjft#&y(JBKJ*3)(^0pz8imug@*H5pWPM`i?kum+^^v_R! zIPuZMO8HMB|C&DNVaEok2ZOe;WBLb2X@CQEYzl=?A{+{dF98L1O7jBGiSa;;m&IsU zYPg2XQ5kN-L_&}%_hna%lgS+*M5hDOaOuM>Bvp|RDeUBG#qI{Gh2`=+XRP$%tFT@! zZl6<M0ZNGyfN$7Wp&Tv>{Oe*0hU7UXWdT5H({#zm&<sQs01HK1R?OtDNWGl@zOP7i p<h5UsI-J*jMXD>W{h+#z(qnYd+nzg7(qExzSBd%|C@P@b{{g`MqtO5W literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffab8b4f67e52a3128aa8740301f958a0d72c502 GIT binary patch literal 2815 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 C4-2yZ literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92db2e7e7390700d4b6b25bcdc0db1906dee37bc GIT binary patch literal 5228 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 H>m>gNxx5;C literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82737a42dd7351d06b703b3da838031ba95979da GIT binary patch literal 2886 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 UGiz{V6;d({`I`N<wKeJd7wkkSHUIzs literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92d0cc0e7a0a07123fdfbc2c777d1b9281a43344 GIT binary patch literal 14412 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51c4ea4a7b9eb757b303782de26abffc022df39b GIT binary patch literal 21706 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..063355b16a397fb5fd89d38daa0d3ca5a8506766 GIT binary patch literal 14506 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 B<oN&q literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f32454f2feaeb17bcf42a4b924156c45d354b009 GIT binary patch literal 84465 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 B#&`e# literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbfe4d97e8e83ebc276e45ba6e84f514784f1d0b GIT binary patch literal 5560 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 Z-$TZ+G!?TsR$7>|U8i)t^vVlo{{y+urp*8V literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaf7d2d285e24e4d2e31c3dab3b1b071be7c5ecf GIT binary patch literal 8154 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 bd8inaNFU$G@89A|r0WO|$^Hun+x`CllJEy5 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27878248cbdaa2abf0af9d51d061aa6e2db86f43 GIT binary patch literal 5648 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 Qn=09pu6MokM(NCd0M{nQGXMYp literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc01f0f01b8bc70d438a3317b87d304883456f15 GIT binary patch literal 17477 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т#dTfa#8J56>f8$ut6T)8sKb87ka10Av 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 WxdKn&n8;-&>4E+sNkEpU=>G#}NHw+q literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..786fb6880e590007f4cc628dab413d62f1590cce GIT binary patch literal 19555 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7e0226dc1e28c09b9cd09a610599007b2267e3c GIT binary patch literal 17597 zcmd6PTZ|l6dS2c7-qUmCa5$v6rAt<9nlmfy#aSzgEQuGHD{;hVD2ZxQZq{^F_jFHp zRr6H!kTa>?hou&~G9Z~SHa7O+V8&P&Q64sly$FK9KpvbR#=`K!!Z3n*2n^)K%7bC7 zfqgI*%Y6TTs;jGKh9b4t0PaDbK2_(O|6J;v|NCz>*3?u{!RPLO{WJUZmZJP0x=4R? zT)c>{{}vKkvDL0pQ~6h`Y5c3#bpADJ2LEPy*;-Dex>`5i%h&SA>$cG?^a{0ts=T7u z89V!)VrTDawW6)AE7jb`pslP`)yN2L*}acdT;XEQ>U-Utdc$-5Knxl|+jARKG5wjt z#f$j*A0lyhXc(4?A!*bpb%k$^e+@g2zXI+Q?QBc2i_JN^WS8GlG4RjWQ+5TpjBVP} z_6%}a`*C~Lo<lBY&)W;{DYd+P%wEKA!9H#;;kRf%VV|&<QKMv^v`^tq*?!DEjo&Fd zgK0e(6))cDUvT_(%k`~an^KgbiO;powr@7NmhYP_$904iIKJsyy?z(JP2u&-VAC=C z!tooTz2Vqq&l0V+YjsiT2`=n;w$o)|eM?w9Cvb#s4*a&;;^Lc^-TolBX?hzSrxC0c zx#mkj0CEF##+NI}hcCH>`5ZOjYZ|D$CyAJN3W3#jM_nZSjz@RSY_B@2ri<~MOK8|_ zJUi+Z56=vC`i^P2SmN~Egp_Y$de*kp?phmN#}w9W)3yR@m5E`Jo1Tpkf?h)X8WHrG zJZa}n-x2MegJE_}n-_f*YwaN4v<BV4#H!zX+Vw=w>OOsQ)qEYRJf`IJd4ycYcWw<p zrp@(6om=%QwCJBO0F2P8^OKPy=0}S4svkM@H7wI;=%bouTyyl8A2_9^*X??@K|5KA zgCs2BnEs&O_e9{>&&eG?&-5&o)wR7|((tU=wSu-=-^5ai#$dxqmH6I<C%2hwx@mO- z&rMa>w0b>ky{@y9y4l!tHg^0?XZy^hYt_{KmT21tZVmkS5p3GcFV&lEJoU*3oL(iW zV{)Bf(+Wl#(tqH?=dRtl>)fu7PS<m0+YOQ-tqpn`j-ZEd1{<56chw9;yvh3>s`~Ot zy7iuQ=b=PUr`;Ri^d3b5`=b8Z>#x^?O`PjZuS+|*+4ZdPXlSdVR=e58k?%UzwzJ~7 z_zo~t;elCfTirI!10SS>%57|7hn66j)p+;DrvN9$>&G*}*lfpZHtRl~5;oxEYG0$$ z6%?Csap0L?Q(#}_ZKvJZ46xYVXuZ20I2R3u4m5UZ*J}rSV?2_Ehsk2exyhk%jn=jS z0yfQzhI91up(?UQvbeq@N7JynjRCeWF9OERUE%;q>O3yt9DM{2aF1j{2TtMPfiqh< zd<JDZ-+b`dd&?7^>$Q^=`c$V8+vogSsiyV-jLvdh2m2!C1o2~d#OcP*>mb)TdcH}= z$-LuspETc>tsTdIy&p&nOh}wHx!|S7;exj;aa4V)+uyV{oS@xE5n1nB4QB-$A(=m5 zrdw|g+=krPgeP4<P11(W7}aS9J0?|=hsiTHz%2VtL!P}6_q{o}nt+T;5`GhMW2`zz z6oBqH=9-6X=>vjsOwzl(-V)xR??1wJmlapdi&kUP<O^a~4>}IFu@uSRFehglz=xw@ zV-SS0fz#cg<4E~#*XfSNB%FS?-H@mGK}RrE#|L=2phOGR@Oq%u_A$YOVEe2j-}n5W z?z>hWY%e%4<+nG1>R`d(D&QXh^9iaCAP4OSGL8d1B~!k6O$?lyvRe@8Kd4*U25!Rq zsU|bFPdkL9-;{(APnz(;s?$_3W7>i&+6ZBdf$~ZW7nYgKxIGdGk~<TU5(KQKx#fDd z<ys%r{mtKeH=e&`Tm7KE?T8J}C&s$rrJ($%b!W-N1jFt_-geAw0#?8*wj21GB}+#~ z1DKlh4)KnqLI%tSKQk$U(23xdiS)U`m-Ix&jD=6r_=Jw--m_=ZKy&tNngubPgCft9 z_(*1xa24|mFw<qpl0?Gf3`<dE#k}z9Yv!3(2i@+5)!15j&1pjx73PIDmJ;H6!%6C0 zy=tDhuyS>@T~|ncYWq0qqZ%(!jhBwD!K3BTf#bbw`Hnpv;K~c;#1LJajAWQ{^~{TI zAiVyLc_z+$?#h+*i=VT=YPKDc9t1s;(LgR<e&rHsLO^a1Gq~LA3vV0n?*@E^U+H=q zfRbiA7&Tz1G0(g<A%&c0Ddeq03aQFR%9A+2pRtN7m=CQFe%g?@!Er~#Uy?=qbD-!| zS;RjRMNw7??vdVaI8j#0uxo;p)7GE9|G$3!kAM8V=Xa+j0O4Z;g_jx&NJk&aYxthW z*WX4Gs-aR>LJg@J>PWTFK&posq(+!UnhA4Avtb@-E-WF<hh?ONa0+QLEFdj~MWp4h zf^;gJMp_AHkWPoQNN2)1q_g2X(m7jMS3XkLs`F8v)vMPxI#E^%4pET~np88Q>5)Jm zV|i3aMC52{La3$7lz1A=9uhU93ZI%p42rMYK|(vh&1m|7gcz0G`dC1tzUV3jFuF|P zLNrBuD`C3P)C3R4^b)2RO--<;>Oy4rPPZ9lcuhnZk48XURz!u8X-Z}&nWcnOez8c& zaZ2VXp(iVjQL;qI2}+hJIZ4SWN*+V<ks?g|{Nw)l=We_S-NU~joGtI!8}^_#xFge* zUYm6CZhM#UaHZ*3!9X}Gm(O2ax$x$dH?MzT^-DK42JNoB(&$-R&JC;I@7`!P`ZpXT zE4}88Ch6+nqtH41?PoXfaJC#VaBpmoFvLQ<@b2932SRu)K(bUB{Tp~jb*Z-ctNooQ zU$2u=Qm^|Mu>V;kN<OPT{BL(2=RCGKtd3|j=q!vr8Dw(!@+o)$ncd|;>8ODgs&{c7 zI(i5L$_M(;cw2E#sS5pt%AO(1_tj2jXuPAi+A~UMbjZx1S*tiy%$G<_eC3c$<90iM z@B+r<N;3yIQ_Q%>dg;}~j*$>L01-sneSi{1Wn*nlkp7On2eC(5Ris2fl@6RL;3CWk z=S+{ae`_o}QQdWFJRa*I`R3-+k`2L_kc=6p$Mu1dy%=#HKpKjctR`iy?Y0F$9%$r& zF>hEK5Kw)Hx}-^_t4TJ&<48KBfu_Wdo0niFA`vL5@P>o!>q?ssRgPCRDUX-vIcP1A zP6+P(O$%0)Gs#+?!?Kga*z+X^Co1$AJ?LbarSS@*!3l!Zip?c$vP4Z9qNwdhT9kzq z0=jl&h(Xt>W}{qV)AD@m{F#weZ1k`r9a>>j@I<@yl?zyzs3I3WE*Ft{t(p<1v6G`h zGHPZWQ6X8vC>PI^Ie<(aM-%Zhl6(02#A}penrf)!`$avgE^50cQ)lVms2X&RMxPQg zS$z3S{Q&k$oFiqJ3Dhvt(dbmw^#I6Xt9Ld344pAsJB~W_Opv8hH>7iy+sp66Qo5yy zOE#fU!G-CPekBz<dqU|H@2bM)(o$RsMCz2p4+CIQN589HP~QFWFdIzmRjB8X+w7~u z9PUg{+{pvi@-1z2uRe2Y7pHtSH1^dSgolJ#^WX$IjOTAadtpf9DDYg4xgS!m_f+u) zYUEMlXK1?^s_3cUUc<e@mUd6|XOJsWPMkvdaiWd#FYYb{OPv#hy`5#$D1D%JP7Vv; zHp?S!(^=j-MbzlN<TWlRP>;TQRNGKTAAf`zj{%Q0yZnJREaDeqM~iRaegVJVLs_w@ ztt&w50{yy1SXfu=De$n06&%gOz?BbL6@Bvzc9j%*VTGug%-^8L#5^uOrsE^{|A)6F zV@O-7=xqHH;c=HgnVTJErz6%ybD$523y}5ziY;(cuz&|J(~%-|_54MsQr#Wb>%o)< zuGkU|?9rrJq&egotZKgigTxR%HHTbxx>Dj!o>k0)Qv5lpxDx0`?1^OB$gnW;YnKFh zLL!6Aq#}=OO}~2nO3ip}{rna2B(AF}%Svn2(}Flqq<0-RDqI=)3nBw%vtE?jw0sNJ zfAKlg5oahN;VR0&h77{bP`=2Fx=!}?Xl9(RGi*m0Fx-|CX>LE#As->J?nFff1@=8q z6UZujqwbSgCd$KnFUgfRya7bUU_cIzNWCu3(Fo2`ucdyYH{#-gWE|$kQHI&P_!X*> zha|-)E>>_^Eis>$Bv?44yHP2%SEB4?!W{I}jtZDzox6|ngTBm(RkWxT12KY^1Aq{f z5>9{d!hb+r|F@7Ri&?d-7V*vN6*aGA^%+jHYDJ$@@u$z}d5C9aJ&)hAR#db14Xtcw zxM!%^&&v!bdED3T=MBDxyIErnREpZ};!!|z@j`>NmC=VJ;6!dKqXc|S8G=`L)FEWH zjy5!Gb(m=pt`OQtG*}u!i|Ocl8Pv!!9_02_Rk`(4sM^{9XoAvwXxRD(;QPbeka0mH z8l>4kuK~LJZ=efW+XfJ5iV>g^Oz+K*#?+}awSB_3*`&t{!|d)Ul+PtSPEn1{Y?yss zd0V;ldkL2>(0KOd!_2t+9h5(VuR9kkbdHf8)+yMT4+xQ<OLZ2(=hx)OIj41w({G!` zyA+&|V}OG%XXiiAfrV#*h0C(<6VUeVYQq9)Y@H<=ecQ$3%6FAN(4JTBskfd;#!vV; zy?1id3Yb;IHQ^6ta6-W~>3bz$C)QuCY5g%!c&nuh%L$e1!zrHs6xQstU1Ajc@5!Cd zV67{|X;{Xm_e`dYdZ0|}`grPkIxOSKRl;dnWtGPHz2J$k%+KISuBUXKBrL0zt*?Pu zBx2oV>CkBJ!T_I~Qy4jMG*isy(U6G_*P}AwUl!LLagQU}E>FlOxin^)lY;3R6OKcI zk~9YbMQM<O+mKmOvSw8CC0UsAb~2M>CkNbVummwJxGJ0Db%k>!A=1A3XNp3u>>|u1 zj=Rw%&P!|@y!t8pT-$y8JZz@WxS<8XJGZ%-2CatYG@E`^i!zqqXtyH+8et>S`gJyS z014c7v-%V>d+|k3i;8a~z0?X=mpZv$eer8lmW68SxVHELT^Ljl6<Kqwv;UQ3RWNaK zv6Exg7hlE=@p(%AIg(oT%K3HdAMqU3%OK<V;@3IPKp16XzMSxFMv~f0?6jwe)SF$a zCHs&w6U5L2X`_+Rb1Wc<AJ|c@=aDhWj|wy}9*y{yRPkR>@;uef@Us#xB43@6vVJb! zm*NuDqSdHPkJp^LuH|}-x{pajS**=v`;MSVi)%=LJu<j}#u;h7fv8c@i<G=V$!}0{ znG!Qe9;Y0s%+q+H{taZ5S*em6;O}L15xjp!t!P;dh@h1<QYMP`ajlxf^TGL-fd_;E zMU>@%0EV%om(gYhZJ~G&l4!Wn<_Hzi>c>HVoqz^1i4^dq+4+B-Km!<(j<10)U;%86 z*f7+Q3(7t1-P$k*cBF?nFem`WKp|m1zRmy!^gS58i0J@S3hq);W`Ko`>g6D2tKzG+ zHY^4Cy}~{i;62s-i?G1-e%IEACA6k{{{>1*VXwHaY%AhV?F`lLfQ^z;gA`)`!`8Uw zhhWX4nm@52s&gw<{6zNBfe@c+Rf=0(x67ke0EDOPDej@1u8VvH{Y=BOK_mLCJ(Frt zvuC-*)ZrGmGlzEb9~i^3`}g)js@0EqOckhBJSMv`uLKnUV{(NY%?<aDgT0?57C%Kb z@SV1E<I-`9lU$RbAP;qHDy-~dUEDkNu~ff5qm{)9&dGK$okdy;cg;SY)YQbexaNGi zCi2NjxTo!<u<%{QJ`v{Z908)e{0Eugbg&Rk-&MaxJLcFu&9C8i@t!7ri|B<J?2R(* zjWCN`iE{>W1<KtrZ8bEuvB$*sG0)?nj@irvOM5568RTZ!D7x&P!uU^ynGcoWESJsh zow85vL+JyQFQZPDVeORlpVP2*Ucej&NF!}4CF?W)A}<o0UVV71VSc~`nB{hT!}8mH z9cDK_wmE@wC(N42T!GQ`3fn4Vq)UpIKN>uac@Cgu!p#CaF~|J*pgD(lW2&=<8EVM< zA!Tc3-{?z@H<=9e_L3P}QA`%0<0|ZYGF#RFzI@BAZ`p`Ei9>^^5q-um5aZ(n+1J>E z1;iVxS8~Zm4k1QlRs~WsT7%}{h+aEzqJkwh+R%c;j(8nBD#~{qNZGb<7#bPes+#y! zD#|d-0<U02gF@rAP+)NZ0ug#vlxZR8!~zAYHGuZwd`ys1)uRmCt?+}00Ee#H%^))1 zGq$2^$7*;R?T>Y;X#iWvn=CwBahJj&@;P+HeP*EZ!-=Db9#wF;4B-zOa0%@e$o|A} z1G^RWog@?Aog;73gsWz?Jp<!X^)U(81j&q2jK_k&gK<{;E6Oq45t2sPH4agdi;;U1 zfKLmNd4*?fyo~uUB8wJPHvC&6s1;uGTC!DCf+7J0m!p?zxwqx8qawUE1Lq<v&O)L* z>wGz=g=F-LG}zS2>FrS~^~nPpt8(gB#M|hsIwy6nS82S2xwSmJ$gJblDx4dEw_hvq zZtZXk4a2Rd^KePO<f$_t!=xDHX;0B+f~<q~{HVnyRn9?>@hzyG#s##hO&>S_2Vr>~ zZ8iv&-$O>3BNdDPv>5;@scu=V48@G@m9;$5JgyCO8ENsphWpD}1=pyjW`ABZD35mc zN!>HlXVf!L^eDH)wPv8+<qar&_w!mF^bNg8%AsC_f>$J!4lurZETz<q<*o_fCeS9u zo`L%fj6P8IRJM$1B=NI$rxQG%0F>jtzNLtp0ck}H<L|Bx4cP9pdpTQ!Hm2_DLn_nZ z#mY1_Kr017>R*Rfs|hXV)~fq=yNf6XR0ja=yJTT24K-Nao-&l6yz`wzGt2KyrE5qV zTu=#Rum29(OBUjT0^md1nc3I;??dOC?aYDogFXdb!m3xYF@|9t^iQWKLpY#*Wm)V= zAWHDC5hYmaE_@QLTR(j;ty@2Z?)Xzsg5?wQ{eDQAQPx^XL&$m@X*o97jRFnh(75hS ziibTK1SE<Gm}feIi8$*g`Xv%B`!MbwD>}b`5sK_z+?o`Qt|!AhlBg^;^&HX*nISW4 zUSqqHG&apk#`7ljt7K%P4Tvr!%-m=rM>(?1V-2LFeSr$kP{PKXN)m)Bc@eRdsNf(L zgTr8>sXD^a8e4TXH~CT+C#J||p=u#z`ynGvRFbR05`GO5e!Xqqslo6BYZG#C8z3R2 z$byl{32M{uuE0a-*dvpZNu)V>oN{E6`Vn!EmyuDXarz<7SHM3`Ls(w~4_U%Vuc#!{ z=kI69kORSfi3~jVvn=Y5?=Gtl-%q5@KMl%DY+VyPfV`Mw*CBNBPXo=qsghmi8){Rv zVWW93Khy(t59j-v%3T#@`j)Y;+B(Ead~yEOJp=X|<2bd$sR!4{d_zHNje?%hIvZrE zgna|g;nZfs9P9_&0yH4>+4-*%r93F*@XeFh4>63wrgPvOIp!U;pwKCzv;;xkunQ1p zHKJ-4A#}nsuvZQs*m5|v0xtph1jd2-ooO4~h(_1a?5Pi6J4ub^%dnTsB>j|$V}a5v zPH&m4AxoGq#AOv?ZYi8<Va|31!h7k~--e~mJZvRuXCbWcT@3=O3XwYQi&tSL)zi6Q z8MY*d+&m-hDdZHwr@D6x-uhYD1{Rh#<fv(O@tEg=Y_J%@_rh!V)-VTUYCc8%^PoP1 zsDL84Ayc)DC52`)TnOi32U{Sq82ua%=dmis(8qt|UgyGN-0K|f{9E(~5g8t!Y1oQ1 zQ4Z&Zi*6;Hvvrh!hlAQ;xCnkWW4)T@XRjpw)&@ld$6;L3DPThSg)B^=*Wd!eLm&z4 z7L*@LatRBPrkk`a<I$Mkgn1~TMy&5j9O5J?lNFvlgBv@DRd*1fnN)rl_k({HuK{!s zPzBE7{{l?#{Gp{u_1?g8CLcP5#K`9H_1BQ#S*w9UxMr)zmAe|Oiq8O-)jfF3_i!dV zMhIWtesU#qA<p4~vW)vsh~@%Pm~bKx`=QCGm1<7%OcMTJ3bBICsL(|C4ul*850EiK zGFy7<0>Z71B}CW@2NguB4O<eqJIA~WM*sStA9z^t8E_DvA}AE_DKbqjfKTmKQ@ki; zbYFd*c1+iQVKr$#mdGd8h1Q7HhSy~VnSl5WR^@~Oz66{V^d1SMW-{)uod|;@q3<Io zjdbh4fXi1CUE->BlE#cL#=Lv(VIxg9T>JPwK4J?kVRFL)^`Rdg8aIu79bccu79z`I z<<<L0jnq4G9ZeL9$B{(&=et&K!?s>{3S;^Q+);KZdTJC^apd}qnqbz1h!~B5-S5|o zuHWcYmw82EQyPN1p!l#CWQ?V3v4dBl-K(>y4L%nfSD3`0K8XOqdw!Gye%W{r28KNb zNI{z;GRT@4Wf2C8ic!Yt^@E*Aw>Et74vM9A!QgB7FgHfoZ9hO@o3!%{sYZnoQoX9j z<wN4f#n}EW+^rR$XZe2p0(M}&5g$SEd(?>SWH+gfaTP<WEm9BAPFr=T-iX1#ne8F` zux4Dts3Nr!sXpHDLB5u6yS8(ue*S8$%xxO-WY==>Rc($llVoJo0YZ>Kww7H-XK$Xb zO^s^G+m%UPAs_9(q0!Q#6)z+C8TNz!A~G=E>E+xhZ9ya1epx-OpHi3f1z`LW>H_qI z3Z(c75FXAQ=mG}rFG0G;T{wSGI_b7a?TU$Tn|bt;#h2loB4r@v!et}gg7~bFD9rA5 zgxiD&3V<v9Ig}eP`jgWJOrryL4aDW#FasN$bmUO^L<y`}e}$U)kysA#frM$Y)WLl+ zEP{oVAkG8!!Mqj$R;9gCnD3McW;<}sfJJ>3&{^76{C|%Y6;7wc4?-}kU<QB;+5oPp zR6aAJcTauyI#DEA!wSJMoJxNOCkw9Mhl}0T-zSGVl}@Am+&2`6HBb-UBZ@PC<SaYs zO|)cpy{OSUS}hI0JP&xEwTn<=X6*u}$S)}f7|`BVnHGsi<(SqSf)b|fDW>LvT7_LM zdwADtMD19b+5sxl36<Xfl^Le;Lr|GzDt`-`B!U`FK#1XSEq(%}xe+CZ1SGPM`o%&4 zgs!Ra_45kC0#nx~AnZUCO6o&>`OA>PtLCl$iT#>D<ux3A8DT^)9;*c=MG!d%vx0xZ zN}HSzMSVnIQ9=yrb}GOq1&NP_{MVuGJlH9IbkxxLNd01CT`~a29tTm$01D8iSI1KC zIFU$k8RE;tphs3c7+;<ysp9Ezxq1DZ=^z}+><kcqO?E-^dTNdj6FT4_zW(Xwmpq?z z_*t^xm&CJR1#5>8DnV8P(QhhyU=k!PNK92Dy<s=Sw^0OiA@hdhYRu5Si_3ovt|GpN z%<gAXFqN#+801GFC2UlVa$v7yToS)eBxwkY{qR1)?ABoO*QXjNuvG8&<v@|ovNPwM z17m$}G*+=e9X64Cs!qgzqGq%f;!h|sDM?o1{e*gl?zfTr5~+VUq7I}i5&f%_tW#2@ z<UA4zR@<)W&D%Dsyiz?ThtpWzOBn#!<wnN1v1%O^wh=S}IS^vNSE+<z5O|$<I@Ngz z(l627uTes>UZmD*25ndtE28}9>`C7k501uwS63k{u<5pzfnr>5*9>eeD9xk$;x3W= z0oBd3=IqzsspT-GI&DD{_aWl(7W^Sq<b|gYj90KUJ}rkbM=r3ux~!jqO^lsmu&tHV z1>h<IB4B%~K&#F}KZX{q&KV1^#Q{^HK`&?vxU;CzFI;IrSyO*P+g&(nOHU}!^e9My zrsem4f&_S{wb}P&tAD5hSq<P`h;Te8VPOVA0NLGh;I-P8F1`#8284NFQO;cmvmGta zp-$r(oY;VBn}hLcF*Z0QHDjYy4kowE^Pt(uz%++IaWZ-VgY)De143uQJgIj;*M$JS zHVR9?YtQg=p-vG94P*k||23!p*GQQ^l*4^eoasLBB9AZvMf_i&DYqd1h+R$s*!I;F zN?dBw+i?I0eqChZEfRj!g^I`)n_`EL#`1SQiRDka;mK+n`(*HH0m5-pojr{AA{v~% z97ke65>~|q<B6Ax`St0Wu_gcJIrAo2^yxQdb$BOQB+QubgkJLU+*Aaw-1L|wiPaNT z#|wnFp5S<(7iD1S!YkMEok)yXMtjk)(xXbvyJ`p@8&n==KG*?W@;y91RvYkIXoJ-U z(ee*5FB~(e%8-sqD(MMQXFen%CK74~g`vk6GT|diDDmG$+-vurrH&LH4X^ZJkN_=x z%h{3qhtQ$*op00UqhGITYin!Oe3Wa!8$p3(#HS)1q@;$UV^O2*7DBLr;H2TQBR`Ja ziqsvvCyyn<s{<S(&s+>I)6*@EUXWah^UP`@VpUczQZGa*REN>tI55X3Kbp$7i5HQ2 zrOX+S+9kIkcY9eQYuyYi_6zEaPMl`}w*Ml2%i2WT{D@M6rak%)iy;M)*$nwV;M&#$ z*w|UD{vr;w0qZ*~YY=r2X+;d?gtDdhU*tTF_m&~bwgEf7t|6v=UAa{bbqIJFYb$+p z`QHO1FDJ4+6xLd{+Tc8O+v7KCWk@}%f}h@M0}cRkv3xVR&toeoB&PU(3*hxZ{1*W_ zF7%NdqNyu`><=B3k++bTOdmc!ylDj0G;WtV3=d-h^cLqKe<}pPcJQEOz#DP_USXq% zcaz=)l;R%;mZti>Ha2lwf<W~?9wp2%WS>Bo2`vl1VAP^u#RluRQC0^1i0`1zfo&&# z8~1)hJC5{dW!8X=IFEfso}}HS)IpmtZ39H<0AH%=@)rR^Yjmor6?*Z5PC>mM73=hF z2%_VWFW2k0@V;+clB?HkuTigyCqRUa<Kiondx4U5O3qU9G9`r0;(t&=BTbFoq)X-w z6v<Ab=R*V6m`%rqpqtZwEIx+qdcXJ?PHz_1^PBn4=U*+pk$+ZD%W5ggz=Gf3kuuEh z5ZQf7$Z`)GeWTsqS%uL7#*7UANU;V>CL@8E$Wh~h9Y)Uo1v+-TzI2x9kK~B5{{H~X C=1mCz literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..076580dd7fa9e11559ef202903d44e00e25b8a26 GIT binary patch literal 20552 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af7431ce432969f095d1c07f429b8129cb5a2def GIT binary patch literal 8154 zcmdT}&yU;4mF90zYDumBVRzdznGo4YY$0lOw>{%zoyjC#x9#yHZVzH78+0<^P$XNT zOp)p$Wp_8IJ*+24c7Z+Yc@dy}oMR9mm;ER9OkjZkIRyR(a_}LY?-fN#YPT`TZI=Q| z#bVW~SFh^5@4d&cR;viOe)sCC`{a%w{E;4JFBuQt#~pnGg(EnkFYJl<mwag;@5!QY zPjF;M`CM?6=hB|yh>wJ(`VxJG-KLo8ju*vNV7oT8%w7fEAEMReH1{M&+>^_av&<=q zpr$(7=fa-qlpG!ZnzQ0moQ2QDy^>RPYG~2R_41;#>NK1sw3eMRX1|aw+&LWjA+usH z3@iaNRSaCWnQO(aV|1(tWf&N7&ov&67z?{-Hy(tJ>w7`hcpQd)Cp<K+KKk*4hfU*W z+n=^8oB(RZy^wiP<OVHcr`<Acha>yR=qPR(_wlsj4qP{iUDh%_p~s%(25!rE+%~Mh z!Svyv<Jt!;;|J{)r$<a(+uGi08@G(8;A4>UL4z#E8phsJ*NCjakaHJLxZ4kzVTXg^ z2=f)xvZXn0<aL9#@o_j}f#n<FzA>=uo)@@=?^-ONMKU)+)$X-7Zd-#6^PDa?ePBh= z3~$@pEn_%rU)y?rdjrM$ZE!gVzfVQm3u4!9kGgIUw>z$}Vf5m7cyn{}oR^vKZpAV4 zI^Z_q+-?*Xe|+G^7T*BlrV)1f#e$~oXm#zl&EEv34dHkWZQD%)tQ7rsN02e26;FF` z(YaAJbYPn{^B^-E4UCQAsqh}TK4zeH^l-B-ZR0TxiR12DBR@90$oTBaz}}$6vj|i+ zhAixF#Jww@VGn~42Wm<##KwWv`C~AE^Ze|M{4=aD92mn8lSNn~Kdor7P^G<hv7_0k zaA~=ix)4Il(1|uVawh_NwR#@cwlbrTRF`ny#vOePMIt7GDRc#tVj`iG5*elJP`ly? z&@^fHrGuVLH7yq#g{sB69?o5qF3fCHTAdYrDn4r}sS>&VKGQ&g=~R?ad?BzZ{$BlJ za}dOv_U4Zxh<cMf344CevZBqM&>jtN>Y~kiUi{Ihvw7DKpM7G*z0Hnw<VH^|-*Z@a zh=Vv$Y?CWgwCPT5LVI|W>ZS=H#isdH%odRi)Fe%$Uqw7#oiQNoyrV6mQ+}zakjS{W zet}9N^o6mQh<&jyjinf3dM=6r{-s3vFPO;R$dhN@o=A@JL}Fi0gcIe3@N;P_j}?el z*_R%H(usPut*Kf+$MnS(KkngN?T>=&yh00ISUWeGp8Cj$Lj#Hl3FA=1-dT|mxX*Bu z$u^KdDrn*8cnt5O(Dt~2oRO3f*&$5D!~l}P`jH#Ms$@z`&l5c^s9C;0)y@dV+hWW* zq9Yphtf6aMojDUNBQS>+vj$PK7*8~B89rcxk0G;{>n^>T;myo=o6HcMKgB%ZnQbjr zMpWra#mceD)&01=f#ci@9a7#|0YXx<3>X96tDTm960$G|y{5(wb6UncJ6zCdJ!9B4 zv%aZ1WKigIx$DN}(~x11Ik8V^o!X!zljo+&7I3aI^;kwNt<TFgU4C5{Tz9gfMnl$! z=3KW-pjYrRT1BB%by1fZxOJ&2>1y>ax^(;x;6KOD_8Tb7X~ShuD&gkZa1mx?q76b{ z9K&?<rM}!(#&RO}RY$xe;H(QL8rn;V{6fO%SI1hcpOm31(0~`>xYQNKdR&PY67@Os zWk>k*f5v6>uO?-Tt|S%Ekx*Mm790tB^if=MGX1JSi_nL3EzwWvN%;k82Ui_wT*Y0( zEQ`qkW~djn#ki6z@HyTeH_+Mug%amt2{SGwOGzbZT!MS!sQ)34m(gQ6Sq6obWF@I5 zjSmF;SD&ctUy_w^HECdum6O$cR9AGg7xH+Ok6L{pCW|!UU@sA!68QeDqhkf)8r-Tx zc}rNq|GKa$j4$Nvs9#JjBz63+C2PsWWN}sa7V5zkD3n3re;s|i?o^WXRUuh;OBi2@ zFJO*KPapx7#(MuExaZH{L~<6ef(mb~pJ`nSN=Y4bm3YmmJ{SL01jp;i+6&RC;aC5q z3<=Z{>6avRl42t%fpYDVknPvORXhvkB~DvS^lUD)T!suU;l50kt+{C3{adWqL<6Rt z8Z?FU%dlPFkGMC*jaFeaV5DHBh9R5+f<11tGPi>?`^!ug>|(BT|Bvj|OM)Xt#qr)_ z7^eNu2NLr2a~(H&F!>$V4UFiCHyo1V>)O^Ra>-X<uJMeDAe=(R#G8P8SvZ34>Ba4K z`|%fIT5>`&I$&{HwtH^pDC)USUoE}nQ2Ys;;QGV&7~$ee@+B}<u@1fH)fO@M;P%Gt z!u2`|NAN)pM&vJZI}7j0u%23;Z*_dPz5DVMSMx3I5@gN+cN3OCH5GrFsvJzx6>A6& z?9dwkx5%8*Az_5&sT2%T)g27uqf~_})pb+ZcZ0NU`(cDR&CIW2E7Vs56*q8F_1I-$ zlxj~Ave-}3b+a?_e8;2^#>5QFJIscq^1uriEihGWdYj5taFl9@AK*5o<y~vw-hubQ z(h^*uD1_t|X3iK}!^r04%(|1y!`GMUA?CWXWBxQ%aEu3O%_S1WsxH!WjU0{g^O`Pn zET?!-y})q~(@Np{MrkcDXQoaY1MAQP_k2+lm!<U%iK7^iF4Nn>!R7t3Hga{jE0MK{ zeRhLbs=Ff_E|+U%G_$^E+UjS<UU=qu-5!8xerVo&ruR}D#+ILLL#EoPYWc&Sm8uS{ z<qYOAf;B|4LX@D;YH;YJim1q%sGrs~MQlhFxgzVbE>_Vl;f(^9uY#w#q{tOfJFQ5- zL`4ztldGa~+5k4Li&aq<>%d6`HMHW^PN}~n>VMHxNdl$Qw^gF0oodQ5=pDav7Dwk1 zf7hlnlwTK6p)<}g^aOeht0@3ICGJte_3o38C_3UuV9R(?#%iF#-^`Fu<^8m=mS|{! zwH}uyeOvVA1lG9^5A%gYJ}T_89+yuli3%K>*2=)!3~j#&Os<T9tw1zFT@5Ie;a?5o zYDtX{6zHcX72sc;<KG_e1HDhO-h_IKyze4VuT1?8zMCi<_5M8phrm4GEXO=~U2t?D zTw~Hs^`)ed&_A#iSX$<&w+z%%IO_c#sE1TQvI5jofqJVkkUm-EsQ0_L++V~R`E!AK zB5&2tv@Qen^zkxKuaTi1m(3F96inQT&|k(HRtWFEg6N3a;1Qseqgl<W!qgQY^d_Ht z63M*=YWMuGgXsK0h-lKdZ81MANM+9A4ALRge;wgkQ-GW%DG2Z=Q8AZpFn(ycY+waZ z%ea$eBc{oT7Udwe+s2*!eb4p~SruFmsc2}~?#907^W+1iB!V#5uz@w!Fv?;~81W$X zu#!n^ftVWRxa%PtL7+NM%^Qq-o|f6jQWbf!1JjRKID{3M&00JhQdmPt93LQ_B`oIX zf%onAu3m5QJjIP~U*EX#k2kWwns}#c=i&XEJU0;`IpKs}J7nEWq+GVQwr_0q+ipK( zNN`~NTkp5Gu3wuv4fiSVpg<Gwly3(@s!7Ua;$z&L<7T^QyoQQ%9j=|z0ojA;q_<c% z3vP>H^Jx-V(R>h)J1i|D%QsklF_bz#%G`Yl26N7V{uAzLdtOg)?1q7hbjE$kIC#@I zkEq$moV5x!;TaAEg_wEt2?yhdQYFYUL1dK0LfQiPDI}jJ34y;OjGO_je2M1=c>kwj z$X)J_u}d)Hj~N9;>}@K(Ld82&kZZ&!<G>6mzJ{W?nuU1e+AxaqW_+Hn)8o4+(nc=j z9PAl61dQT1wm}`rZh)ghn#VS&af^y;R9vUxJt_#Wx%ZK30gS<D(7cd&A)FR>u+A{> zEgJD{DsEBnPbgB+gCm&d-_klfiU(e>Gs*L^9qLE$%kENfkBX0|xKG8$RQ!MnO7ctt zRYvIdTij6xh4!|NJPbe>(5(Yvb(wNA%Bcq6t^mLR*?@BZH9(vLHJ$*|@|$5A;0;jL zC8D!R(0utUG*1I>TLugHMIkr|hT5V(qk#1n5Xk~lCy^}G5EcC!CCnzRz%3QAu5=<3 zq5*S(%0Lt)RuT0oz(c_-{Yuyu2~$7UV?9wQ{(MgDWjrC~Ma0_zf(!i$Qg2#PLiD9M zB}8vJXe=Z;@R#D@62-cXv_@Q^4lEY><t#=<zbYa$K9*v%><v)(J&tRoMCFK9Lcbb~ zCIsf3)j2J}T+IIaJSWvGTmKE0q_8cwkV2Ze-p17d2QiyKtZ6)@<S0^~$oV|5VmS0y zBBO}l!U1r|nXv?ai_OcibCT;R*dU|y(03>)gN!a&>nRLn`7gvfJojajC1-g$l@h2E zj^=3b_;QA~FN+*4d{QWKTyvD>1T+x_S>8ep6v<ves09L3#G1G5H;XhF&!NrR;@5Iy zlq2Rz;n^vsq^FiC)iRG{E`vj!D4lZ(h$6CFl=%I$JQic&1fP3;&Ex$4lnyA07dfq_ zlv$sv=-iZ2slCM>qWXoH*$b}UJO@?zfU<c6KOf$}8H#AC%fj*XSq+>yOnJo9{=g4y zWRX8aB_BUAs+4?fHZrrxO(eIS^daf2RaCivS(9FUlM1qp2>4i+0*5v|$S`23g7agi z8V|Xm=0au_c_3MuoIO5US`Kpio9f72^5lG~P5x!iIZVs>7q4g<Y-S|Vl_7JVnr9+V zE~m%D8VQSi1I0Q?sfCKRM4?MvuET0oWrQG#f@iXOtFVI<YE%)@Ec4Xe@mIe@o<N8^ z+`4O%1oMlwoo*g@(EPOJi5QdllDZ;{f(&O~O%%46s7OyEg}1`9|JK{s%Hq`DwtSnM zJGgyx(2Ee#$OS_700%tRK^)gyt@rV1ENh<8y-z4HOrK$<=e}@;Hi}tu66fWaC-2_m zAy7^NG52}KW2!cMYjY2zn3e3#t(nXT?=>Bi`HL7e`+14R<S3bEjthd53=4*I@O|$M z&fGuukZ*<&gJokp3txy9$!}&v2P2$zXWDqyw<~5NRzAB6-GZYxbw0n$*ya0pzQN0v zHv6rBdpb>pr%Kp1P8PQqh~DXw0FvcAzx^|`BP~v<lxmse*jv>1Gb*@x@PexcsqZ6F z5BgqoagAbk<g4GEJ^F9T+Q4j)_tg}4VYzJ7?lvp*6)3<dGtIPO(ubmvPxY#4LYDsI zP02K!&^Aq0#~`*&#VQr#vT%LP9Ih#+Q+CN~AWkE4uyjEYrM1ebuIukqe7!4uM-uC& zjQZdUnhN)Ac$5jK7TMnLsEyc*;;Kx1)NMu@#T=>rLB{uo5Q`9zBJ0RnEX#idPQR4o literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93c4663b2cd6bd9acef73471231ba305bddf9dad GIT binary patch literal 12405 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98964152a4ea29f85f061ea6ec7daa3df7487230 GIT binary patch literal 8190 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 O{Slolq(+zPr9T4XZ>fI( literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16a383b994853cdb226f7b7fb291cdbef789e1f7 GIT binary patch literal 7185 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ce136ba4d826073719d19ffbbc87cff8dc02562 GIT binary patch literal 7952 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3f24cf9cb753b59f9e226f828a7c3598ac65a9a GIT binary patch literal 7232 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2310be6610a4c4824d6749297cdffe80c533a47 GIT binary patch literal 16785 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed2b0f6f101965fb42fe059ec79e8084a4b3a9bf GIT binary patch literal 2413 zcmc&$&2HO95GE<=$Exk5b`J%5Sp;rf0g2e4$i-+38*SqTXoVt4f!2mWued9jDYYx_ zE*;y*EqR6B+hbmdKu>*(o;ow6D5(mJ-ns_IoZZ>knc4Y1N^fj*Js9Ekr}DS9=lzAs z;%I<!0FPxLjy&NB|1CUkf@9PI(EzOhnlHlVUay&e)zSz+JAlXTfRG;8dB=h9j~gO5 z4n;$RZ@uHDXo?p6Z;3Ye=oHPTYMML#C+zJq7>6v$xV6k_CgdnplDTuqa+OHqc&b>6 z=4{FhpGYT-?RU#<&Y5(WJ84OMP!Cdn;AWgEo>{iX^zbFk;bF6RoRo>PefC^Rc1CB| z{%rNEPaB?TE7dUL&ViSq)>-Z5>4?E%z3L2CcBIXOyHrEOmKk}Gr$!0}vy_jJQ>lbh zuFR+Qw364iS9~(fma`)3S#XvmT(P07swEh=a7vcxSE(BBmBrcL-)B^2+vh^WlUX%B z?~$v8<=X4X7pHv%C1#J=?$7bV-CGSsYF+HEr(~V06m!3Q$2?Cs;N-!h`|Qza87tHh zF5E~go6;=NlL^#NaK~|mU-B&F!%W_%GM3Fii&YiI>7`T@?Eg>)3MZy;9+wwO3Wf6` z@c|UGf$xZxui>$GL5#iEUJO_R38(>N1cN8NpjfLfr0CB3@10+SR%WAjo@v3}zki7) z%0)@^lLbIT=2v~5opWxZZ*-DRpvi1>l)CToVe|yr;z#bzqanYR7HcVtzKU#aj2?3* z<B1kBvrz?r>2=YG<5Z<Cj_+ZlA&8dW^=~$*o%*xImE4d?D7P(mdF{RQe)nDQ#{0wf zAxF&a=7Oq%AUqTTE|w|z>fd-o5<v8q*IZ(>!aHt!CS7h+33${i%-4<wTFC|TL9b!3 z=0%H75q(8xR$PO5Q7KCS+~^e>OHla?rY!E>TD#dUlV4gN^x9Y}giIV4-54vGXZXGz z#}_%zs+D#e3!T99-Koy5<3!8R$i}0Lk4*=I_y7f7>Vm*<40a5LX_3M^Ug(FPbb|Ge z<`bA&8W`vSJoaM{%S4PM4rELOZqOJ12&}1QhpOU1K%GLe1qPw|+o?>_QJN5+S*8i1 ztfmoSHOZ6nIZczl8sz_pqls<ym<1kJ<M|yT2UQ2o{jnF&74UiBc?Jw>+1c*SRs3*g zw_@r!AKmH?&FG^6EZtvmiQQBAs}IKSM+Up<@V*CSB|M;HZH%;2tpt^@?Bd1a7_udu zS-V<HXW?w>{gPAm7&nGr*E<d`d72>^RsccbS<U0*w8~<li3@H^p)x7IcPpUAt|Cz1 zgBPMI_=!*w7RZ1otU)tjMPWBhx|d$F2=RK0wfbg??!2f)cb;U?u3~r}CJ7=(a5#aW z<(GdzM<33RTr<+3*EH*3X*N)7qPT;CK=wX-Ar!uZ$KoR5YkiyGG3W(^F;W&lNj``u SI$xDo-$#fNMQ%2>qJID($9<0g literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43d077e6552c249ec0d115a4d34f47de65e354cc GIT binary patch literal 2860 zcmc&$&2Jk;6rXjxjbobhD~L8UFhW&>p|z+`IYcy4MWIwGIkZJWsmo@(Gj=wtcioxY zwuySkp@$rLMG+E6oPw%K{4E6`5v|0Df526G>WTN>?v9ffMcf$2&olGhym|9JelNdF zPSzQW_QtR3`*Ftp#zi@*#bkFLCR?n+t~1G=FzIYp7<&%id@SXh3UI~_a2#2^%^I#> zisG+REOy_6$re*=$&qZSBAul%Sy`&eu_tWFl~tfeqzk8yWbTcqpC;ljxUtS*T;+Z! zjNwVlrRoHc;>n8QY2+)Nh#=wtiu1nEqNft2O|zaKOA;Nl(?l6sUbKUjUkTj}A`u!s z&*Szg?crtRK5i;MF-?A3DZWg1m}bdcZqk8Uu~AVw6iEVF+Ho9OH8(mOn3kJp5t&Y` zdm;&9u-I^|?x%rPlEW^&N2<Pxq>7UKJyz4myFPy;di`+!t4O*u&TwBuysZjvNiGcB z5{B`^AnMNN&RJMk;N)i06jFM<(i`tLNYx&;)q3}%d(8-3%&+jdZ@f!$hYHHTBwn)C zC+Rc_@a>167`_uOxO?&P1%CNnZY%f_0<IOhEsD7x_j=$%DH4G@;(-VQ(GJxGa$}wh z#4Nnf4IZe7jQt<{K<0R4&Xqi{v><ct_+@QiiC}$=!MCWBE_=*8+@~QOSXpVwpiU}_ zUo<M&gbhztA7<k-C#xD2b_^cjuOELl-}>4>Wwi8n@k+QNglS!i{j>+!W?I*S<jb_( zYKt{x(3eujk6NlovR2w_>p*sumzWfyA0%lK>p+AD<V~t|+!cxPda+cYX%z+2U(0Hq z7eqngdFxY@am{j#fMBM9Y_Od(Z*NwgPVLOR3qQv;;j@eH-sd2MCvwm&m~4T2R#Ak; z&(<~N4*n+YaJ3E7=XSXb^3UxV2Otg|x_+O+LXaaRWEPLq!-If;D1`8n=UEOC1>oSp zTPjI)lp_wV3(&EO7vo6n5npVKX|yssBKlbVS*?tx26Se5{PYA$Ozx}G^;5Yo_idiX zBj<o@u)#?-G5K`r&)V$owb`Fmepvl+^|xB%k6PnJ`KR9i!NtZn#s|yV^Rl{!(Mv;| zAN9QZsR#?sxaY~(hwbD2I9&7mSamwa>x81Kv7hK;K%OyDN!Dr%6cLP?xdvpzeg>5p zw>Dr%K4GWNzNk(Qsuh<Hm?gCd_k#f&CHV!Y+lQ|mWh8e`!`8tT1C0fm48*spr+_V{ zZCi;7j0Z%Cu#o^dQfN(I`9UY}39Ai{34XYRNJ4BS{FPw~qVQS(`%nFckaV6K=uuI3 zm>!6)#f3wC{0<}>v_6rB&>ak4o;&x*yL4`@=t4uRJyaixQA30d)ErTXiCO5g7h`V> z;gmJ+CM-tGgLV^ZtxP|TB)KpzkiFM&>;!bDRkimyd+w&P%JFiZ3$4YPJ#qDc2tow< zqV^C}N8fSxUh#@vOz?Kt6AF>Mm+!+G3&uAoqX>R&x=DoQGUwo5Bv_$54T5b<P#VO; z3Mf_t+v_exui<7@OoD8}#xJW6U7yv5uE@p<OAmqq72o=a5;H8aUWfZk0|+4NG$QN7 z&Y9U9VBbN2-I+N{KW`!L=q7v$G;sBCIHgY@If>*H5-RaGafX<Y7dX}u71YNtF&BaC zE$|aq;7HE9?%4qwCAlV4ve>BPXh9nH-}1WlX%0vWdKN^{=VlqmV9arxLG42aP-2w4 Z#JyKT#<$KH2aFgcFLCeHzc9$Ue*o51>5l*a literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0c91ff3182adb1245aa7f20656e8e94336a438c GIT binary patch literal 2474 zcmc&$&2HO95GM6w$!hGRO%DZnSp-I10g+lG@Wp5h8*UpIXoMn(fxxCgued9jF}b97 zmyRvu<~&9Z?J=*=Yu|!EPkoD?Iy0mwsS1qVy2g&Vf3rK^&iAeO+FHkfa{K!q;;`j7 ze_><3)S<Bl)i5y69N`G}J=ELUF}7-=4y`)0T+w*xbejRpS|~MW?LjpgV59@{oa35s zkL#j#+z@rqc<&rHMN_Q6{}s^!AMLz(sM5^xKVfZ$LD^?P#EoG#VM2~VC7C^!EK`Bh zmWPUkIGv?j^H^G`O}|qtvsQ=0%t}MeUR9|1oa=F@cx2cPONMW#4>z0kW2X$P>9dzo zvNPJl^rxd|eOmA$F;Wd9ZY_8jCP`GeIUF$<tVXTo%8U{na~mdbV#Bn&%t9>%gI<b9 z$W$sJl`Z0_JT1lb!!?i7XfZ09Jw2RZ0at7&OSA;z26l;}<ZY<NI|VqqySt2FHhnIH zA5YQvx=XI+hAXcp-=6jrK+K-9&DZ|c=A9EoXsmB<QktEq5M#f4#Vk(P;H0<xm~EdH zX9X<b!nH)$RKkKJjsZi#Eyo^y#iNi9Bl(zMERul+OBBZ8l~i=t{{aU&j!(yVT3jqO z=s2$e7f3NJ_>F8ifNCCq89VPBAGih<SOd(c4Swv_^401>^3E*(KDc?q$Y}Jz(JQd_ z?_Umfydwi-@U*;0wmgx=*>z!iF;GYYXcJ1t-biwrY1unG___D}(etC%Px{;5FbgBm z3u1mDJ)WkK7Y3;(!Sv#h2OQ*)mL`j=x!O91?75ISQ{Ir@NQ2iQbaL&POzULKt@PtW z$jEplhtiw8?fan$t?xg=U>jf@cg3BoQ%3fugG=zB7!f?5!N)u2jq|H(Yq!pCt_v_B zK$A-X7J0lc1mp%&^6kGVjXHt?Qe;X&^HMT!;R^|9s6sQaUCKt~c#tSLH+|5pYrM96 z1z-XK=k4kJXpD<)qc9+^PQJFlwy&Ve;A&@e@~{YgVSLbSAy&vb-_JWfBAG?_eb4tV zGai*AE#DVO0NoGLB)ai~M2<$rA4Pnu+u&S(f(G+q&fsx0CLJEr;Iy{e__9%JH>fv& zj)j89+=FVq0JEs%_zHlU(+i;SJ>j3jY(i{bl|l-%RjAe=L4>|ZWe|?SfO62VggDMB z9U@tjJUE}}Jo&3s;y;Nz$<+=s@DQl+>;_T9$_;1!*el2hcwabVHR{UQ=Ek+ZwXs=B z{Y=pA^oP^v)d89BFS*3rDg9L&;{z1Is_J+@L1XE7py`PQ%B6`C1YwcG^V>0$TiUa7 zH6PC0-jw-;DD5z=HNUA=>|gOPLNzVvfy%WU$H{3KMV!R&V%-@+Ii+|omne-{MU;L7 zAEb5g8>3J>ur<=aI`uS44V*OTUb@Y^f!CX_RyUJ(W}xPsS&(_FJj2HrNd$QYn;ZHe z1Ts|oO+KCSxYDCRx2f;JOudF?9nF0-M6r*t3q3x8N(u+;dPw9LbZf*gYRnOmJdjAV PzbkmYOVmV&*1!1&Ix?AS literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1e26394365e683dbec6da95fbe223ebcee10ef4 GIT binary patch literal 13488 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 Bp;Z6? literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ebbfad9c34b1f9e6c819ea7cf7852af65591444 GIT binary patch literal 42392 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 J{$pjC|2Gc|fYty2 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff5e3935b0dd191141f8dfb60bedbeb9a3441d01 GIT binary patch literal 87304 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 VVvQP|=-}`ZcKvS-xy!oPe*=NpfUp1n literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd6eb8fcd459fd95ff1b85514f996344b6e4880c GIT binary patch literal 42705 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 X0Qd@E+a(_g`Az8O{>jTCN=^RXpccWy literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..543416416ef052c2402c2e9a97976dc4aab22866 GIT binary patch literal 8915 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 StX4>a*409eT+%Xuv;M!r+lnOs literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2b6e8e274e98df5f28013ef45589d246125aff5 GIT binary patch literal 14832 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f1ec9479869fec42f363e7f46e07dba2f1c6be5 GIT binary patch literal 8930 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 H7PS8b3n7jV literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97ed55acc1e800a138ddf489ccea709a8b28f634 GIT binary patch literal 11629 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 avA&6Yk^<6Wno`U`AM%$xPx3uy*Z&u-bVhUl literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0784caa91ce5a8acf65a6e83b8f58a47f8e12bcb GIT binary patch literal 19787 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 M>^HBe!Eo^Z0iAV!9smFU literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0843cdf8bd820d9cccfdcde3a1193f3f416ccc10 GIT binary patch literal 11717 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 Zi*F}O^<C;cm`0%G$mvY}IHnd?{}%}UP3r&v literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30079dce4bc04802324f720381b872c1a2f64018 GIT binary patch literal 9509 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 X4&uxQi9kPt=A@8#$;cEg3d(;2)UokG literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..489534282f927e599530fd2c176b5240e2214e1d GIT binary patch literal 19040 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 RV>v$k20#DP38fgR{|_UFGxGod literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a3bbc05003eab405d52a934e83053ae50080d25 GIT binary patch literal 9581 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af35ff42f1ea1e8ee19d476f7b51c19199513cde GIT binary patch literal 87535 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 E|3L9E)c^nh literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b856dfef2c2658af8ecc6b1ab85b99c499a39705 GIT binary patch literal 35103 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 RfEonip2Lr$Q;xp){{<f=hrs{< literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d6f35b0e889d838247709ac2440fed2799abfce GIT binary patch literal 61708 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f44a774b4165e6ff769d8db2f2c13c4dd0cbe8b3 GIT binary patch literal 35188 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 X?l%ZtK(YD%eZCe!@XRZi#_|6P0+p{e literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/adaptPlot.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/adaptPlot.py new file mode 100644 index 000000000..102f0373c --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/adaptPlot.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 13 13:46:24 2020 + +@author: farid +""" +import os +from sklearn.metrics import mean_squared_error, r2_score +from itertools import cycle +from matplotlib.backends.backend_pdf import PdfPages +import matplotlib.pyplot as plt + + +def adaptPlot(PCEModel, Y_Val, Y_PC_Val, Y_PC_Val_std, x_values=[], + plotED=False, SaveFig=True): + + NrofSamples = PCEModel.ExpDesign.n_new_samples + initNSamples = PCEModel.ExpDesign.n_init_samples + itrNr = 1 + (PCEModel.ExpDesign.X.shape[0] - initNSamples)//NrofSamples + + oldEDY = PCEModel.ExpDesign.Y + + if SaveFig: + newpath = 'adaptivePlots' + os.makedirs(newpath, exist_ok=True) + + # create a PdfPages object + pdf = PdfPages(f'./{newpath}/Model_vs_PCEModel_itr_{itrNr}.pdf') + + # List of markers and colors + color = cycle((['b', 'g', 'r', 'y', 'k'])) + marker = cycle(('x', 'd', '+', 'o', '*')) + + OutNames = list(Y_Val.keys()) + x_axis = 'Time [s]' + + if len(OutNames) == 1: + OutNames.insert(0, x_axis) + try: + x_values = Y_Val['x_values'] + except KeyError: + x_values = x_values + + fig = plt.figure(figsize=(24, 16)) + + # Plot the model vs PCE model + for keyIdx, key in enumerate(PCEModel.ModelObj.Output.names): + Y_PC_Val_ = Y_PC_Val[key] + Y_PC_Val_std_ = Y_PC_Val_std[key] + Y_Val_ = Y_Val[key] + if Y_Val_.ndim == 1: + Y_Val_ = Y_Val_.reshape(1, -1) + old_EDY = oldEDY[key] + if isinstance(x_values, dict): + x = x_values[key] + else: + x = x_values + + for idx, y in enumerate(Y_Val_): + Color = next(color) + Marker = next(marker) + + plt.plot( + x, y, color=Color, marker=Marker, + lw=2.0, label='$Y_{%s}^{M}$'%(idx+itrNr) + ) + + plt.plot( + x, Y_PC_Val_[idx], color=Color, marker=Marker, + lw=2.0, linestyle='--', label='$Y_{%s}^{PCE}$'%(idx+itrNr) + ) + plt.fill_between( + x, Y_PC_Val_[idx]-1.96*Y_PC_Val_std_[idx], + Y_PC_Val_[idx]+1.96*Y_PC_Val_std_[idx], color=Color, + alpha=0.15 + ) + + if plotED: + for output in old_EDY: + plt.plot(x, output, color='grey', alpha=0.1) + + # Calculate the RMSE + RMSE = mean_squared_error(Y_PC_Val_, Y_Val_, squared=False) + R2 = r2_score(Y_PC_Val_.reshape(-1, 1), Y_Val_.reshape(-1, 1)) + + plt.ylabel(key) + plt.xlabel(x_axis) + plt.title(key) + + ax = fig.axes[0] + ax.legend(loc='best', frameon=True) + fig.canvas.draw() + ax.text(0.65, 0.85, + f'RMSE = {round(RMSE, 3)}\n$R^2$ = {round(R2, 3)}', + transform=ax.transAxes, color='black', + bbox=dict(facecolor='none', + edgecolor='black', + boxstyle='round,pad=1') + ) + plt.grid() + + if SaveFig: + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + pdf.close() diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/apoly_construction.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/apoly_construction.py new file mode 100644 index 000000000..40830fe8a --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/apoly_construction.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import numpy as np + + +def apoly_construction(Data, degree): + """ + Construction of Data-driven Orthonormal Polynomial Basis + Author: Dr.-Ing. habil. Sergey Oladyshkin + Department of Stochastic Simulation and Safety Research for Hydrosystems + Institute for Modelling Hydraulic and Environmental Systems + Universitaet Stuttgart, Pfaffenwaldring 5a, 70569 Stuttgart + E-mail: Sergey.Oladyshkin@iws.uni-stuttgart.de + http://www.iws-ls3.uni-stuttgart.de + The current script is based on definition of arbitrary polynomial chaos + expansion (aPC), which is presented in the following manuscript: + Oladyshkin, S. and W. Nowak. Data-driven uncertainty quantification using + the arbitrary polynomial chaos expansion. Reliability Engineering & System + Safety, Elsevier, V. 106, P. 179-190, 2012. + DOI: 10.1016/j.ress.2012.05.002. + + Parameters + ---------- + Data : array + Raw data. + degree : int + Maximum polynomial degree. + + Returns + ------- + Polynomial : array + The coefficients of the univariate orthonormal polynomials. + + """ + if Data.ndim !=1: + raise AttributeError('Data should be a 1D array') + + # Initialization + dd = degree + 1 + nsamples = len(Data) + + # Forward linear transformation (Avoiding numerical issues) + MeanOfData = np.mean(Data) + Data = Data/MeanOfData + + # Compute raw moments of input data + raw_moments = [np.sum(np.power(Data, p))/nsamples for p in range(2*dd+2)] + + # Main Loop for Polynomial with degree up to dd + PolyCoeff_NonNorm = np.empty((0, 1)) + Polynomial = np.zeros((dd+1, dd+1)) + + for degree in range(dd+1): + Mm = np.zeros((degree+1, degree+1)) + Vc = np.zeros((degree+1)) + + # Define Moments Matrix Mm + for i in range(degree+1): + for j in range(degree+1): + if (i < degree): + Mm[i, j] = raw_moments[i+j] + + elif (i == degree) and (j == degree): + Mm[i, j] = 1 + + # Numerical Optimization for Matrix Solver + Mm[i] = Mm[i] / max(abs(Mm[i])) + + # Defenition of Right Hand side ortogonality conditions: Vc + for i in range(degree+1): + Vc[i] = 1 if i == degree else 0 + + # Solution: Coefficients of Non-Normal Orthogonal Polynomial: Vp Eq.(4) + try: + Vp = np.linalg.solve(Mm, Vc) + except: + inv_Mm = np.linalg.pinv(Mm) + Vp = np.dot(inv_Mm, Vc.T) + + if degree == 0: + PolyCoeff_NonNorm = np.append(PolyCoeff_NonNorm, Vp) + + if degree != 0: + if degree == 1: + zero = [0] + else: + zero = np.zeros((degree, 1)) + PolyCoeff_NonNorm = np.hstack((PolyCoeff_NonNorm, zero)) + + PolyCoeff_NonNorm = np.vstack((PolyCoeff_NonNorm, Vp)) + + if 100*abs(sum(abs(np.dot(Mm, Vp)) - abs(Vc))) > 0.5: + print('\n---> Attention: Computational Error too high !') + print('\n---> Problem: Convergence of Linear Solver') + + # Original Numerical Normalization of Coefficients with Norm and + # orthonormal Basis computation Matrix Storrage + # Note: Polynomial(i,j) correspont to coefficient number "j-1" + # of polynomial degree "i-1" + P_norm = 0 + for i in range(nsamples): + Poly = 0 + for k in range(degree+1): + if degree == 0: + Poly += PolyCoeff_NonNorm[k] * (Data[i]**k) + else: + Poly += PolyCoeff_NonNorm[degree, k] * (Data[i]**k) + + P_norm += Poly**2 / nsamples + + P_norm = np.sqrt(P_norm) + + for k in range(degree+1): + if degree == 0: + Polynomial[degree, k] = PolyCoeff_NonNorm[k]/P_norm + else: + Polynomial[degree, k] = PolyCoeff_NonNorm[degree, k]/P_norm + + # Backward linear transformation to the real data space + Data *= MeanOfData + for k in range(len(Polynomial)): + Polynomial[:, k] = Polynomial[:, k] / (MeanOfData**(k)) + + return Polynomial diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/bayes_linear.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/bayes_linear.py new file mode 100644 index 000000000..3bd827ac0 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/bayes_linear.py @@ -0,0 +1,523 @@ +import numpy as np +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +from sklearn.utils import check_X_y, check_array, as_float_array +from sklearn.utils.validation import check_is_fitted +from scipy.linalg import svd +import warnings +from sklearn.preprocessing import normalize as f_normalize + + + +class BayesianLinearRegression(RegressorMixin,LinearModel): + ''' + Superclass for Empirical Bayes and Variational Bayes implementations of + Bayesian Linear Regression Model + ''' + def __init__(self, n_iter, tol, fit_intercept,copy_X, verbose): + self.n_iter = n_iter + self.fit_intercept = fit_intercept + self.copy_X = copy_X + self.verbose = verbose + self.tol = tol + + + def _check_convergence(self, mu, mu_old): + ''' + Checks convergence of algorithm using changes in mean of posterior + distribution of weights + ''' + return np.sum(abs(mu-mu_old)>self.tol) == 0 + + + def _center_data(self,X,y): + ''' Centers data''' + X = as_float_array(X,copy = self.copy_X) + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype = X.dtype) + if self.fit_intercept: + X_mean = np.average(X,axis = 0) + y_mean = np.average(y,axis = 0) + X -= X_mean + y = y - y_mean + else: + X_mean = np.zeros(X.shape[1],dtype = X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X,y, X_mean, y_mean, X_std + + + def predict_dist(self,X): + ''' + Calculates mean and variance of predictive distribution for each data + point of test set.(Note predictive distribution for each data point is + Gaussian, therefore it is uniquely determined by mean and variance) + + Parameters + ---------- + x: array-like of size (n_test_samples, n_features) + Set of features for which corresponding responses should be predicted + + Returns + ------- + :list of two numpy arrays [mu_pred, var_pred] + + mu_pred : numpy array of size (n_test_samples,) + Mean of predictive distribution + + var_pred: numpy array of size (n_test_samples,) + Variance of predictive distribution + ''' + # Note check_array and check_is_fitted are done within self._decision_function(X) + mu_pred = self._decision_function(X) + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + return [mu_pred,var_pred] + + + + +class EBLinearRegression(BayesianLinearRegression): + ''' + Bayesian Regression with type II maximum likelihood (Empirical Bayes) + + Parameters: + ----------- + n_iter: int, optional (DEFAULT = 300) + Maximum number of iterations + + tol: float, optional (DEFAULT = 1e-3) + Threshold for convergence + + optimizer: str, optional (DEFAULT = 'fp') + Method for optimization , either Expectation Maximization or + Fixed Point Gull-MacKay {'em','fp'}. Fixed point iterations are + faster, but can be numerically unstable (especially in case of near perfect fit). + + fit_intercept: bool, optional (DEFAULT = True) + If True includes bias term in model + + perfect_fit_tol: float (DEAFAULT = 1e-5) + Prevents overflow of precision parameters (this is smallest value RSS can have). + ( !!! Note if using EM instead of fixed-point, try smaller values + of perfect_fit_tol, for better estimates of variance of predictive distribution ) + + alpha: float (DEFAULT = 1) + Initial value of precision paramter for coefficients ( by default we define + very broad distribution ) + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied, otherwise will be + + verbose: bool, optional (Default = False) + If True at each iteration progress report is printed out + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + intercept_: float + Value of bias term (if fit_intercept is False, then intercept_ = 0) + + alpha_ : float + Estimated precision of coefficients + + beta_ : float + Estimated precision of noise + + eigvals_ : array, shape = (n_features, ) + Eigenvalues of covariance matrix (from posterior distribution of weights) + + eigvecs_ : array, shape = (n_features, n_featues) + Eigenvectors of covariance matrix (from posterior distribution of weights) + + ''' + + def __init__(self,n_iter = 300, tol = 1e-3, optimizer = 'fp', fit_intercept = True, + normalize=True, perfect_fit_tol = 1e-6, alpha = 1, copy_X = True, verbose = False): + super(EBLinearRegression,self).__init__(n_iter, tol, fit_intercept, copy_X, verbose) + if optimizer not in ['em','fp']: + raise ValueError('Optimizer can be either "em" or "fp" ') + self.optimizer = optimizer + self.alpha = alpha + self.perfect_fit = False + self.normalize = True + self.scores_ = [np.NINF] + self.perfect_fit_tol = perfect_fit_tol + + def _check_convergence(self, mu, mu_old): + ''' + Checks convergence of algorithm using changes in mean of posterior + distribution of weights + ''' + return np.sum(abs(mu-mu_old)>self.tol) == 0 + + + def _center_data(self,X,y): + ''' Centers data''' + X = as_float_array(X,copy = self.copy_X) + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype = X.dtype) + if self.fit_intercept: + X_mean = np.average(X, axis=0) + X -= X_mean + if self.normalize: + X, X_std = f_normalize(X, axis=0, copy=False, + return_norm=True) + else: + X_std = np.ones(X.shape[1], dtype=X.dtype) + y_mean = np.average(y, axis=0) + y = y - y_mean + else: + X_mean = np.zeros(X.shape[1],dtype = X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X,y, X_mean, y_mean, X_std + + def fit(self, X, y): + ''' + Fits Bayesian Linear Regression using Empirical Bayes + + Parameters + ---------- + X: array-like of size [n_samples,n_features] + Matrix of explanatory variables (should not include bias term) + + y: array-like of size [n_features] + Vector of dependent variables. + + Returns + ------- + object: self + self + + ''' + # preprocess data + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # precision of noise & and coefficients + alpha = self.alpha + var_y = np.var(y) + # check that variance is non zero !!! + if var_y == 0 : + beta = 1e-2 + else: + beta = 1. / np.var(y) + + # to speed all further computations save svd decomposition and reuse it later + u,d,vt = svd(X, full_matrices = False) + Uy = np.dot(u.T,y) + dsq = d**2 + mu = 0 + + for i in range(self.n_iter): + + # find mean for posterior of w ( for EM this is E-step) + mu_old = mu + if n_samples > n_features: + mu = vt.T * d/(dsq+alpha/beta) + else: + # clever use of SVD here , faster for large n_features + mu = u * 1./(dsq + alpha/beta) + mu = np.dot(X.T,mu) + mu = np.dot(mu,Uy) + + # precompute errors, since both methods use it in estimation + error = y - np.dot(X,mu) + sqdErr = np.sum(error**2) + + if sqdErr / n_samples < self.perfect_fit_tol: + self.perfect_fit = True + warnings.warn( ('Almost perfect fit!!! Estimated values of variance ' + 'for predictive distribution are computed using only RSS')) + break + + if self.optimizer == "fp": + gamma = np.sum(beta*dsq/(beta*dsq + alpha)) + # use updated mu and gamma parameters to update alpha and beta + # !!! made computation numerically stable for perfect fit case + alpha = gamma / (np.sum(mu**2) + np.finfo(np.float32).eps ) + beta = ( n_samples - gamma ) / (sqdErr + np.finfo(np.float32).eps ) + else: + # M-step, update parameters alpha and beta to maximize ML TYPE II + eigvals = 1. / (beta * dsq + alpha) + alpha = n_features / ( np.sum(mu**2) + np.sum(1/eigvals) ) + beta = n_samples / ( sqdErr + np.sum(dsq/eigvals) ) + + # if converged or exceeded maximum number of iterations => terminate + converged = self._check_convergence(mu_old,mu) + if self.verbose: + print( "Iteration {0} completed".format(i) ) + if converged is True: + print("Algorithm converged after {0} iterations".format(i)) + if converged or i==self.n_iter -1: + break + eigvals = 1./(beta * dsq + alpha) + self.coef_ = beta*np.dot(vt.T*d*eigvals ,Uy) + self._set_intercept(X_mean,y_mean,X_std) + self.beta_ = beta + self.alpha_ = alpha + self.eigvals_ = eigvals + self.eigvecs_ = vt.T + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self,X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of predictive + distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + ''' + y_hat = np.dot(X,self.coef_) + self.intercept_ + + if return_std: + if self.normalize: + X = (X - self._x_mean_) / self._x_std + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + std_hat = np.sqrt(var_pred) + return y_hat, std_hat + else: + return y_hat + + +# ============================== VBLR ========================================= + +def gamma_mean(a,b): + ''' + Computes mean of gamma distribution + + Parameters + ---------- + a: float + Shape parameter of Gamma distribution + + b: float + Rate parameter of Gamma distribution + + Returns + ------- + : float + Mean of Gamma distribution + ''' + return float(a) / b + + + +class VBLinearRegression(BayesianLinearRegression): + ''' + Implements Bayesian Linear Regression using mean-field approximation. + Assumes gamma prior on precision parameters of coefficients and noise. + + Parameters: + ----------- + n_iter: int, optional (DEFAULT = 100) + Maximum number of iterations for KL minimization + + tol: float, optional (DEFAULT = 1e-3) + Convergence threshold + + fit_intercept: bool, optional (DEFAULT = True) + If True will use bias term in model fitting + + a: float, optional (Default = 1e-4) + Shape parameter of Gamma prior for precision of coefficients + + b: float, optional (Default = 1e-4) + Rate parameter of Gamma prior for precision coefficients + + c: float, optional (Default = 1e-4) + Shape parameter of Gamma prior for precision of noise + + d: float, optional (Default = 1e-4) + Rate parameter of Gamma prior for precision of noise + + verbose: bool, optional (Default = False) + If True at each iteration progress report is printed out + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + intercept_: float + Value of bias term (if fit_intercept is False, then intercept_ = 0) + + alpha_ : float + Mean of precision of coefficients + + beta_ : float + Mean of precision of noise + + eigvals_ : array, shape = (n_features, ) + Eigenvalues of covariance matrix (from posterior distribution of weights) + + eigvecs_ : array, shape = (n_features, n_featues) + Eigenvectors of covariance matrix (from posterior distribution of weights) + + ''' + + def __init__(self, n_iter = 100, tol =1e-4, fit_intercept = True, + a = 1e-4, b = 1e-4, c = 1e-4, d = 1e-4, copy_X = True, + verbose = False): + super(VBLinearRegression,self).__init__(n_iter, tol, fit_intercept, copy_X, + verbose) + self.a,self.b = a, b + self.c,self.d = c, d + + + def fit(self,X,y): + ''' + Fits Variational Bayesian Linear Regression Model + + Parameters + ---------- + X: array-like of size [n_samples,n_features] + Matrix of explanatory variables (should not include bias term) + + Y: array-like of size [n_features] + Vector of dependent variables. + + Returns + ------- + object: self + self + ''' + # preprocess data + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # SVD decomposition, done once , reused at each iteration + u,D,vt = svd(X, full_matrices = False) + dsq = D**2 + UY = np.dot(u.T,y) + + # some parameters of Gamma distribution have closed form solution + a = self.a + 0.5 * n_features + c = self.c + 0.5 * n_samples + b,d = self.b, self.d + + # initial mean of posterior for coefficients + mu = 0 + + for i in range(self.n_iter): + + # update parameters of distribution Q(weights) + e_beta = gamma_mean(c,d) + e_alpha = gamma_mean(a,b) + mu_old = np.copy(mu) + mu,eigvals = self._posterior_weights(e_beta,e_alpha,UY,dsq,u,vt,D,X) + + # update parameters of distribution Q(precision of weights) + b = self.b + 0.5*( np.sum(mu**2) + np.sum(eigvals)) + + # update parameters of distribution Q(precision of likelihood) + sqderr = np.sum((y - np.dot(X,mu))**2) + xsx = np.sum(dsq*eigvals) + d = self.d + 0.5*(sqderr + xsx) + + # check convergence + converged = self._check_convergence(mu,mu_old) + if self.verbose is True: + print("Iteration {0} is completed".format(i)) + if converged is True: + print("Algorithm converged after {0} iterations".format(i)) + + # terminate if convergence or maximum number of iterations are achieved + if converged or i==(self.n_iter-1): + break + + # save necessary parameters + self.beta_ = gamma_mean(c,d) + self.alpha_ = gamma_mean(a,b) + self.coef_, self.eigvals_ = self._posterior_weights(self.beta_, self.alpha_, UY, + dsq, u, vt, D, X) + self._set_intercept(X_mean,y_mean,X_std) + self.eigvecs_ = vt.T + return self + + + def _posterior_weights(self, e_beta, e_alpha, UY, dsq, u, vt, d, X): + ''' + Calculates parameters of approximate posterior distribution + of weights + ''' + # eigenvalues of covariance matrix + sigma = 1./ (e_beta*dsq + e_alpha) + + # mean of approximate posterior distribution + n_samples, n_features = X.shape + if n_samples > n_features: + mu = vt.T * d/(dsq + e_alpha/e_beta)# + np.finfo(np.float64).eps) + else: + mu = u * 1./(dsq + e_alpha/e_beta)# + np.finfo(np.float64).eps) + mu = np.dot(X.T,mu) + mu = np.dot(mu,UY) + return mu,sigma + + def predict(self,X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of predictive + distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + ''' + x = (X - self._x_mean_) / self._x_std + y_hat = np.dot(x,self.coef_) + self._y_mean + + if return_std: + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + std_hat = np.sqrt(var_pred) + return y_hat, std_hat + else: + return y_hat \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/engine.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/engine.py new file mode 100644 index 000000000..7f5c1bf77 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/engine.py @@ -0,0 +1,2195 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Dec 16 10:16:50 2023 +Engine to train the surrogate with + +@author: Rebecca Kohlhaas +""" +import copy +from copy import deepcopy, copy +import h5py +import joblib +import numpy as np +import os + +from scipy import stats, signal, linalg, sparse +from scipy.spatial import distance +from tqdm import tqdm +import scipy.optimize as opt +from sklearn.metrics import mean_squared_error +import multiprocessing +import matplotlib.pyplot as plt +import sys +import seaborn as sns +from joblib import Parallel, delayed +from .exploration import Exploration +import pathlib + +#from .inputs import Input +#from .exp_designs import ExpDesigns +#from .surrogate_models import MetaModel +#from bayesvalidrox.post_processing.post_processing import PostProcessing + +def hellinger_distance(P, Q): + """ + Hellinger distance between two continuous distributions. + + The maximum distance 1 is achieved when P assigns probability zero to + every set to which Q assigns a positive probability, and vice versa. + 0 (identical) and 1 (maximally different) + + Parameters + ---------- + P : array + Reference likelihood. + Q : array + Estimated likelihood. + + Returns + ------- + float + Hellinger distance of two distributions. + + """ + P = np.array(P) + Q= np.array(Q) + + mu1 = P.mean() + Sigma1 = np.std(P) + + mu2 = Q.mean() + Sigma2 = np.std(Q) + + term1 = np.sqrt(2*Sigma1*Sigma2 / (Sigma1**2 + Sigma2**2)) + + term2 = np.exp(-.25 * (mu1 - mu2)**2 / (Sigma1**2 + Sigma2**2)) + + H_squared = 1 - term1 * term2 + + return np.sqrt(H_squared) + + +def logpdf(x, mean, cov): + """ + Computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = linalg.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(linalg.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + + return log_lik + +def subdomain(Bounds, n_new_samples): + """ + Divides a domain defined by Bounds into sub domains. + + Parameters + ---------- + Bounds : list of tuples + List of lower and upper bounds. + n_new_samples : int + Number of samples to divide the domain for. + n_params : int + The number of params to build the subdomains for + + Returns + ------- + Subdomains : List of tuples of tuples + Each tuple of tuples divides one set of bounds into n_new_samples parts. + + """ + n_params = len(Bounds) + n_subdomains = n_new_samples + 1 + LinSpace = np.zeros((n_params, n_subdomains)) + + for i in range(n_params): + LinSpace[i] = np.linspace(start=Bounds[i][0], stop=Bounds[i][1], + num=n_subdomains) + Subdomains = [] + for k in range(n_subdomains-1): + mylist = [] + for i in range(n_params): + mylist.append((LinSpace[i, k+0], LinSpace[i, k+1])) + Subdomains.append(tuple(mylist)) + + return Subdomains + +class Engine(): + + + def __init__(self, MetaMod, Model, ExpDes): + self.MetaModel = MetaMod + self.Model = Model + self.ExpDesign = ExpDes + self.parallel = False + + def start_engine(self) -> None: + """ + Do all the preparations that need to be run before the actual training + + Returns + ------- + None + + """ + self.out_names = self.Model.Output.names + self.MetaModel.out_names = self.out_names + + + def train_normal(self, parallel = False, verbose = False, save = False) -> None: + """ + Trains surrogate on static samples only. + Samples are taken from the experimental design and the specified + model is run on them. + Alternatively the samples can be read in from a provided hdf5 file. + + + Returns + ------- + None + + """ + + ExpDesign = self.ExpDesign + MetaModel = self.MetaModel + + # Read ExpDesign (training and targets) from the provided hdf5 + if ExpDesign.hdf5_file is not None: + # TODO: need to run 'generate_ED' as well after this or not? + ExpDesign.read_from_file(self.out_names) + else: + # Check if an old hdf5 file exists: if yes, rename it + hdf5file = f'ExpDesign_{self.Model.name}.hdf5' + if os.path.exists(hdf5file): + # os.rename(hdf5file, 'old_'+hdf5file) + file = pathlib.Path(hdf5file) + file.unlink() + + # Prepare X samples + # For training the surrogate use ExpDesign.X_tr, ExpDesign.X is for the model to run on + ExpDesign.generate_ED(ExpDesign.n_init_samples, + transform=True, + max_pce_deg=np.max(MetaModel.pce_deg)) + + # Run simulations at X + if not hasattr(ExpDesign, 'Y') or ExpDesign.Y is None: + print('\n Now the forward model needs to be run!\n') + ED_Y, up_ED_X = self.Model.run_model_parallel(ExpDesign.X, mp = parallel) + ExpDesign.Y = ED_Y + else: + # Check if a dict has been passed. + if not type(ExpDesign.Y) is dict: + raise Exception('Please provide either a dictionary or a hdf5' + 'file to ExpDesign.hdf5_file argument.') + + # Separate output dict and x-values + if 'x_values' in ExpDesign.Y: + ExpDesign.x_values = ExpDesign.Y['x_values'] + del ExpDesign.Y['x_values'] + else: + print('No x_values are given, this might lead to issues during PostProcessing') + + + # Fit the surrogate + MetaModel.fit(ExpDesign.X_tr, ExpDesign.Y, parallel, verbose) + + # Save what there is to save + if save: + # Save surrogate + with open(f'surrogates/surrogate_{self.Model.name}.pk1', 'wb') as output: + joblib.dump(MetaModel, output, 2) + + # Zip the model run directories + if self.Model.link_type.lower() == 'pylink' and\ + self.ExpDesign.sampling_method.lower() != 'user': + self.Model.zip_subdirs(self.Model.name, f'{self.Model.name}_') + + + def train_sequential(self, parallel = False, verbose = False) -> None: + """ + Train the surrogate in a sequential manner. + First build and train evereything on the static samples, then iterate + choosing more samples and refitting the surrogate on them. + + Returns + ------- + None + + """ + #self.train_normal(parallel, verbose) + self.parallel = parallel + self.train_seq_design(parallel, verbose) + + + # ------------------------------------------------------------------------- + def eval_metamodel(self, samples=None, nsamples=None, + sampling_method='random', return_samples=False): + """ + Evaluates meta-model at the requested samples. One can also generate + nsamples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate meta-model at. The default is None. + nsamples : int, optional + Number of samples to generate, if no `samples` is provided. The + default is None. + sampling_method : str, optional + Type of sampling, if no `samples` is provided. The default is + 'random'. + return_samples : bool, optional + Retun samples, if no `samples` is provided. The default is False. + + Returns + ------- + mean_pred : dict + Mean of the predictions. + std_pred : dict + Standard deviatioon of the predictions. + """ + # Generate or transform (if need be) samples + if samples is None: + # Generate + samples = self.ExpDesign.generate_samples( + nsamples, + sampling_method + ) + + # Transformation to other space is to be done in the MetaModel + # TODO: sort the transformations better + mean_pred, std_pred = self.MetaModel.eval_metamodel(samples) + + if return_samples: + return mean_pred, std_pred, samples + else: + return mean_pred, std_pred + + + # ------------------------------------------------------------------------- + def train_seq_design(self, parallel = False, verbose = False): + """ + Starts the adaptive sequential design for refining the surrogate model + by selecting training points in a sequential manner. + + Returns + ------- + MetaModel : object + Meta model object. + + """ + self.parallel = parallel + + # Initialization + self.SeqModifiedLOO = {} + self.seqValidError = {} + self.SeqBME = {} + self.SeqKLD = {} + self.SeqDistHellinger = {} + self.seqRMSEMean = {} + self.seqRMSEStd = {} + self.seqMinDist = [] + + if not hasattr(self.MetaModel, 'valid_samples'): + self.ExpDesign.valid_samples = [] + self.ExpDesign.valid_model_runs = [] + self.valid_likelihoods = [] + + validError = None + + + # Determine the metamodel type + if self.MetaModel.meta_model_type.lower() != 'gpe': + pce = True + else: + pce = False + mc_ref = True if bool(self.Model.mc_reference) else False + if mc_ref: + self.Model.read_observation('mc_ref') + + # Get the parameters + max_n_samples = self.ExpDesign.n_max_samples + mod_LOO_threshold = self.ExpDesign.mod_LOO_threshold + n_canddidate = self.ExpDesign.n_canddidate + post_snapshot = self.ExpDesign.post_snapshot + n_replication = self.ExpDesign.n_replication + util_func = self.ExpDesign.util_func + output_name = self.out_names + + # Handle if only one UtilityFunctions is provided + if not isinstance(util_func, list): + util_func = [self.ExpDesign.util_func] + + # Read observations or MCReference + # TODO: recheck the logic in this if statement + if (len(self.Model.observations) != 0 or self.Model.meas_file is not None) and hasattr(self.MetaModel, 'Discrepancy'): + self.observations = self.Model.read_observation() + obs_data = self.observations + else: + obs_data = [] + # TODO: TotalSigma2 not defined if not in this else??? + # TODO: no self.observations if in here + TotalSigma2 = {} + + # ---------- Initial self.MetaModel ---------- + self.train_normal(parallel = parallel, verbose=verbose) + + initMetaModel = deepcopy(self.MetaModel) + + # Validation error if validation set is provided. + if self.ExpDesign.valid_model_runs: + init_rmse, init_valid_error = self._validError(initMetaModel) + init_valid_error = list(init_valid_error.values()) + else: + init_rmse = None + + # Check if discrepancy is provided + if len(obs_data) != 0 and hasattr(self.MetaModel, 'Discrepancy'): + TotalSigma2 = self.MetaModel.Discrepancy.parameters + + # Calculate the initial BME + out = self._BME_Calculator( + obs_data, TotalSigma2, init_rmse) + init_BME, init_KLD, init_post, init_likes, init_dist_hellinger = out + print(f"\nInitial BME: {init_BME:.2f}") + print(f"Initial KLD: {init_KLD:.2f}") + + # Posterior snapshot (initial) + if post_snapshot: + parNames = self.ExpDesign.par_names + print('Posterior snapshot (initial) is being plotted...') + self.__posteriorPlot(init_post, parNames, 'SeqPosterior_init') + + # Check the convergence of the Mean & Std + if mc_ref and pce: + init_rmse_mean, init_rmse_std = self._error_Mean_Std() + print(f"Initial Mean and Std error: {init_rmse_mean:.2f}," + f" {init_rmse_std:.2f}") + + # Read the initial experimental design + Xinit = self.ExpDesign.X + init_n_samples = len(self.ExpDesign.X) + initYprev = self.ExpDesign.Y#initMetaModel.ModelOutputDict + #self.MetaModel.ModelOutputDict = self.ExpDesign.Y + initLCerror = initMetaModel.LCerror + n_itrs = max_n_samples - init_n_samples + + ## Get some initial statistics + # Read the initial ModifiedLOO + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = self.ExpDesign.Y[out_name] + Scores_all.append(list( + self.MetaModel.score_dict['b_1'][out_name].values())) + if self.MetaModel.dim_red_method.lower() == 'pca': + pca = self.MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + + Scores = [item for sublist in Scores_all for item in sublist] + weights = [item for sublist in varExpDesignY for item in sublist] + init_mod_LOO = [np.average([1-score for score in Scores], + weights=weights)] + + prevMetaModel_dict = {} + #prevExpDesign_dict = {} + # Can run sequential design multiple times for comparison + for repIdx in range(n_replication): + print(f'\n>>>> Replication: {repIdx+1}<<<<') + + # util_func: the function to use inside the type of exploitation + for util_f in util_func: + print(f'\n>>>> Utility Function: {util_f} <<<<') + # To avoid changes ub original aPCE object + self.ExpDesign.X = Xinit + self.ExpDesign.Y = initYprev + self.ExpDesign.LCerror = initLCerror + + # Set the experimental design + Xprev = Xinit + total_n_samples = init_n_samples + Yprev = initYprev + + Xfull = [] + Yfull = [] + + # Store the initial ModifiedLOO + if pce: + print("\nInitial ModifiedLOO:", init_mod_LOO) + SeqModifiedLOO = np.array(init_mod_LOO) + + if len(self.ExpDesign.valid_model_runs) != 0: + SeqValidError = np.array(init_valid_error) + + # Check if data is provided + if len(obs_data) != 0 and hasattr(self.MetaModel, 'Discrepancy'): + SeqBME = np.array([init_BME]) + SeqKLD = np.array([init_KLD]) + SeqDistHellinger = np.array([init_dist_hellinger]) + + if mc_ref and pce: + seqRMSEMean = np.array([init_rmse_mean]) + seqRMSEStd = np.array([init_rmse_std]) + + # ------- Start Sequential Experimental Design ------- + postcnt = 1 + for itr_no in range(1, n_itrs+1): + print(f'\n>>>> Iteration number {itr_no} <<<<') + + # Save the metamodel prediction before updating + prevMetaModel_dict[itr_no] = deepcopy(self.MetaModel) + #prevExpDesign_dict[itr_no] = deepcopy(self.ExpDesign) + if itr_no > 1: + pc_model = prevMetaModel_dict[itr_no-1] + self._y_hat_prev, _ = pc_model.eval_metamodel( + samples=Xfull[-1].reshape(1, -1)) + del prevMetaModel_dict[itr_no-1] + + # Optimal Bayesian Design + #self.MetaModel.ExpDesignFlag = 'sequential' + Xnew, updatedPrior = self.choose_next_sample(TotalSigma2, + n_canddidate, + util_f) + S = np.min(distance.cdist(Xinit, Xnew, 'euclidean')) + self.seqMinDist.append(S) + print(f"\nmin Dist from OldExpDesign: {S:2f}") + print("\n") + + # Evaluate the full model response at the new sample + Ynew, _ = self.Model.run_model_parallel( + Xnew, prevRun_No=total_n_samples + ) + total_n_samples += Xnew.shape[0] + + # ------ Plot the surrogate model vs Origninal Model ------ + if hasattr(self.ExpDesign, 'adapt_verbose') and \ + self.ExpDesign.adapt_verbose: + from .adaptPlot import adaptPlot + y_hat, std_hat = self.MetaModel.eval_metamodel( + samples=Xnew + ) + adaptPlot( + self.MetaModel, Ynew, y_hat, std_hat, + plotED=False + ) + + # -------- Retrain the surrogate model ------- + # Extend new experimental design + Xfull = np.vstack((Xprev, Xnew)) + + # Updating experimental design Y + for out_name in output_name: + Yfull = np.vstack((Yprev[out_name], Ynew[out_name])) + self.ExpDesign.Y[out_name] = Yfull + + # Pass new design to the metamodel object + self.ExpDesign.sampling_method = 'user' + self.ExpDesign.X = Xfull + #self.ExpDesign.Y = self.MetaModel.ModelOutputDict + + # Save the Experimental Design for next iteration + Xprev = Xfull + Yprev = self.ExpDesign.Y + + # Pass the new prior as the input + # TODO: another look at this - no difference apc to pce to gpe? + self.MetaModel.input_obj.poly_coeffs_flag = False + if updatedPrior is not None: + self.MetaModel.input_obj.poly_coeffs_flag = True + print("updatedPrior:", updatedPrior.shape) + # Arbitrary polynomial chaos + for i in range(updatedPrior.shape[1]): + self.MetaModel.input_obj.Marginals[i].dist_type = None + x = updatedPrior[:, i] + self.MetaModel.input_obj.Marginals[i].raw_data = x + + # Train the surrogate model for new ExpDesign + self.train_normal(parallel=False) + + # -------- Evaluate the retrained surrogate model ------- + # Extract Modified LOO from Output + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = self.ExpDesign.Y[out_name] + Scores_all.append(list( + self.MetaModel.score_dict['b_1'][out_name].values())) + if self.MetaModel.dim_red_method.lower() == 'pca': + pca = self.MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, + axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + Scores = [item for sublist in Scores_all for item + in sublist] + weights = [item for sublist in varExpDesignY for item + in sublist] + ModifiedLOO = [np.average( + [1-score for score in Scores], weights=weights)] + + print('\n') + print(f"Updated ModifiedLOO {util_f}:\n", ModifiedLOO) + print('\n') + + # Compute the validation error + if self.ExpDesign.valid_model_runs: + rmse, validError = self._validError(self.MetaModel) + ValidError = list(validError.values()) + else: + rmse = None + + # Store updated ModifiedLOO + if pce: + SeqModifiedLOO = np.vstack( + (SeqModifiedLOO, ModifiedLOO)) + if len(self.ExpDesign.valid_model_runs) != 0: + SeqValidError = np.vstack( + (SeqValidError, ValidError)) + # -------- Caclulation of BME as accuracy metric ------- + # Check if data is provided + if len(obs_data) != 0: + # Calculate the initial BME + out = self._BME_Calculator(obs_data, TotalSigma2, rmse) + BME, KLD, Posterior, likes, DistHellinger = out + print('\n') + print(f"Updated BME: {BME:.2f}") + print(f"Updated KLD: {KLD:.2f}") + print('\n') + + # Plot some snapshots of the posterior + step_snapshot = self.ExpDesign.step_snapshot + if post_snapshot and postcnt % step_snapshot == 0: + parNames = self.ExpDesign.par_names + print('Posterior snapshot is being plotted...') + self.__posteriorPlot(Posterior, parNames, + f'SeqPosterior_{postcnt}') + postcnt += 1 + + # Check the convergence of the Mean&Std + if mc_ref and pce: + print('\n') + RMSE_Mean, RMSE_std = self._error_Mean_Std() + print(f"Updated Mean and Std error: {RMSE_Mean:.2f}, " + f"{RMSE_std:.2f}") + print('\n') + + # Store the updated BME & KLD + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.vstack((SeqBME, BME)) + SeqKLD = np.vstack((SeqKLD, KLD)) + SeqDistHellinger = np.vstack((SeqDistHellinger, + DistHellinger)) + if mc_ref and pce: + seqRMSEMean = np.vstack((seqRMSEMean, RMSE_Mean)) + seqRMSEStd = np.vstack((seqRMSEStd, RMSE_std)) + + if pce and any(LOO < mod_LOO_threshold + for LOO in ModifiedLOO): + break + + # Clean up + if len(obs_data) != 0: + del out + print() + print('-'*50) + print() + + # Store updated ModifiedLOO and BME in dictonary + strKey = f'{util_f}_rep_{repIdx+1}' + if pce: + self.SeqModifiedLOO[strKey] = SeqModifiedLOO + if len(self.ExpDesign.valid_model_runs) != 0: + self.seqValidError[strKey] = SeqValidError + + # Check if data is provided + if len(obs_data) != 0: + self.SeqBME[strKey] = SeqBME + self.SeqKLD[strKey] = SeqKLD + if hasattr(self.MetaModel, 'valid_likelihoods') and \ + self.valid_likelihoods: + self.SeqDistHellinger[strKey] = SeqDistHellinger + if mc_ref and pce: + self.seqRMSEMean[strKey] = seqRMSEMean + self.seqRMSEStd[strKey] = seqRMSEStd + + # return self.MetaModel + + # ------------------------------------------------------------------------- + def util_VarBasedDesign(self, X_can, index, util_func='Entropy'): + """ + Computes the exploitation scores based on: + active learning MacKay(ALM) and active learning Cohn (ALC) + Paper: Sequential Design with Mutual Information for Computer + Experiments (MICE): Emulation of a Tsunami Model by Beck and Guillas + (2016) + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + index : int + Model output index. + UtilMethod : string, optional + Exploitation utility function. The default is 'Entropy'. + + Returns + ------- + float + Score. + + """ + MetaModel = self.MetaModel + ED_X = self.ExpDesign.X + out_dict_y = self.ExpDesign.Y + out_names = self.out_names + + # Run the Metamodel for the candidate + X_can = X_can.reshape(1, -1) + Y_PC_can, std_PC_can = MetaModel.eval_metamodel(samples=X_can) + + if util_func.lower() == 'alm': + # ----- Entropy/MMSE/active learning MacKay(ALM) ----- + # Compute perdiction variance of the old model + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + varPCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + varPCE[KeyIdx] = np.max(canPredVar[key], axis=1) + score = np.max(varPCE, axis=0) + + elif util_func.lower() == 'eigf': + # ----- Expected Improvement for Global fit ----- + # Find closest EDX to the candidate + distances = distance.cdist(ED_X, X_can, 'euclidean') + index = np.argmin(distances) + + # Compute perdiction error and variance of the old model + predError = {key: Y_PC_can[key] for key in out_names} + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + # Compute perdiction error and variance of the old model + # Eq (5) from Liu et al.(2018) + EIGF_PCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + residual = predError[key] - out_dict_y[key][int(index)] + var = canPredVar[key] + EIGF_PCE[KeyIdx] = np.max(residual**2 + var, axis=1) + score = np.max(EIGF_PCE, axis=0) + + return -1 * score # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianActiveDesign(self, y_hat, std, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian active design criterion (var). + + It is based on the following paper: + Oladyshkin, Sergey, Farid Mohammadi, Ilja Kroeker, and Wolfgang Nowak. + "Bayesian3 active learning for the gaussian process emulator using + information theory." Entropy 22, no. 8 (2020): 890. + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + BAL design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # Get the data + obs_data = self.observations + # TODO: this should be optimizable to be calculated explicitly + if hasattr(self.Model, 'n_obs'): + n_obs = self.Model.n_obs + else: + n_obs = self.n_obs + mc_size = 10000 + + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + Y_MC, std_MC = {}, {} + logPriorLikelihoods = np.zeros((mc_size)) + # print(y_hat) + # print(list[y_hat]) + for key in list(y_hat): + cov = np.diag(std[key]**2) + # print(y_hat[key], cov) + # TODO: added the allow_singular = True here + rv = stats.multivariate_normal(mean=y_hat[key], cov=cov,) + Y_MC[key] = rv.rvs(size=mc_size) + logPriorLikelihoods += rv.logpdf(Y_MC[key]) + std_MC[key] = np.zeros((mc_size, y_hat[key].shape[0])) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self._normpdf(Y_MC, std_MC, obs_data, sigma2Dict) + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, mc_size)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods), dtype=np.longdouble)#float128) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + # Utility function Eq.2 in Ref. (2) + # Posterior covariance matrix after observing data y + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # TODO: Calculate the correction factor for BME + # BMECorrFactor = self.BME_Corr_Weight(PCE_SparseBayes_can, + # ObservationData, sigma2Dict) + # BME += BMECorrFactor + # Haun et al implementation + # U_J_d = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + U_J_d = postExpLikelihoods - logBME + + # Marginal log likelihood + elif var == 'BME': + U_J_d = np.nanmean(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + logBME = np.log(np.nanmean(likelihoods)) + infEntropy = logBME - postExpPrior - postExpLikelihoods + U_J_d = infEntropy * -1 # -1 for minimization + + # Bayesian information criterion + elif var == 'BIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxL = np.nanmax(likelihoods) + U_J_d = -2 * np.log(maxL) + np.log(n_obs) * nModelParams + + # Akaike information criterion + elif var == 'AIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxlogL = np.log(np.nanmax(likelihoods)) + AIC = -2 * maxlogL + 2 * nModelParams + # 2 * nModelParams * (nModelParams+1) / (n_obs-nModelParams-1) + penTerm = 0 + U_J_d = 1*(AIC + penTerm) + + # Deviance information criterion + elif var == 'DIC': + # D_theta_bar = np.mean(-2 * Likelihoods) + N_star_p = 0.5 * np.var(np.log(likelihoods[likelihoods != 0])) + Likelihoods_theta_mean = self._normpdf( + y_hat, std, obs_data, sigma2Dict + ) + DIC = -2 * np.log(Likelihoods_theta_mean) + 2 * N_star_p + + U_J_d = DIC + + else: + print('The algorithm you requested has not been implemented yet!') + + # Handle inf and NaN (replace by zero) + if np.isnan(U_J_d) or U_J_d == -np.inf or U_J_d == np.inf: + U_J_d = 0.0 + + # Clear memory + del likelihoods + del Y_MC + del std_MC + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianDesign(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + MetaModel = self.MetaModel + out_names = self.out_names + if X_can.ndim == 1: + X_can = X_can.reshape(1, -1) + + # Compute the mean and std based on the MetaModel + # pce_means, pce_stds = self._compute_pce_moments(MetaModel) + if var == 'ALC': + Y_MC, Y_MC_std = MetaModel.eval_metamodel(samples=X_MC) + + # Old Experimental design + oldExpDesignX = self.ExpDesign.X + oldExpDesignY = self.ExpDesign.Y + + # Evaluate the PCE metamodels at that location ??? + Y_PC_can, Y_std_can = MetaModel.eval_metamodel(samples=X_can) + PCE_Model_can = deepcopy(MetaModel) + engine_can = deepcopy(self) + # Add the candidate to the ExpDesign + NewExpDesignX = np.vstack((oldExpDesignX, X_can)) + + NewExpDesignY = {} + for key in oldExpDesignY.keys(): + NewExpDesignY[key] = np.vstack( + (oldExpDesignY[key], Y_PC_can[key]) + ) + + engine_can.ExpDesign.sampling_method = 'user' + engine_can.ExpDesign.X = NewExpDesignX + #engine_can.ModelOutputDict = NewExpDesignY + engine_can.ExpDesign.Y = NewExpDesignY + + # Train the model for the observed data using x_can + engine_can.MetaModel.input_obj.poly_coeffs_flag = False + engine_can.start_engine() + engine_can.train_normal(parallel=False) + engine_can.MetaModel.fit(NewExpDesignX, NewExpDesignY) +# engine_can.train_norm_design(parallel=False) + + # Set the ExpDesign to its original values + engine_can.ExpDesign.X = oldExpDesignX + engine_can.ModelOutputDict = oldExpDesignY + engine_can.ExpDesign.Y = oldExpDesignY + + if var.lower() == 'mi': + # Mutual information based on Krause et al + # Adapted from Beck & Guillas (MICE) paper + _, std_PC_can = engine_can.MetaModel.eval_metamodel(samples=X_can) + std_can = {key: std_PC_can[key] for key in out_names} + + std_old = {key: Y_std_can[key] for key in out_names} + + varPCE = np.zeros((len(out_names))) + for i, key in enumerate(out_names): + varPCE[i] = np.mean(std_old[key]**2/std_can[key]**2) + score = np.mean(varPCE) + + return -1 * score + + elif var.lower() == 'alc': + # Active learning based on Gramyc and Lee + # Adaptive design and analysis of supercomputer experiments Techno- + # metrics, 51 (2009), pp. 130–145. + + # Evaluate the MetaModel at the given samples + Y_MC_can, Y_MC_std_can = engine_can.MetaModel.eval_metamodel(samples=X_MC) + + # Compute the score + score = [] + for i, key in enumerate(out_names): + pce_var = Y_MC_std_can[key]**2 + pce_var_can = Y_MC_std[key]**2 + score.append(np.mean(pce_var-pce_var_can, axis=0)) + score = np.mean(score) + + return -1 * score + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = X_MC.shape[0] + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Enriching Monte Carlo samples if need be + if ESS != 0: + X_MC = self.ExpDesign.generate_samples( + MCsize, 'random' + ) + + # Evaluate the MetaModel at the given samples + Y_MC, std_MC = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self._normpdf( + Y_MC, std_MC, self.observations, sigma2Dict + ) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.sum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + print("--- increasing MC size---") + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # -------------------- Utility functions -------------------- + # Utility function Eq.2 in Ref. (2) + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods, dtype=np.longdouble))#float128)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Haun et al implementation + U_J_d = np.mean(np.log(likelihoods[likelihoods != 0]) - logBME) + + # U_J_d = np.sum(G_n_m_all) + # Ryan et al (2014) implementation + # importanceWeights = Likelihoods[Likelihoods!=0]/np.sum(Likelihoods[Likelihoods!=0]) + # U_J_d = np.mean(importanceWeights*np.log(Likelihoods[Likelihoods!=0])) - logBME + + # U_J_d = postExpLikelihoods - logBME + + # Marginal likelihood + elif var == 'BME': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + U_J_d = logBME + + # Bayes risk likelihood + elif var == 'BayesRisk': + + U_J_d = -1 * np.var(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postLikelihoods /= np.nansum(likelihoods[accepted]) + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + infEntropy = logBME - postExpPrior - postExpLikelihoods + + U_J_d = infEntropy * -1 # -1 for minimization + + # D-Posterior-precision + elif var == 'DPP': + X_Posterior = X_MC[accepted] + # covariance of the posterior parameters + U_J_d = -np.log(np.linalg.det(np.cov(X_Posterior))) + + # A-Posterior-precision + elif var == 'APP': + X_Posterior = X_MC[accepted] + # trace of the posterior parameters + U_J_d = -np.log(np.trace(np.cov(X_Posterior))) + + else: + print('The algorithm you requested has not been implemented yet!') + + # Clear memory + del likelihoods + del Y_MC + del std_MC + + return -1 * U_J_d # -1 is for minimization instead of maximization + + + # ------------------------------------------------------------------------- + def run_util_func(self, method, candidates, index, sigma2Dict=None, + var=None, X_MC=None): + """ + Runs the utility function based on the given method. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + candidates : array of shape (n_samples, n_params) + All candidate parameter sets. + index : int + ExpDesign index. + sigma2Dict : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + var : string, optional + Utility function. The default is None. + X_MC : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + index : TYPE + DESCRIPTION. + List + Scores. + + """ + + if method.lower() == 'varoptdesign': + # U_J_d = self.util_VarBasedDesign(candidates, index, var) + U_J_d = np.zeros((candidates.shape[0])) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="varoptdesign"): + U_J_d[idx] = self.util_VarBasedDesign(X_can, index, var) + + elif method.lower() == 'bayesactdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + # Evaluate all candidates + y_can, std_can = self.MetaModel.eval_metamodel(samples=candidates) + # loop through candidates + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="BAL Design"): + y_hat = {key: items[idx] for key, items in y_can.items()} + std = {key: items[idx] for key, items in std_can.items()} + + # print(y_hat) + # print(std) + U_J_d[idx] = self.util_BayesianActiveDesign( + y_hat, std, sigma2Dict, var) + + elif method.lower() == 'bayesoptdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianDesign(X_can, X_MC, sigma2Dict, + var) + return (index, -1 * U_J_d) + + # ------------------------------------------------------------------------- + def dual_annealing(self, method, Bounds, sigma2Dict, var, Run_No, + verbose=False): + """ + Exploration algorithm to find the optimum parameter space. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + Bounds : list of tuples + List of lower and upper boundaries of parameters. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + Run_No : int + Run number. + verbose : bool, optional + Print out a summary. The default is False. + + Returns + ------- + Run_No : int + Run number. + array + Optimial candidate. + + """ + + Model = self.Model + max_func_itr = self.ExpDesign.max_func_itr + + if method == 'VarOptDesign': + Res_Global = opt.dual_annealing(self.util_VarBasedDesign, + bounds=Bounds, + args=(Model, var), + maxfun=max_func_itr) + + elif method == 'BayesOptDesign': + Res_Global = opt.dual_annealing(self.util_BayesianDesign, + bounds=Bounds, + args=(Model, sigma2Dict, var), + maxfun=max_func_itr) + + if verbose: + print(f"Global minimum: xmin = {Res_Global.x}, " + f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}") + + return (Run_No, Res_Global.x) + + # ------------------------------------------------------------------------- + def tradeoff_weights(self, tradeoff_scheme, old_EDX, old_EDY): + """ + Calculates weights for exploration scores based on the requested + scheme: `None`, `equal`, `epsilon-decreasing` and `adaptive`. + + `None`: No exploration. + `equal`: Same weights for exploration and exploitation scores. + `epsilon-decreasing`: Start with more exploration and increase the + influence of exploitation along the way with a exponential decay + function + `adaptive`: An adaptive method based on: + Liu, Haitao, Jianfei Cai, and Yew-Soon Ong. "An adaptive sampling + approach for Kriging metamodeling by maximizing expected prediction + error." Computers & Chemical Engineering 106 (2017): 171-182. + + Parameters + ---------- + tradeoff_scheme : string + Trade-off scheme for exloration and exploitation scores. + old_EDX : array (n_samples, n_params) + Old experimental design (training points). + old_EDY : dict + Old model responses (targets). + + Returns + ------- + exploration_weight : float + Exploration weight. + exploitation_weight: float + Exploitation weight. + + """ + if tradeoff_scheme is None: + exploration_weight = 0 + + elif tradeoff_scheme == 'equal': + exploration_weight = 0.5 + + elif tradeoff_scheme == 'epsilon-decreasing': + # epsilon-decreasing scheme + # Start with more exploration and increase the influence of + # exploitation along the way with a exponential decay function + initNSamples = self.ExpDesign.n_init_samples + n_max_samples = self.ExpDesign.n_max_samples + + itrNumber = (self.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.ExpDesign.n_new_samples + + tau2 = -(n_max_samples-initNSamples-1) / np.log(1e-8) + exploration_weight = signal.exponential(n_max_samples-initNSamples, + 0, tau2, False)[itrNumber] + + elif tradeoff_scheme == 'adaptive': + + # Extract itrNumber + initNSamples = self.ExpDesign.n_init_samples + n_max_samples = self.ExpDesign.n_max_samples + itrNumber = (self.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.ExpDesign.n_new_samples + + if itrNumber == 0: + exploration_weight = 0.5 + else: + # New adaptive trade-off according to Liu et al. (2017) + # Mean squared error for last design point + last_EDX = old_EDX[-1].reshape(1, -1) + lastPCEY, _ = self.MetaModel.eval_metamodel(samples=last_EDX) + pce_y = np.array(list(lastPCEY.values()))[:, 0] + y = np.array(list(old_EDY.values()))[:, -1, :] + mseError = mean_squared_error(pce_y, y) + + # Mean squared CV - error for last design point + pce_y_prev = np.array(list(self._y_hat_prev.values()))[:, 0] + mseCVError = mean_squared_error(pce_y_prev, y) + + exploration_weight = min([0.5*mseError/mseCVError, 1]) + + # Exploitation weight + exploitation_weight = 1 - exploration_weight + + return exploration_weight, exploitation_weight + + # ------------------------------------------------------------------------- + def choose_next_sample(self, sigma2=None, n_candidates=5, var='DKL'): + """ + Runs optimal sequential design. + + Parameters + ---------- + sigma2 : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + n_candidates : int, optional + Number of candidate samples. The default is 5. + var : string, optional + Utility function. The default is None. # TODO: default is set to DKL, not none + + Raises + ------ + NameError + Wrong utility function. + + Returns + ------- + Xnew : array (n_samples, n_params) + Selected new training point(s). + """ + + # Initialization + Bounds = self.ExpDesign.bound_tuples + n_new_samples = self.ExpDesign.n_new_samples + explore_method = self.ExpDesign.explore_method + exploit_method = self.ExpDesign.exploit_method + n_cand_groups = self.ExpDesign.n_cand_groups + tradeoff_scheme = self.ExpDesign.tradeoff_scheme + + old_EDX = self.ExpDesign.X + old_EDY = self.ExpDesign.Y.copy() + ndim = self.ExpDesign.X.shape[1] + OutputNames = self.out_names + + # ----------------------------------------- + # ----------- CUSTOMIZED METHODS ---------- + # ----------------------------------------- + # Utility function exploit_method provided by user + if exploit_method.lower() == 'user': + if not hasattr(self.ExpDesign, 'ExploitFunction'): + raise AttributeError('Function `ExploitFunction` not given to the ExpDesign, thus cannor run user-defined sequential scheme') + # TODO: syntax does not fully match the rest - can test this?? + Xnew, filteredSamples = self.ExpDesign.ExploitFunction(self) + + print("\n") + print("\nXnew:\n", Xnew) + + return Xnew, filteredSamples + + + # Dual-Annealing works differently from the rest, so deal with this first + # Here exploration and exploitation are performed simulataneously + if explore_method == 'dual annealing': + # ------- EXPLORATION: OPTIMIZATION ------- + import time + start_time = time.time() + + # Divide the domain to subdomains + subdomains = subdomain(Bounds, n_new_samples) + + # Multiprocessing + if self.parallel: + args = [] + for i in range(n_new_samples): + args.append((exploit_method, subdomains[i], sigma2, var, i)) + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + + # With Pool.starmap_async() + results = pool.starmap_async(self.dual_annealing, args).get() + + # Close the pool + pool.close() + # Without multiprocessing + else: + results = [] + for i in range(n_new_samples): + results.append(self.dual_annealing(exploit_method, subdomains[i], sigma2, var, i)) + + # New sample + Xnew = np.array([results[i][1] for i in range(n_new_samples)]) + print("\nXnew:\n", Xnew) + + # Computational cost + elapsed_time = time.time() - start_time + print("\n") + print(f"Elapsed_time: {round(elapsed_time,2)} sec.") + print('-'*20) + + return Xnew, None + + # Generate needed Exploration class + explore = Exploration(self.ExpDesign, n_candidates) + explore.w = 100 # * ndim #500 # TODO: where does this value come from? + + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + + # Generate the candidate samples + # TODO: here use the sampling method provided by the expdesign? + sampling_method = self.ExpDesign.sampling_method + + # TODO: changed this from 'random' for LOOCV + if explore_method == 'LOOCV': + allCandidates = self.ExpDesign.generate_samples(n_candidates, + sampling_method) + else: + allCandidates, scoreExploration = explore.get_exploration_samples() + + # ----------------------------------------- + # ---------- EXPLORATION METHODS ---------- + # ----------------------------------------- + if explore_method == 'LOOCV': + # ----------------------------------------------------------------- + # TODO: LOOCV model construnction based on Feng et al. (2020) + # 'LOOCV': + # Initilize the ExploitScore array + + # Generate random samples + allCandidates = self.ExpDesign.generate_samples(n_candidates, + 'random') + + # Construct error model based on LCerror + errorModel = self.MetaModel.create_ModelError(old_EDX, self.LCerror) + self.errorModel.append(copy(errorModel)) + + # Evaluate the error models for allCandidates + eLCAllCands, _ = errorModel.eval_errormodel(allCandidates) + # Select the maximum as the representative error + eLCAllCands = np.dstack(eLCAllCands.values()) + eLCAllCandidates = np.max(eLCAllCands, axis=1)[:, 0] + + # Normalize the error w.r.t the maximum error + scoreExploration = eLCAllCandidates / np.sum(eLCAllCandidates) + + else: + # ------- EXPLORATION: SPACE-FILLING DESIGN ------- + # Generate candidate samples from Exploration class + explore = Exploration(self.ExpDesign, n_candidates) + explore.w = 100 # * ndim #500 + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + allCandidates, scoreExploration = explore.get_exploration_samples() + + # Temp: ---- Plot all candidates ----- + if ndim == 2: + def plotter(points, allCandidates, Method, + scoreExploration=None): + if Method == 'Voronoi': + from scipy.spatial import Voronoi, voronoi_plot_2d + vor = Voronoi(points) + fig = voronoi_plot_2d(vor) + ax1 = fig.axes[0] + else: + fig = plt.figure() + ax1 = fig.add_subplot(111) + ax1.scatter(points[:, 0], points[:, 1], s=10, c='r', + marker="s", label='Old Design Points') + ax1.scatter(allCandidates[:, 0], allCandidates[:, 1], s=10, + c='b', marker="o", label='Design candidates') + for i in range(points.shape[0]): + txt = 'p'+str(i+1) + ax1.annotate(txt, (points[i, 0], points[i, 1])) + if scoreExploration is not None: + for i in range(allCandidates.shape[0]): + txt = str(round(scoreExploration[i], 5)) + ax1.annotate(txt, (allCandidates[i, 0], + allCandidates[i, 1])) + + plt.xlim(self.bound_tuples[0]) + plt.ylim(self.bound_tuples[1]) + # plt.show() + plt.legend(loc='upper left') + + # ----------------------------------------- + # --------- EXPLOITATION METHODS ---------- + # ----------------------------------------- + if exploit_method == 'BayesOptDesign' or\ + exploit_method == 'BayesActDesign': + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradeoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\n Exploration weight={explore_w:0.3f} " + f"Exploitation weight={exploit_w:0.3f}\n") + + # ------- EXPLOITATION: BayesOptDesign & ActiveLearning ------- + if explore_w != 1.0: + # Check if all needed properties are set + if not hasattr(self.ExpDesign, 'max_func_itr'): + raise AttributeError('max_func_itr not given to the experimental design') + + # Create a sample pool for rejection sampling + MCsize = 15000 + X_MC = self.ExpDesign.generate_samples(MCsize, 'random') + candidates = self.ExpDesign.generate_samples( + n_candidates, 'latin_hypercube') + + # Split the candidates in groups for multiprocessing + split_cand = np.array_split( + candidates, n_cand_groups, axis=0 + ) + # print(candidates) + # print(split_cand) + if self.parallel: + results = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.run_util_func)( + exploit_method, split_cand[i], i, sigma2, var, X_MC) + for i in range(n_cand_groups)) + else: + results = [] + for i in range(n_cand_groups): + results.append(self.run_util_func(exploit_method, split_cand[i], i, sigma2, var, X_MC)) + + # Retrieve the results and append them + U_J_d = np.concatenate([results[NofE][1] for NofE in + range(n_cand_groups)]) + + # Check if all scores are inf + if np.isinf(U_J_d).all() or np.isnan(U_J_d).all(): + U_J_d = np.ones(len(U_J_d)) + + # Get the expected value (mean) of the Utility score + # for each cell + if explore_method == 'Voronoi': + U_J_d = np.mean(U_J_d.reshape(-1, n_candidates), axis=1) + + # Normalize U_J_d + norm_U_J_d = U_J_d / np.sum(U_J_d) + else: + norm_U_J_d = np.zeros((len(scoreExploration))) + + # ------- Calculate Total score ------- + # ------- Trade off between EXPLORATION & EXPLOITATION ------- + # Total score + totalScore = exploit_w * norm_U_J_d + totalScore += explore_w * scoreExploration + + # temp: Plot + # dim = self.ExpDesign.X.shape[1] + # if dim == 2: + # plotter(self.ExpDesign.X, allCandidates, explore_method) + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + # select the requested number of samples + if explore_method == 'Voronoi': + Xnew = np.zeros((n_new_samples, ndim)) + for i, idx in enumerate(bestIdx): + X_can = explore.closestPoints[idx] + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + else: + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + elif exploit_method == 'VarOptDesign': + # ------- EXPLOITATION: VarOptDesign ------- + UtilMethod = var + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradeoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\nweightExploration={explore_w:0.3f} " + f"weightExploitation={exploit_w:0.3f}") + + # Generate candidate samples from Exploration class + nMeasurement = old_EDY[OutputNames[0]].shape[1] + + # print(UtilMethod) + + # Find sensitive region + if UtilMethod == 'LOOCV': + LCerror = self.MetaModel.LCerror + allModifiedLOO = np.zeros((len(old_EDX), len(OutputNames), + nMeasurement)) + for y_idx, y_key in enumerate(OutputNames): + for idx, key in enumerate(LCerror[y_key].keys()): + allModifiedLOO[:, y_idx, idx] = abs( + LCerror[y_key][key]) + + ExploitScore = np.max(np.max(allModifiedLOO, axis=1), axis=1) + # print(allModifiedLOO.shape) + + elif UtilMethod in ['EIGF', 'ALM']: + # ----- All other in ['EIGF', 'ALM'] ----- + # Initilize the ExploitScore array + ExploitScore = np.zeros((len(old_EDX), len(OutputNames))) + + # Split the candidates in groups for multiprocessing + if explore_method != 'Voronoi': + split_cand = np.array_split(allCandidates, + n_cand_groups, + axis=0) + goodSampleIdx = range(n_cand_groups) + else: + # Find indices of the Vornoi cells with samples + goodSampleIdx = [] + for idx in range(len(explore.closest_points)): + if len(explore.closest_points[idx]) != 0: + goodSampleIdx.append(idx) + split_cand = explore.closest_points + + # Split the candidates in groups for multiprocessing + args = [] + for index in goodSampleIdx: + args.append((exploit_method, split_cand[index], index, + sigma2, var)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + # With Pool.starmap_async() + results = pool.starmap_async(self.run_util_func, args).get() + + # Close the pool + pool.close() + + # Retrieve the results and append them + if explore_method == 'Voronoi': + ExploitScore = [np.mean(results[k][1]) for k in + range(len(goodSampleIdx))] + else: + ExploitScore = np.concatenate( + [results[k][1] for k in range(len(goodSampleIdx))]) + + else: + raise NameError('The requested utility function is not ' + 'available.') + + # print("ExploitScore:\n", ExploitScore) + + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + # Total score + # Normalize U_J_d + ExploitScore = ExploitScore / np.sum(ExploitScore) + totalScore = exploit_w * ExploitScore + # print(totalScore.shape) + # print(explore_w) + # print(scoreExploration.shape) + totalScore += explore_w * scoreExploration + + temp = totalScore.copy() + sorted_idxtotalScore = np.argsort(temp, axis=0)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + Xnew = np.zeros((n_new_samples, ndim)) + if explore_method != 'Voronoi': + Xnew = allCandidates[bestIdx] + else: + for i, idx in enumerate(bestIdx.flatten()): + X_can = explore.closest_points[idx] + # plotter(self.ExpDesign.X, X_can, explore_method, + # scoreExploration=None) + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + + elif exploit_method == 'alphabetic': + # ------- EXPLOITATION: ALPHABETIC ------- + Xnew = self.util_AlphOptDesign(allCandidates, var) + + elif exploit_method == 'Space-filling': + # ------- EXPLOITATION: SPACE-FILLING ------- + totalScore = scoreExploration + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + + # select the requested number of samples + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + else: + raise NameError('The requested design method is not available.') + + print("\n") + print("\nRun No. {}:".format(old_EDX.shape[0]+1)) + print("Xnew:\n", Xnew) + + # TODO: why does it also return None? + return Xnew, None + + # ------------------------------------------------------------------------- + def util_AlphOptDesign(self, candidates, var='D-Opt'): + """ + Enriches the Experimental design with the requested alphabetic + criterion based on exploring the space with number of sampling points. + + Ref: Hadigol, M., & Doostan, A. (2018). Least squares polynomial chaos + expansion: A review of sampling strategies., Computer Methods in + Applied Mechanics and Engineering, 332, 382-407. + + Arguments + --------- + NCandidate : int + Number of candidate points to be searched + + var : string + Alphabetic optimality criterion + + Returns + ------- + X_new : array of shape (1, n_params) + The new sampling location in the input space. + """ + MetaModelOrig = self # TODO: this doesn't fully seem correct? + n_new_samples = MetaModelOrig.ExpDesign.n_new_samples + NCandidate = candidates.shape[0] + + # TODO: Loop over outputs + OutputName = self.out_names[0] + + # To avoid changes ub original aPCE object + MetaModel = deepcopy(MetaModelOrig) + + # Old Experimental design + oldExpDesignX = self.ExpDesign.X + + # TODO: Only one psi can be selected. + # Suggestion: Go for the one with the highest LOO error + # TODO: this is just a patch, need to look at again! + Scores = list(self.MetaModel.score_dict['b_1'][OutputName].values()) + #print(Scores) + #print(self.MetaModel.score_dict) + #print(self.MetaModel.score_dict.values()) + #print(self.MetaModel.score_dict['b_1'].values()) + #print(self.MetaModel.score_dict['b_1'][OutputName].values()) + ModifiedLOO = [1-score for score in Scores] + outIdx = np.argmax(ModifiedLOO) + + # Initialize Phi to save the criterion's values + Phi = np.zeros((NCandidate)) + + # TODO: also patched here + BasisIndices = self.MetaModel.basis_dict['b_1'][OutputName]["y_"+str(outIdx+1)] + P = len(BasisIndices) + + # ------ Old Psi ------------ + univ_p_val = self.MetaModel.univ_basis_vals(oldExpDesignX) + Psi = self.MetaModel.create_psi(BasisIndices, univ_p_val) + + # ------ New candidates (Psi_c) ------------ + # Assemble Psi_c + univ_p_val_c = self.MetaModel.univ_basis_vals(candidates) + Psi_c = self.MetaModel.create_psi(BasisIndices, univ_p_val_c) + + for idx in range(NCandidate): + + # Include the new row to the original Psi + Psi_cand = np.vstack((Psi, Psi_c[idx])) + + # Information matrix + PsiTPsi = np.dot(Psi_cand.T, Psi_cand) + M = PsiTPsi / (len(oldExpDesignX)+1) + + if np.linalg.cond(PsiTPsi) > 1e-12 \ + and np.linalg.cond(PsiTPsi) < 1 / sys.float_info.epsilon: + # faster + invM = linalg.solve(M, sparse.eye(PsiTPsi.shape[0]).toarray()) + else: + # stabler + invM = np.linalg.pinv(M) + + # ---------- Calculate optimality criterion ---------- + # Optimality criteria according to Section 4.5.1 in Ref. + + # D-Opt + if var.lower() == 'd-opt': + Phi[idx] = (np.linalg.det(invM)) ** (1/P) + + # A-Opt + elif var.lower() == 'a-opt': + Phi[idx] = np.trace(invM) + + # K-Opt + elif var.lower() == 'k-opt': + Phi[idx] = np.linalg.cond(M) + + else: + # print(var.lower()) + raise Exception('The optimality criterion you requested has ' + 'not been implemented yet!') + + # find an optimal point subset to add to the initial design + # by minimization of the Phi + sorted_idxtotalScore = np.argsort(Phi) + + # select the requested number of samples + Xnew = candidates[sorted_idxtotalScore[:n_new_samples]] + + return Xnew + + # ------------------------------------------------------------------------- + def _normpdf(self, y_hat_pce, std_pce, obs_data, total_sigma2s, + rmse=None): + """ + Calculated gaussian likelihood for given y+std based on given obs+sigma + # TODO: is this understanding correct? + + Parameters + ---------- + y_hat_pce : dict of 2d np arrays + Mean output of the surrogate. + std_pce : dict of 2d np arrays + Standard deviation output of the surrogate. + obs_data : dict of 1d np arrays + Observed data. + total_sigma2s : pandas dataframe, matches obs_data + Estimated uncertainty for the observed data. + rmse : dict, optional + RMSE values from validation of the surrogate. The default is None. + + Returns + ------- + likelihoods : dict of float + The likelihood for each surrogate eval in y_hat_pce compared to the + observations (?). + + """ + + likelihoods = 1.0 + + # Loop over the outputs + for idx, out in enumerate(self.out_names): + + # (Meta)Model Output + # print(y_hat_pce[out]) + nsamples, nout = y_hat_pce[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout].values + + # Surrogate error if valid dataset is given. + if rmse is not None: + tot_sigma2s += rmse[out]**2 + else: + tot_sigma2s += np.mean(std_pce[out])**2 + + likelihoods *= stats.multivariate_normal.pdf( + y_hat_pce[out], data, np.diag(tot_sigma2s), + allow_singular=True) + + # TODO: remove this here + self.Likelihoods = likelihoods + + return likelihoods + + # ------------------------------------------------------------------------- + def _corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = self.ExpDesign.X # valid_samples + model_outputs = self.ExpDesign.Y # valid_model_runs + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = self.out_names + + # TODO: Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + # covMatrix = np.diag(stdOutputRS[out][i]**2) + covMatrix = np.diag((y_m-y_m_hat)**2) + covMatrix = np.diag( + np.mean((model_outputs[out]-OutputRS[out]), axis=0)**2 + ) + + # Compute likelilhood output vs data + logLik_data[i] += logpdf( + y_m_hat, data, covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += logpdf(y_m_hat, y_m, covMatrix) + + # Weight + logLik_data -= logBME + weights = np.exp(logLik_model+logLik_data) + + return np.log(np.mean(weights)) + + # ------------------------------------------------------------------------- + def _posteriorPlot(self, posterior, par_names, key): + """ + Plot the posterior of a specific key as a corner plot + + Parameters + ---------- + posterior : 2d np.array + Samples of the posterior. + par_names : list of strings + List of the parameter names. + key : string + Output key that this posterior belongs to. + + Returns + ------- + figPosterior : corner.corner + Plot of the posterior. + + """ + + # Initialization + newpath = (r'Outputs_SeqPosteriorComparison/posterior') + os.makedirs(newpath, exist_ok=True) + + bound_tuples = self.ExpDesign.bound_tuples + n_params = len(par_names) + font_size = 40 + if n_params == 2: + + figPosterior, ax = plt.subplots(figsize=(15, 15)) + + sns.kdeplot(x=posterior[:, 0], y=posterior[:, 1], + fill=True, ax=ax, cmap=plt.cm.jet, + clip=bound_tuples) + # Axis labels + plt.xlabel(par_names[0], fontsize=font_size) + plt.ylabel(par_names[1], fontsize=font_size) + + # Set axis limit + plt.xlim(bound_tuples[0]) + plt.ylim(bound_tuples[1]) + + # Increase font size + plt.xticks(fontsize=font_size) + plt.yticks(fontsize=font_size) + + # Switch off the grids + plt.grid(False) + + else: + import corner + figPosterior = corner.corner(posterior, labels=par_names, + title_fmt='.2e', show_titles=True, + title_kwargs={"fontsize": 12}) + + figPosterior.savefig(f'./{newpath}/{key}.pdf', bbox_inches='tight') + plt.close() + + # Save the posterior as .npy + np.save(f'./{newpath}/{key}.npy', posterior) + + return figPosterior + + + # ------------------------------------------------------------------------- + def _BME_Calculator(self, obs_data, sigma2Dict, rmse=None): + """ + This function computes the Bayesian model evidence (BME) via Monte + Carlo integration. + + Parameters + ---------- + obs_data : dict of 1d np arrays + Observed data. + sigma2Dict : pandas dataframe, matches obs_data + Estimated uncertainty for the observed data. + rmse : dict of floats, optional + RMSE values for each output-key. The dafault is None. + + Returns + ------- + (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + """ + # Initializations + if hasattr(self, 'valid_likelihoods'): + valid_likelihoods = self.valid_likelihoods + else: + valid_likelihoods = [] + valid_likelihoods = np.array(valid_likelihoods) + + post_snapshot = self.ExpDesign.post_snapshot + if post_snapshot or valid_likelihoods.shape[0] != 0: + newpath = (r'Outputs_SeqPosteriorComparison/likelihood_vs_ref') + os.makedirs(newpath, exist_ok=True) + + SamplingMethod = 'random' + MCsize = 10000 + ESS = 0 + + # Estimation of the integral via Monte Varlo integration + while (ESS > MCsize) or (ESS < 1): + + # Generate samples for Monte Carlo simulation + X_MC = self.ExpDesign.generate_samples( + MCsize, SamplingMethod + ) + + # Monte Carlo simulation for the candidate design + Y_MC, std_MC = self.MetaModel.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and + # simulation results via PCE with candidate design) + Likelihoods = self._normpdf( + Y_MC, std_MC, obs_data, sigma2Dict, rmse + ) + + # Check the Effective Sample Size (1000<ESS<MCsize) + ESS = 1 / np.sum(np.square(Likelihoods/np.sum(Likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if (ESS > MCsize) or (ESS < 1): + print(f'ESS={ESS} MC size should be larger.') + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + X_Posterior = X_MC[accepted] + + # ------------------------------------------------------------ + # --- Kullback-Leibler Divergence & Information Entropy ------ + # ------------------------------------------------------------ + # Prior-based estimation of BME + logBME = np.log(np.nanmean(Likelihoods)) + + # TODO: Correction factor + # log_weight = self.__corr_factor_BME(obs_data, sigma2Dict, logBME) + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean(np.log(Likelihoods[accepted])) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean( + np.log(self.ExpDesign.JDist.pdf(X_Posterior.T)) + ) + + # Calculate Kullback-Leibler Divergence + # KLD = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + KLD = postExpLikelihoods - logBME + + # Information Entropy based on Entropy paper Eq. 38 + infEntropy = logBME - postExpPrior - postExpLikelihoods + + # If post_snapshot is True, plot likelihood vs refrence + if post_snapshot or valid_likelihoods: + # Hellinger distance + ref_like = np.log(valid_likelihoods[valid_likelihoods > 0]) + est_like = np.log(Likelihoods[Likelihoods > 0]) + distHellinger = hellinger_distance(ref_like, est_like) + + idx = len([name for name in os.listdir(newpath) if 'Likelihoods_' + in name and os.path.isfile(os.path.join(newpath, name))]) + + fig, ax = plt.subplots() + try: + sns.kdeplot(np.log(valid_likelihoods[valid_likelihoods > 0]), + shade=True, color="g", label='Ref. Likelihood') + sns.kdeplot(np.log(Likelihoods[Likelihoods > 0]), shade=True, + color="b", label='Likelihood with PCE') + except: + pass + + text = f"Hellinger Dist.={distHellinger:.3f}\n logBME={logBME:.3f}" + "\n DKL={KLD:.3f}" + + plt.text(0.05, 0.75, text, bbox=dict(facecolor='wheat', + edgecolor='black', + boxstyle='round,pad=1'), + transform=ax.transAxes) + + fig.savefig(f'./{newpath}/Likelihoods_{idx}.pdf', + bbox_inches='tight') + plt.close() + + else: + distHellinger = 0.0 + + # Bayesian inference with Emulator only for 2D problem + if post_snapshot and self.MetaModel.n_params == 2 and not idx % 5: + from bayesvalidrox.bayes_inference.bayes_inference import BayesInference + from bayesvalidrox.bayes_inference.discrepancy import Discrepancy + import pandas as pd + BayesOpts = BayesInference(self) + BayesOpts.emulator = True + BayesOpts.plot_post_pred = False + + # Select the inference method + import emcee + BayesOpts.inference_method = "MCMC" + # Set the MCMC parameters passed to self.mcmc_params + BayesOpts.mcmc_params = { + 'n_steps': 1e5, + 'n_walkers': 30, + 'moves': emcee.moves.KDEMove(), + 'verbose': False + } + + # ----- Define the discrepancy model ------- + # TODO: check with Farid if this first line is how it should be + BayesOpts.measured_data = obs_data + obs_data = pd.DataFrame(obs_data, columns=self.out_names) + BayesOpts.measurement_error = obs_data + # TODO: shouldn't the uncertainty be sigma2Dict instead of obs_data? + + # # -- (Option B) -- + DiscrepancyOpts = Discrepancy('') + DiscrepancyOpts.type = 'Gaussian' + DiscrepancyOpts.parameters = obs_data**2 + BayesOpts.Discrepancy = DiscrepancyOpts + # Start the calibration/inference + Bayes_PCE = BayesOpts.create_inference() + X_Posterior = Bayes_PCE.posterior_df.values + + return (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + # ------------------------------------------------------------------------- + def _validError(self): + """ + Evaluate the metamodel on the validation samples and calculate the + error against the corresponding model runs + + Returns + ------- + rms_error : dict + RMSE for each validation run. + valid_error : dict + Normed (?)RMSE for each validation run. + + """ + # Extract the original model with the generated samples + valid_model_runs = self.ExpDesign.valid_model_runs + + # Run the PCE model with the generated samples + valid_PCE_runs, _ = self.MetaModel.eval_metamodel(samples=self.ExpDesign.valid_samples) + + rms_error = {} + valid_error = {} + # Loop over the keys and compute RMSE error. + for key in self.out_names: + rms_error[key] = mean_squared_error( + valid_model_runs[key], valid_PCE_runs[key], + multioutput='raw_values', + sample_weight=None, + squared=False) + # Validation error + valid_error[key] = (rms_error[key]**2) + valid_error[key] /= np.var(valid_model_runs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Updated Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(rms_error[key], + valid_error[key])))) + + return rms_error, valid_error + + # ------------------------------------------------------------------------- + def _error_Mean_Std(self): + """ + Calculates the error in the overall mean and std approximation of the + surrogate against the mc-reference provided to the model. + This can only be applied to metamodels of polynomial type + + Returns + ------- + RMSE_Mean : float + RMSE of the means + RMSE_std : float + RMSE of the standard deviations + + """ + # Compute the mean and std based on the MetaModel + pce_means, pce_stds = self.MetaModel._compute_pce_moments() + + # Compute the root mean squared error + for output in self.out_names: + + # Compute the error between mean and std of MetaModel and OrigModel + RMSE_Mean = mean_squared_error( + self.Model.mc_reference['mean'], pce_means[output], squared=False + ) + RMSE_std = mean_squared_error( + self.Model.mc_reference['std'], pce_stds[output], squared=False + ) + + return RMSE_Mean, RMSE_std diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/eval_rec_rule.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/eval_rec_rule.py new file mode 100644 index 000000000..b583c7eb2 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/eval_rec_rule.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" + + +Based on the implementation in UQLab [1]. + +References: +1. S. Marelli, and B. Sudret, UQLab: A framework for uncertainty quantification +in Matlab, Proc. 2nd Int. Conf. on Vulnerability, Risk Analysis and Management +(ICVRAM2014), Liverpool, United Kingdom, 2014, 2554-2563. + +2. S. Marelli, N. Lüthen, B. Sudret, UQLab user manual – Polynomial chaos +expansions, Report # UQLab-V1.4-104, Chair of Risk, Safety and Uncertainty +Quantification, ETH Zurich, Switzerland, 2021. + +Author: Farid Mohammadi, M.Sc. +E-Mail: farid.mohammadi@iws.uni-stuttgart.de +Department of Hydromechanics and Modelling of Hydrosystems (LH2) +Institute for Modelling Hydraulic and Environmental Systems (IWS), University +of Stuttgart, www.iws.uni-stuttgart.de/lh2/ +Pfaffenwaldring 61 +70569 Stuttgart + +Created on Fri Jan 14 2022 +""" +import numpy as np +from numpy.polynomial.polynomial import polyval + + +def poly_rec_coeffs(n_max, poly_type, params=None): + """ + Computes the recurrence coefficients for classical Wiener-Askey orthogonal + polynomials. + + Parameters + ---------- + n_max : int + Maximum polynomial degree. + poly_type : string + Polynomial type. + params : list, optional + Parameters required for `laguerre` poly type. The default is None. + + Returns + ------- + AB : dict + The 3 term recursive coefficients and the applicable ranges. + + """ + + if poly_type == 'legendre': + + def an(n): + return np.zeros((n+1, 1)) + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = np.sqrt(1./(4-i**-2)) + return sq_bn + + bounds = [-1, 1] + + elif poly_type == 'hermite': + + def an(n): + return np.zeros((n+1, 1)) + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = np.sqrt(i) + return sq_bn + + bounds = [-np.inf, np.inf] + + elif poly_type == 'laguerre': + + def an(n): + a = np.zeros((n+1, 1)) + for i in range(1, n+1): + a[i] = 2*n + params[1] + return a + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = -np.sqrt(i * (i+params[1]-1)) + return sq_bn + + bounds = [0, np.inf] + + AB = {'alpha_beta': np.concatenate((an(n_max), sqrt_bn(n_max)), axis=1), + 'bounds': bounds} + + return AB + + +def eval_rec_rule(x, max_deg, poly_type): + """ + Evaluates the polynomial that corresponds to the Jacobi matrix defined + from the AB. + + Parameters + ---------- + x : array (n_samples) + Points where the polynomials are evaluated. + max_deg : int + Maximum degree. + poly_type : string + Polynomial type. + + Returns + ------- + values : array of shape (n_samples, max_deg+1) + Polynomials corresponding to the Jacobi matrix. + + """ + AB = poly_rec_coeffs(max_deg, poly_type) + AB = AB['alpha_beta'] + + values = np.zeros((len(x), AB.shape[0]+1)) + values[:, 1] = 1 / AB[0, 1] + + for k in range(AB.shape[0]-1): + values[:, k+2] = np.multiply((x - AB[k, 0]), values[:, k+1]) - \ + np.multiply(values[:, k], AB[k, 1]) + values[:, k+2] = np.divide(values[:, k+2], AB[k+1, 1]) + return values[:, 1:] + + +def eval_rec_rule_arbitrary(x, max_deg, poly_coeffs): + """ + Evaluates the polynomial at sample array x. + + Parameters + ---------- + x : array (n_samples) + Points where the polynomials are evaluated. + max_deg : int + Maximum degree. + poly_coeffs : dict + Polynomial coefficients computed based on moments. + + Returns + ------- + values : array of shape (n_samples, max_deg+1) + Univariate Polynomials evaluated at samples. + + """ + values = np.zeros((len(x), max_deg+1)) + + for deg in range(max_deg+1): + values[:, deg] = polyval(x, poly_coeffs[deg]).T + + return values + + +def eval_univ_basis(x, max_deg, poly_types, apoly_coeffs=None): + """ + Evaluates univariate regressors along input directions. + + Parameters + ---------- + x : array of shape (n_samples, n_params) + Training samples. + max_deg : int + Maximum polynomial degree. + poly_types : list of strings + List of polynomial types for all parameters. + apoly_coeffs : dict , optional + Polynomial coefficients computed based on moments. The default is None. + + Returns + ------- + univ_vals : array of shape (n_samples, n_params, max_deg+1) + Univariate polynomials for all degrees and parameters evaluated at x. + + """ + # Initilize the output array + n_samples, n_params = x.shape + univ_vals = np.zeros((n_samples, n_params, max_deg+1)) + + for i in range(n_params): + + if poly_types[i] == 'arbitrary': + polycoeffs = apoly_coeffs[f'p_{i+1}'] + univ_vals[:, i] = eval_rec_rule_arbitrary(x[:, i], max_deg, + polycoeffs) + else: + univ_vals[:, i] = eval_rec_rule(x[:, i], max_deg, poly_types[i]) + + return univ_vals diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exp_designs.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exp_designs.py new file mode 100644 index 000000000..665ee4fc3 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exp_designs.py @@ -0,0 +1,493 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import math +import itertools +import chaospy +import scipy.stats as st +from tqdm import tqdm +import h5py +import os + +from .apoly_construction import apoly_construction +from .input_space import InputSpace + +# ------------------------------------------------------------------------- +def check_ranges(theta, ranges): + """ + This function checks if theta lies in the given ranges. + + Parameters + ---------- + theta : array + Proposed parameter set. + ranges : nested list + List of the praremeter ranges. + + Returns + ------- + c : bool + If it lies in the given range, it return True else False. + + """ + c = True + # traverse in the list1 + for i, bounds in enumerate(ranges): + x = theta[i] + # condition check + if x < bounds[0] or x > bounds[1]: + c = False + return c + return c + + +class ExpDesigns(InputSpace): + """ + This class generates samples from the prescribed marginals for the model + parameters using the `Input` object. + + Attributes + ---------- + Input : obj + Input object containing the parameter marginals, i.e. name, + distribution type and distribution parameters or available raw data. + meta_Model_type : str + Type of the meta_Model_type. + sampling_method : str + Name of the sampling method for the experimental design. The following + sampling method are supported: + + * random + * latin_hypercube + * sobol + * halton + * hammersley + * chebyshev(FT) + * grid(FT) + * user + hdf5_file : str + Name of the hdf5 file that contains the experimental design. + n_new_samples : int + Number of (initial) training points. + n_max_samples : int + Number of maximum training points. + mod_LOO_threshold : float + The modified leave-one-out cross validation threshold where the + sequential design stops. + tradeoff_scheme : str + Trade-off scheme to assign weights to the exploration and exploitation + scores in the sequential design. + n_canddidate : int + Number of candidate training sets to calculate the scores for. + explore_method : str + Type of the exploration method for the sequential design. The following + methods are supported: + + * Voronoi + * random + * latin_hypercube + * LOOCV + * dual annealing + exploit_method : str + Type of the exploitation method for the sequential design. The + following methods are supported: + + * BayesOptDesign + * BayesActDesign + * VarOptDesign + * alphabetic + * Space-filling + util_func : str or list + The utility function to be specified for the `exploit_method`. For the + available utility functions see Note section. + n_cand_groups : int + Number of candidate groups. Each group of candidate training sets will + be evaulated separately in parallel. + n_replication : int + Number of replications. Only for comparison. The default is 1. + post_snapshot : int + Whether to plot the posterior in the sequential design. The default is + `True`. + step_snapshot : int + The number of steps to plot the posterior in the sequential design. The + default is 1. + max_a_post : list or array + Maximum a posteriori of the posterior distribution, if known. The + default is `[]`. + adapt_verbose : bool + Whether to plot the model response vs that of metamodel for the new + trining point in the sequential design. + + Note + ---------- + The following utiliy functions for the **exploitation** methods are + supported: + + #### BayesOptDesign (when data is available) + - DKL (Kullback-Leibler Divergence) + - DPP (D-Posterior-percision) + - APP (A-Posterior-percision) + + #### VarBasedOptDesign -> when data is not available + - Entropy (Entropy/MMSE/active learning) + - EIGF (Expected Improvement for Global fit) + - LOOCV (Leave-one-out Cross Validation) + + #### alphabetic + - D-Opt (D-Optimality) + - A-Opt (A-Optimality) + - K-Opt (K-Optimality) + """ + + def __init__(self, Input, meta_Model_type='pce', + sampling_method='random', hdf5_file=None, + n_new_samples=1, n_max_samples=None, mod_LOO_threshold=1e-16, + tradeoff_scheme=None, n_canddidate=1, explore_method='random', + exploit_method='Space-filling', util_func='Space-filling', + n_cand_groups=4, n_replication=1, post_snapshot=False, + step_snapshot=1, max_a_post=[], adapt_verbose=False, max_func_itr=1): + + self.InputObj = Input + self.meta_Model_type = meta_Model_type + self.sampling_method = sampling_method + self.hdf5_file = hdf5_file + self.n_new_samples = n_new_samples + self.n_max_samples = n_max_samples + self.mod_LOO_threshold = mod_LOO_threshold + self.explore_method = explore_method + self.exploit_method = exploit_method + self.util_func = util_func + self.tradeoff_scheme = tradeoff_scheme + self.n_canddidate = n_canddidate + self.n_cand_groups = n_cand_groups + self.n_replication = n_replication + self.post_snapshot = post_snapshot + self.step_snapshot = step_snapshot + self.max_a_post = max_a_post + self.adapt_verbose = adapt_verbose + self.max_func_itr = max_func_itr + + # Other + self.apce = None + self.ndim = None + + # Init + self.check_valid_inputs() + + # ------------------------------------------------------------------------- + def generate_samples(self, n_samples, sampling_method='random', + transform=False): + """ + Generates samples with given sampling method + + Parameters + ---------- + n_samples : int + Number of requested samples. + sampling_method : str, optional + Sampling method. The default is `'random'`. + transform : bool, optional + Transformation via an isoprobabilistic transformation method. The + default is `False`. + + Returns + ------- + samples: array of shape (n_samples, n_params) + Generated samples from defined model input object. + + """ + try: + samples = chaospy.generate_samples( + int(n_samples), domain=self.origJDist, rule=sampling_method + ) + except: + samples = self.random_sampler(int(n_samples)).T + + return samples.T + + + + # ------------------------------------------------------------------------- + def generate_ED(self, n_samples, transform=False, + max_pce_deg=None): + """ + Generates experimental designs (training set) with the given method. + + Parameters + ---------- + n_samples : int + Number of requested training points. + sampling_method : str, optional + Sampling method. The default is `'random'`. + transform : bool, optional + Isoprobabilistic transformation. The default is `False`. + max_pce_deg : int, optional + Maximum PCE polynomial degree. The default is `None`. + + Returns + ------- + None + + """ + if n_samples <0: + raise ValueError('A negative number of samples cannot be created. Please provide positive n_samples') + n_samples = int(n_samples) + + if not hasattr(self, 'n_init_samples'): + self.n_init_samples = n_samples + + # Generate the samples based on requested method + self.init_param_space(max_pce_deg) + + sampling_method = self.sampling_method + # Pass user-defined samples as ED + if sampling_method == 'user': + if not hasattr(self, 'X'): + raise AttributeError('User-defined sampling cannot proceed as no samples provided. Please add them to this class as attribute X') + if not self.X.ndim == 2: + raise AttributeError('The provided samples shuld have 2 dimensions') + samples = self.X + self.n_samples = len(samples) + + # Sample the distribution of parameters + elif self.input_data_given: + # Case II: Input values are directly given by the user. + + if sampling_method == 'random': + samples = self.random_sampler(n_samples) + + elif sampling_method == 'PCM' or \ + sampling_method == 'LSCM': + samples = self.pcm_sampler(n_samples, max_pce_deg) + + else: + # Create ExpDesign in the actual space using chaospy + try: + samples = chaospy.generate_samples(n_samples, + domain=self.JDist, + rule=sampling_method).T + except: + samples = self.JDist.resample(n_samples).T + + elif not self.input_data_given: + # Case I = User passed known distributions + samples = chaospy.generate_samples(n_samples, domain=self.JDist, + rule=sampling_method).T + + # Transform samples to the original space + if transform: + self.init_param_space(max_pce_deg) + tr_samples = self.transform( + samples, + method=sampling_method + ) + if sampling_method == 'user' or not self.apce: + self.X = samples + self.X_tr = tr_samples + #return samples, tr_samples + else: + self.X = tr_samples + self.X_tr = samples + #return tr_samples, samples # TODO: why is this swapped here? + else: + self.X = samples + self.X_tr = None + + def read_from_file(self, out_names): + """ + Reads in the ExpDesign from a provided h5py file and saves the results. + + Parameters + ---------- + out_names : list of strings + The keys that are in the outputs (y) saved in the provided file. + + Returns + ------- + None. + + """ + if self.hdf5_file == None: + raise AttributeError('ExpDesign cannot be read in, please provide hdf5 file first') + + # Read hdf5 file + f = h5py.File(self.hdf5_file, 'r+') + + # Read EDX and pass it to ExpDesign object + try: + self.X = np.array(f["EDX/New_init_"]) + except KeyError: + self.X = np.array(f["EDX/init_"]) + + # Update number of initial samples + self.n_init_samples = self.X.shape[0] + + # Read EDX and pass it to ExpDesign object + self.Y = {} + + # Extract x values + try: + self.Y["x_values"] = dict() + for varIdx, var in enumerate(out_names): + x = np.array(f[f"x_values/{var}"]) + self.Y["x_values"][var] = x + except KeyError: + self.Y["x_values"] = np.array(f["x_values"]) + + # Store the output + for varIdx, var in enumerate(out_names): + try: + y = np.array(f[f"EDY/{var}/New_init_"]) + except KeyError: + y = np.array(f[f"EDY/{var}/init_"]) + self.Y[var] = y + f.close() + print(f'Experimental Design is read in from file {self.hdf5_file}') + print('') + + + + # ------------------------------------------------------------------------- + def random_sampler(self, n_samples, max_deg = None): + """ + Samples the given raw data randomly. + + Parameters + ---------- + n_samples : int + Number of requested samples. + + max_deg : int, optional + Maximum degree. The default is `None`. + This will be used to run init_param_space, if it has not been done + until now. + + Returns + ------- + samples: array of shape (n_samples, n_params) + The sampling locations in the input space. + + """ + if not hasattr(self, 'raw_data'): + self.init_param_space(max_deg) + else: + if np.array(self.raw_data).ndim !=2: + raise AttributeError('The given raw data for sampling should have two dimensions') + samples = np.zeros((n_samples, self.ndim)) + sample_size = self.raw_data.shape[1] + + # Use a combination of raw data + if n_samples < sample_size: + for pa_idx in range(self.ndim): + # draw random indices + rand_idx = np.random.randint(0, sample_size, n_samples) + # store the raw data with given random indices + samples[:, pa_idx] = self.raw_data[pa_idx, rand_idx] + else: + try: + samples = self.JDist.resample(int(n_samples)).T + except AttributeError: + samples = self.JDist.sample(int(n_samples)).T + # Check if all samples are in the bound_tuples + for idx, param_set in enumerate(samples): + if not check_ranges(param_set, self.bound_tuples): + try: + proposed_sample = chaospy.generate_samples( + 1, domain=self.JDist, rule='random').T[0] + except: + proposed_sample = self.JDist.resample(1).T[0] + while not check_ranges(proposed_sample, + self.bound_tuples): + try: + proposed_sample = chaospy.generate_samples( + 1, domain=self.JDist, rule='random').T[0] + except: + proposed_sample = self.JDist.resample(1).T[0] + samples[idx] = proposed_sample + + return samples + + # ------------------------------------------------------------------------- + def pcm_sampler(self, n_samples, max_deg): + """ + Generates collocation points based on the root of the polynomial + degrees. + + Parameters + ---------- + n_samples : int + Number of requested samples. + max_deg : int + Maximum degree defined by user. Will also be used to run + init_param_space if that has not been done beforehand. + + Returns + ------- + opt_col_points: array of shape (n_samples, n_params) + Collocation points. + + """ + + if not hasattr(self, 'raw_data'): + self.init_param_space(max_deg) + + raw_data = self.raw_data + + # Guess the closest degree to self.n_samples + def M_uptoMax(deg): + result = [] + for d in range(1, deg+1): + result.append(math.factorial(self.ndim+d) // + (math.factorial(self.ndim) * math.factorial(d))) + return np.array(result) + #print(M_uptoMax(max_deg)) + #print(np.where(M_uptoMax(max_deg) > n_samples)[0]) + + guess_Deg = np.where(M_uptoMax(max_deg) > n_samples)[0][0] + + c_points = np.zeros((guess_Deg+1, self.ndim)) + + def PolynomialPa(parIdx): + return apoly_construction(self.raw_data[parIdx], max_deg) + + for i in range(self.ndim): + poly_coeffs = PolynomialPa(i)[guess_Deg+1][::-1] + c_points[:, i] = np.trim_zeros(np.roots(poly_coeffs)) + + # Construction of optimal integration points + Prod = itertools.product(np.arange(1, guess_Deg+2), repeat=self.ndim) + sort_dig_unique_combos = np.array(list(filter(lambda x: x, Prod))) + + # Ranking relatively mean + Temp = np.empty(shape=[0, guess_Deg+1]) + for j in range(self.ndim): + s = abs(c_points[:, j]-np.mean(raw_data[j])) + Temp = np.append(Temp, [s], axis=0) + temp = Temp.T + + index_CP = np.sort(temp, axis=0) + sort_cpoints = np.empty((0, guess_Deg+1)) + + for j in range(self.ndim): + #print(index_CP[:, j]) + sort_cp = c_points[index_CP[:, j], j] + sort_cpoints = np.vstack((sort_cpoints, sort_cp)) + + # Mapping of Combination to Cpoint Combination + sort_unique_combos = np.empty(shape=[0, self.ndim]) + for i in range(len(sort_dig_unique_combos)): + sort_un_comb = [] + for j in range(self.ndim): + SortUC = sort_cpoints[j, sort_dig_unique_combos[i, j]-1] + sort_un_comb.append(SortUC) + sort_uni_comb = np.asarray(sort_un_comb) + sort_unique_combos = np.vstack((sort_unique_combos, sort_uni_comb)) + + # Output the collocation points + if self.sampling_method.lower() == 'lscm': + opt_col_points = sort_unique_combos + else: + opt_col_points = sort_unique_combos[0:self.n_samples] + + return opt_col_points diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exploration.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exploration.py new file mode 100644 index 000000000..e18537207 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/exploration.py @@ -0,0 +1,364 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +from scipy.spatial import distance + + +class Exploration: + """ + Created based on the Surrogate Modeling Toolbox (SUMO) [1]. + + [1] Gorissen, D., Couckuyt, I., Demeester, P., Dhaene, T. and Crombecq, K., + 2010. A surrogate modeling and adaptive sampling toolbox for computer + based design. Journal of machine learning research.-Cambridge, Mass., + 11, pp.2051-2055. sumo@sumo.intec.ugent.be - http://sumo.intec.ugent.be + + Attributes + ---------- + ExpDesign : obj + ExpDesign object. + n_candidate : int + Number of candidate samples. + mc_criterion : str + Selection crieterion. The default is `'mc-intersite-proj-th'`. Another + option is `'mc-intersite-proj'`. + w : int + Number of random points in the domain for each sample of the + training set. + """ + + def __init__(self, ExpDesign, n_candidate, + mc_criterion='mc-intersite-proj-th'): + self.ExpDesign = ExpDesign + self.n_candidate = n_candidate + self.mc_criterion = mc_criterion + self.w = 100 + + def get_exploration_samples(self): + """ + This function generates candidates to be selected as new design and + their associated exploration scores. + + Returns + ------- + all_candidates : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + explore_method = self.ExpDesign.explore_method + + print("\n") + print(f' The {explore_method}-Method is selected as the exploration ' + 'method.') + print("\n") + + if explore_method == 'Voronoi': + # Generate samples using the Voronoi method + all_candidates, exploration_scores = self.get_vornoi_samples() + else: + # Generate samples using the MC method + all_candidates, exploration_scores = self.get_mc_samples() + + return all_candidates, exploration_scores + + # ------------------------------------------------------------------------- + def get_vornoi_samples(self): + """ + This function generates samples based on voronoi cells and their + corresponding scores + + Returns + ------- + new_samples : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + + mc_criterion = self.mc_criterion + n_candidate = self.n_candidate + # Get the Old ExpDesign #samples + old_ED_X = self.ExpDesign.X + ndim = old_ED_X.shape[1] + + # calculate error #averageErrors + error_voronoi, all_candidates = self.approximate_voronoi( + self.w, old_ED_X + ) + + # Pick the best candidate point in the voronoi cell + # for each best sample + selected_samples = np.empty((0, ndim)) + bad_samples = [] + + for index in range(len(error_voronoi)): + + # get candidate new samples from voronoi tesselation + candidates = self.closest_points[index] + + # get total number of candidates + n_new_samples = candidates.shape[0] + + # still no candidate samples around this one, skip it! + if n_new_samples == 0: + print('The following sample has been skipped because there ' + 'were no candidate samples around it...') + print(old_ED_X[index]) + bad_samples.append(index) + continue + + # find candidate that is farthest away from any existing sample + max_min_distance = 0 + best_candidate = 0 + min_intersite_dist = np.zeros((n_new_samples)) + min_projected_dist = np.zeros((n_new_samples)) + + for j in range(n_new_samples): + + new_samples = np.vstack((old_ED_X, selected_samples)) + + # find min distorted distance from all other samples + euclidean_dist = self._build_dist_matrix_point( + new_samples, candidates[j], do_sqrt=True) + min_euclidean_dist = np.min(euclidean_dist) + min_intersite_dist[j] = min_euclidean_dist + + # Check if this is the maximum minimum distance from all other + # samples + if min_euclidean_dist >= max_min_distance: + max_min_distance = min_euclidean_dist + best_candidate = j + + # Projected distance + projected_dist = distance.cdist( + new_samples, [candidates[j]], 'chebyshev') + min_projected_dist[j] = np.min(projected_dist) + + if mc_criterion == 'mc-intersite-proj': + weight_euclidean_dist = 0.5 * ((n_new_samples+1)**(1/ndim) - 1) + weight_projected_dist = 0.5 * (n_new_samples+1) + total_dist_scores = weight_euclidean_dist * min_intersite_dist + total_dist_scores += weight_projected_dist * min_projected_dist + + elif mc_criterion == 'mc-intersite-proj-th': + alpha = 0.5 # chosen (tradeoff) + d_min = 2 * alpha / n_new_samples + if any(min_projected_dist < d_min): + candidates = np.delete( + candidates, [min_projected_dist < d_min], axis=0 + ) + total_dist_scores = np.delete( + min_intersite_dist, [min_projected_dist < d_min], + axis=0 + ) + else: + total_dist_scores = min_intersite_dist + else: + raise NameError( + 'The MC-Criterion you requested is not available.' + ) + + # Add the best candidate to the list of new samples + best_candidate = np.argsort(total_dist_scores)[::-1][:n_candidate] + selected_samples = np.vstack( + (selected_samples, candidates[best_candidate]) + ) + + self.new_samples = selected_samples + self.exploration_scores = np.delete(error_voronoi, bad_samples, axis=0) + + return self.new_samples, self.exploration_scores + + # ------------------------------------------------------------------------- + def get_mc_samples(self, all_candidates=None): + """ + This function generates random samples based on Global Monte Carlo + methods and their corresponding scores, based on [1]. + + [1] Crombecq, K., Laermans, E. and Dhaene, T., 2011. Efficient + space-filling and non-collapsing sequential design strategies for + simulation-based modeling. European Journal of Operational Research + , 214(3), pp.683-696. + DOI: https://doi.org/10.1016/j.ejor.2011.05.032 + + Implemented methods to compute scores: + 1) mc-intersite-proj + 2) mc-intersite-proj-th + + Arguments + --------- + all_candidates : array, optional + Samples to compute the scores for. The default is `None`. In this + case, samples will be generated by defined model input marginals. + + Returns + ------- + new_samples : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + explore_method = self.ExpDesign.explore_method + mc_criterion = self.mc_criterion + if all_candidates is None: + n_candidate = self.n_candidate + else: + n_candidate = all_candidates.shape[0] + + # Get the Old ExpDesign #samples + old_ED_X = self.ExpDesign.X + ndim = old_ED_X.shape[1] + + # ----- Compute the number of random points ----- + if all_candidates is None: + # Generate MC Samples + all_candidates = self.ExpDesign.generate_samples( + self.n_candidate, explore_method + ) + self.all_candidates = all_candidates + + # initialization + min_intersite_dist = np.zeros((n_candidate)) + min_projected_dist = np.zeros((n_candidate)) + + for i, candidate in enumerate(all_candidates): + + # find candidate that is farthest away from any existing sample + maxMinDistance = 0 + + # find min distorted distance from all other samples + euclidean_dist = self._build_dist_matrix_point( + old_ED_X, candidate, do_sqrt=True + ) + min_euclidean_dist = np.min(euclidean_dist) + min_intersite_dist[i] = min_euclidean_dist + + # Check if this is the maximum minimum distance from all other + # samples + if min_euclidean_dist >= maxMinDistance: + maxMinDistance = min_euclidean_dist + + # Projected distance + projected_dist = self._build_dist_matrix_point( + old_ED_X, candidate, 'chebyshev' + ) + min_projected_dist[i] = np.min(projected_dist) + + if mc_criterion == 'mc-intersite-proj': + weight_euclidean_dist = ((n_candidate+1)**(1/ndim) - 1) * 0.5 + weight_projected_dist = (n_candidate+1) * 0.5 + total_dist_scores = weight_euclidean_dist * min_intersite_dist + total_dist_scores += weight_projected_dist * min_projected_dist + + elif mc_criterion == 'mc-intersite-proj-th': + alpha = 0.5 # chosen (tradeoff) + d_min = 2 * alpha / n_candidate + if any(min_projected_dist < d_min): + all_candidates = np.delete( + all_candidates, [min_projected_dist < d_min], axis=0 + ) + total_dist_scores = np.delete( + min_intersite_dist, [min_projected_dist < d_min], axis=0 + ) + else: + total_dist_scores = min_intersite_dist + else: + raise NameError('The MC-Criterion you requested is not available.') + + self.new_samples = all_candidates + self.exploration_scores = total_dist_scores + self.exploration_scores /= np.nansum(total_dist_scores) + + return self.new_samples, self.exploration_scores + + # ------------------------------------------------------------------------- + def approximate_voronoi(self, w, samples): + """ + An approximate (monte carlo) version of Matlab's voronoi command. + + Arguments + --------- + samples : array + Old experimental design to be used as center points for voronoi + cells. + + Returns + ------- + areas : array + An approximation of the voronoi cells' areas. + all_candidates: list of arrays + A list of samples in each voronoi cell. + """ + n_samples = samples.shape[0] + ndim = samples.shape[1] + + # Compute the number of random points + n_points = w * samples.shape[0] + # Generate w random points in the domain for each sample + points = self.ExpDesign.generate_samples(n_points, 'random') + self.all_candidates = points + + # Calculate the nearest sample to each point + self.areas = np.zeros((n_samples)) + self.closest_points = [np.empty((0, ndim)) for i in range(n_samples)] + + # Compute the minimum distance from all the samples of old_ED_X for + # each test point + for idx in range(n_points): + # calculate the minimum distance + distances = self._build_dist_matrix_point( + samples, points[idx], do_sqrt=True + ) + closest_sample = np.argmin(distances) + + # Add to the voronoi list of the closest sample + self.areas[closest_sample] = self.areas[closest_sample] + 1 + prev_closest_points = self.closest_points[closest_sample] + self.closest_points[closest_sample] = np.vstack( + (prev_closest_points, points[idx]) + ) + + # Divide by the amount of points to get the estimated volume of each + # voronoi cell + self.areas /= n_points + + self.perc = np.max(self.areas * 100) + + self.errors = self.areas + + return self.areas, self.all_candidates + + # ------------------------------------------------------------------------- + def _build_dist_matrix_point(self, samples, point, method='euclidean', + do_sqrt=False): + """ + Calculates the intersite distance of all points in samples from point. + + Parameters + ---------- + samples : array of shape (n_samples, n_params) + The old experimental design. + point : array + A candidate point. + method : str + Distance method. + do_sqrt : bool, optional + Whether to return distances or squared distances. The default is + `False`. + + Returns + ------- + distances : array + Distances. + + """ + distances = distance.cdist(samples, np.array([point]), method) + + # do square root? + if do_sqrt: + return distances + else: + return distances**2 + diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/glexindex.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/glexindex.py new file mode 100644 index 000000000..90877331e --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/glexindex.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Multi indices for monomial exponents. +Credit: Jonathan Feinberg +https://github.com/jonathf/numpoly/blob/master/numpoly/utils/glexindex.py +""" + +import numpy +import numpy.typing + + +def glexindex(start, stop=None, dimensions=1, cross_truncation=1., + graded=False, reverse=False): + """ + Generate graded lexicographical multi-indices for the monomial exponents. + Args: + start (Union[int, numpy.ndarray]): + The lower order of the indices. If array of int, counts as lower + bound for each axis. + stop (Union[int, numpy.ndarray, None]): + The maximum shape included. If omitted: stop <- start; start <- 0 + If int is provided, set as largest total order. If array of int, + set as upper bound for each axis. + dimensions (int): + The number of dimensions in the expansion. + cross_truncation (float, Tuple[float, float]): + Use hyperbolic cross truncation scheme to reduce the number of + terms in expansion. If two values are provided, first is low bound + truncation, while the latter upper bound. If only one value, upper + bound is assumed. + graded (bool): + Graded sorting, meaning the indices are always sorted by the index + sum. E.g. ``(2, 2, 2)`` has a sum of 6, and will therefore be + consider larger than both ``(3, 1, 1)`` and ``(1, 1, 3)``. + reverse (bool): + Reversed lexicographical sorting meaning that ``(1, 3)`` is + considered smaller than ``(3, 1)``, instead of the opposite. + Returns: + list: + Order list of indices. + Examples: + >>> numpoly.glexindex(4).tolist() + [[0], [1], [2], [3]] + >>> numpoly.glexindex(2, dimensions=2).tolist() + [[0, 0], [1, 0], [0, 1]] + >>> numpoly.glexindex(start=2, stop=3, dimensions=2).tolist() + [[2, 0], [1, 1], [0, 2]] + >>> numpoly.glexindex([1, 2, 3]).tolist() + [[0, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 2]] + >>> numpoly.glexindex([1, 2, 3], cross_truncation=numpy.inf).tolist() + [[0, 0, 0], [0, 1, 0], [0, 0, 1], [0, 1, 1], [0, 0, 2], [0, 1, 2]] + """ + if stop is None: + start, stop = 0, start + start = numpy.array(start, dtype=int).flatten() + stop = numpy.array(stop, dtype=int).flatten() + start, stop, _ = numpy.broadcast_arrays(start, stop, numpy.empty(dimensions)) + + cross_truncation = cross_truncation*numpy.ones(2) + + # Moved here from _glexindex + bound = stop.max() + dimensions = len(start) + start = numpy.clip(start, a_min=0, a_max=None) + dtype = numpy.uint8 if bound < 256 else numpy.uint16 + range_ = numpy.arange(bound, dtype=dtype) + indices = range_[:, numpy.newaxis] + + for idx in range(dimensions-1): + + # Truncate at each step to keep memory usage low + if idx: + indices = indices[cross_truncate(indices, bound-1, cross_truncation[1])] + + # Repeats the current set of indices. + # e.g. [0,1,2] -> [0,1,2,0,1,2,...,0,1,2] + indices = numpy.tile(indices, (bound, 1)) + + # Stretches ranges over the new dimension. + # e.g. [0,1,2] -> [0,0,...,0,1,1,...,1,2,2,...,2] + front = range_.repeat(len(indices)//bound)[:, numpy.newaxis] + + # Puts them two together. + indices = numpy.column_stack((front, indices)) + + # Complete the truncation scheme + if dimensions == 1: + indices = indices[(indices >= start) & (indices < bound)] + else: + lower = cross_truncate(indices, start-1, cross_truncation[0]) + upper = cross_truncate(indices, stop-1, cross_truncation[1]) + indices = indices[lower ^ upper] + + indices = numpy.array(indices, dtype=int).reshape(-1, dimensions) + if indices.size: + # moved here from glexsort + keys = indices.T + keys_ = numpy.atleast_2d(keys) + if reverse: + keys_ = keys_[::-1] + + indices_sort = numpy.array(numpy.lexsort(keys_)) + if graded: + indices_sort = indices_sort[numpy.argsort( + numpy.sum(keys_[:, indices_sort], axis=0))].T + + indices = indices[indices_sort] + return indices + +def cross_truncate(indices, bound, norm): + r""" + Truncate of indices using L_p norm. + .. math: + L_p(x) = \sum_i |x_i/b_i|^p ^{1/p} \leq 1 + where :math:`b_i` are bounds that each :math:`x_i` should follow. + Args: + indices (Sequence[int]): + Indices to be truncated. + bound (int, Sequence[int]): + The bound function for witch the indices can not be larger than. + norm (float, Sequence[float]): + The `p` in the `L_p`-norm. Support includes both `L_0` and `L_inf`. + Returns: + Boolean indices to ``indices`` with True for each index where the + truncation criteria holds. + Examples: + >>> indices = numpy.array(numpy.mgrid[:10, :10]).reshape(2, -1).T + >>> indices[cross_truncate(indices, 2, norm=0)].T + array([[0, 0, 0, 1, 2], + [0, 1, 2, 0, 0]]) + >>> indices[cross_truncate(indices, 2, norm=1)].T + array([[0, 0, 0, 1, 1, 2], + [0, 1, 2, 0, 1, 0]]) + >>> indices[cross_truncate(indices, [0, 1], norm=1)].T + array([[0, 0], + [0, 1]]) + """ + assert norm >= 0, "negative L_p norm not allowed" + bound = numpy.asfarray(bound).flatten()*numpy.ones(indices.shape[1]) + + if numpy.any(bound < 0): + return numpy.zeros((len(indices),), dtype=bool) + + if numpy.any(bound == 0): + out = numpy.all(indices[:, bound == 0] == 0, axis=-1) + if numpy.any(bound): + out &= cross_truncate(indices[:, bound != 0], bound[bound != 0], norm=norm) + return out + + if norm == 0: + out = numpy.sum(indices > 0, axis=-1) <= 1 + out[numpy.any(indices > bound, axis=-1)] = False + elif norm == numpy.inf: + out = numpy.max(indices/bound, axis=-1) <= 1 + else: + out = numpy.sum((indices/bound)**norm, axis=-1)**(1./norm) <= 1 + + assert numpy.all(out[numpy.all(indices == 0, axis=-1)]) + + return out diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/input_space.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/input_space.py new file mode 100644 index 000000000..3160ba2d0 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/input_space.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import chaospy +import scipy.stats as st + + +class InputSpace: + """ + This class generates the input space for the metamodel from the + distributions provided using the `Input` object. + + Attributes + ---------- + Input : obj + Input object containing the parameter marginals, i.e. name, + distribution type and distribution parameters or available raw data. + meta_Model_type : str + Type of the meta_Model_type. + + """ + + def __init__(self, Input, meta_Model_type='pce'): + self.InputObj = Input + self.meta_Model_type = meta_Model_type + + # Other + self.apce = None + self.ndim = None + + # Init + self.check_valid_inputs() + + + def check_valid_inputs(self)-> None: + """ + Check if the given InputObj is valid to use for further calculations: + Has some Marginals + Marginals have valid priors + All Marginals given as the same type (samples vs dist) + + Returns + ------- + None + + """ + Inputs = self.InputObj + self.ndim = len(Inputs.Marginals) + + # Check if PCE or aPCE metamodel is selected. + # TODO: test also for 'pce'?? + if self.meta_Model_type.lower() == 'apce': + self.apce = True + else: + self.apce = False + + # check if marginals given + if not self.ndim >=1: + raise AssertionError('Cannot build distributions if no marginals are given') + + # check that each marginal is valid + for marginals in Inputs.Marginals: + if len(marginals.input_data) == 0: + if marginals.dist_type == None: + raise AssertionError('Not all marginals were provided priors') + break + if np.array(marginals.input_data).shape[0] and (marginals.dist_type != None): + raise AssertionError('Both samples and distribution type are given. Please choose only one.') + break + + # Check if input is given as dist or input_data. + self.input_data_given = -1 + for marg in Inputs.Marginals: + #print(self.input_data_given) + size = np.array(marg.input_data).shape[0] + #print(f'Size: {size}') + if size and abs(self.input_data_given) !=1: + self.input_data_given = 2 + break + if (not size) and self.input_data_given > 0: + self.input_data_given = 2 + break + if not size: + self.input_data_given = 0 + if size: + self.input_data_given = 1 + + if self.input_data_given == 2: + raise AssertionError('Distributions cannot be built as the priors have different types') + + + # Get the bounds if input_data are directly defined by user: + if self.input_data_given: + for i in range(self.ndim): + low_bound = np.min(Inputs.Marginals[i].input_data) + up_bound = np.max(Inputs.Marginals[i].input_data) + Inputs.Marginals[i].parameters = [low_bound, up_bound] + + + + # ------------------------------------------------------------------------- + def init_param_space(self, max_deg=None): + """ + Initializes parameter space. + + Parameters + ---------- + max_deg : int, optional + Maximum degree. The default is `None`. + + Creates + ------- + raw_data : array of shape (n_params, n_samples) + Raw data. + bound_tuples : list of tuples + A list containing lower and upper bounds of parameters. + + """ + # Recheck all before running! + self.check_valid_inputs() + + Inputs = self.InputObj + ndim = self.ndim + rosenblatt_flag = Inputs.Rosenblatt + mc_size = 50000 + + # Save parameter names + self.par_names = [] + for parIdx in range(ndim): + self.par_names.append(Inputs.Marginals[parIdx].name) + + # Create a multivariate probability distribution + # TODO: change this to make max_deg obligatory? at least in some specific cases? + if max_deg is not None: + JDist, poly_types = self.build_polytypes(rosenblatt=rosenblatt_flag) + self.JDist, self.poly_types = JDist, poly_types + + if self.input_data_given: + self.MCSize = len(Inputs.Marginals[0].input_data) + self.raw_data = np.zeros((ndim, self.MCSize)) + + for parIdx in range(ndim): + # Save parameter names + try: + self.raw_data[parIdx] = np.array( + Inputs.Marginals[parIdx].input_data) + except: + self.raw_data[parIdx] = self.JDist[parIdx].sample(mc_size) + + else: + # Generate random samples based on parameter distributions + self.raw_data = chaospy.generate_samples(mc_size, + domain=self.JDist) + + # Extract moments + for parIdx in range(ndim): + mu = np.mean(self.raw_data[parIdx]) + std = np.std(self.raw_data[parIdx]) + self.InputObj.Marginals[parIdx].moments = [mu, std] + + # Generate the bounds based on given inputs for marginals + bound_tuples = [] + for i in range(ndim): + if Inputs.Marginals[i].dist_type == 'unif': + low_bound = Inputs.Marginals[i].parameters[0] + up_bound = Inputs.Marginals[i].parameters[1] + else: + low_bound = np.min(self.raw_data[i]) + up_bound = np.max(self.raw_data[i]) + + bound_tuples.append((low_bound, up_bound)) + + self.bound_tuples = tuple(bound_tuples) + + # ------------------------------------------------------------------------- + def build_polytypes(self, rosenblatt): + """ + Creates the polynomial types to be passed to univ_basis_vals method of + the MetaModel object. + + Parameters + ---------- + rosenblatt : bool + Rosenblatt transformation flag. + + Returns + ------- + orig_space_dist : object + A chaospy JDist object or a gaussian_kde object. + poly_types : list + List of polynomial types for the parameters. + + """ + Inputs = self.InputObj + + all_data = [] + all_dist_types = [] + orig_joints = [] + poly_types = [] + + for parIdx in range(self.ndim): + + if Inputs.Marginals[parIdx].dist_type is None: + data = Inputs.Marginals[parIdx].input_data + all_data.append(data) + dist_type = None + else: + dist_type = Inputs.Marginals[parIdx].dist_type + params = Inputs.Marginals[parIdx].parameters + + if rosenblatt: + polytype = 'hermite' + dist = chaospy.Normal() + + elif dist_type is None: + polytype = 'arbitrary' + dist = None + + elif 'unif' in dist_type.lower(): + polytype = 'legendre' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Uniform(lower=params[0], upper=params[1]) + + elif 'norm' in dist_type.lower() and \ + 'log' not in dist_type.lower(): + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + polytype = 'hermite' + dist = chaospy.Normal(mu=params[0], sigma=params[1]) + + elif 'gamma' in dist_type.lower(): + polytype = 'laguerre' + if not np.array(params).shape[0]>=3: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Gamma(shape=params[0], + scale=params[1], + shift=params[2]) + + elif 'beta' in dist_type.lower(): + if not np.array(params).shape[0]>=4: + raise AssertionError('Distribution has too few parameters!') + polytype = 'jacobi' + dist = chaospy.Beta(alpha=params[0], beta=params[1], + lower=params[2], upper=params[3]) + + elif 'lognorm' in dist_type.lower(): + polytype = 'hermite' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + mu = np.log(params[0]**2/np.sqrt(params[0]**2 + params[1]**2)) + sigma = np.sqrt(np.log(1 + params[1]**2 / params[0]**2)) + dist = chaospy.LogNormal(mu, sigma) + # dist = chaospy.LogNormal(mu=params[0], sigma=params[1]) + + elif 'expon' in dist_type.lower(): + polytype = 'exponential' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Exponential(scale=params[0], shift=params[1]) + + elif 'weibull' in dist_type.lower(): + polytype = 'weibull' + if not np.array(params).shape[0]>=3: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Weibull(shape=params[0], scale=params[1], + shift=params[2]) + + else: + message = (f"DistType {dist_type} for parameter" + f"{parIdx+1} is not available.") + raise ValueError(message) + + if self.input_data_given or self.apce: + polytype = 'arbitrary' + + # Store dists and poly_types + orig_joints.append(dist) + poly_types.append(polytype) + all_dist_types.append(dist_type) + + # Prepare final output to return + if None in all_dist_types: + # Naive approach: Fit a gaussian kernel to the provided data + Data = np.asarray(all_data) + try: + orig_space_dist = st.gaussian_kde(Data) + except: + raise ValueError('The samples provided to the Marginals should be 1D only') + self.prior_space = orig_space_dist + else: + orig_space_dist = chaospy.J(*orig_joints) + try: + self.prior_space = st.gaussian_kde(orig_space_dist.sample(10000)) + except: + raise ValueError('Parameter values are not valid, please set differently') + + return orig_space_dist, poly_types + + # ------------------------------------------------------------------------- + def transform(self, X, params=None, method=None): + """ + Transforms the samples via either a Rosenblatt or an isoprobabilistic + transformation. + + Parameters + ---------- + X : array of shape (n_samples,n_params) + Samples to be transformed. + method : string + If transformation method is 'user' transform X, else just pass X. + + Returns + ------- + tr_X: array of shape (n_samples,n_params) + Transformed samples. + + """ + # Check for built JDist + if not hasattr(self, 'JDist'): + raise AttributeError('Call function init_param_space first to create JDist') + + # Check if X is 2d + if X.ndim != 2: + raise AttributeError('X should have two dimensions') + + # Check if size of X matches Marginals + if X.shape[1]!= self.ndim: + raise AttributeError('The second dimension of X should be the same size as the number of marginals in the InputObj') + + if self.InputObj.Rosenblatt: + self.origJDist, _ = self.build_polytypes(False) + if method == 'user': + tr_X = self.JDist.inv(self.origJDist.fwd(X.T)).T + else: + # Inverse to original spcace -- generate sample ED + tr_X = self.origJDist.inv(self.JDist.fwd(X.T)).T + else: + # Transform samples via an isoprobabilistic transformation + n_samples, n_params = X.shape + Inputs = self.InputObj + origJDist = self.JDist + poly_types = self.poly_types + + disttypes = [] + for par_i in range(n_params): + disttypes.append(Inputs.Marginals[par_i].dist_type) + + # Pass non-transformed X, if arbitrary PCE is selected. + if None in disttypes or self.input_data_given or self.apce: + return X + + cdfx = np.zeros((X.shape)) + tr_X = np.zeros((X.shape)) + + for par_i in range(n_params): + + # Extract the parameters of the original space + disttype = disttypes[par_i] + if disttype is not None: + dist = origJDist[par_i] + else: + dist = None + polytype = poly_types[par_i] + cdf = np.vectorize(lambda x: dist.cdf(x)) + + # Extract the parameters of the transformation space based on + # polyType + if polytype == 'legendre' or disttype == 'uniform': + # Generate Y_Dists based + params_Y = [-1, 1] + dist_Y = st.uniform(loc=params_Y[0], + scale=params_Y[1]-params_Y[0]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + elif polytype == 'hermite' or disttype == 'norm': + params_Y = [0, 1] + dist_Y = st.norm(loc=params_Y[0], scale=params_Y[1]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + elif polytype == 'laguerre' or disttype == 'gamma': + if params == None: + raise AttributeError('Additional parameters have to be set for the gamma distribution!') + params_Y = [1, params[1]] + dist_Y = st.gamma(loc=params_Y[0], scale=params_Y[1]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + # Compute CDF_x(X) + cdfx[:, par_i] = cdf(X[:, par_i]) + + # Compute invCDF_y(cdfx) + tr_X[:, par_i] = inv_cdf(cdfx[:, par_i]) + + return tr_X diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/inputs.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/inputs.py new file mode 100644 index 000000000..783e82b05 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/inputs.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +class Input: + """ + A class to define the uncertain input parameters. + + Attributes + ---------- + Marginals : obj + Marginal objects. See `inputs.Marginal`. + Rosenblatt : bool + If Rossenblatt transformation is required for the dependent input + parameters. + + Examples + ------- + Marginals can be defined as following: + + >>> Inputs.add_marginals() + >>> Inputs.Marginals[0].name = 'X_1' + >>> Inputs.Marginals[0].dist_type = 'uniform' + >>> Inputs.Marginals[0].parameters = [-5, 5] + + If there is no common data is avaliable, the input data can be given + as following: + + >>> Inputs.add_marginals() + >>> Inputs.Marginals[0].name = 'X_1' + >>> Inputs.Marginals[0].input_data = input_data + """ + poly_coeffs_flag = True + + def __init__(self): + self.Marginals = [] + self.Rosenblatt = False + + def add_marginals(self): + """ + Adds a new Marginal object to the input object. + + Returns + ------- + None. + + """ + self.Marginals.append(Marginal()) + + +# Nested class +class Marginal: + """ + An object containing the specifications of the marginals for each uncertain + parameter. + + Attributes + ---------- + name : string + Name of the parameter. The default is `'$x_1$'`. + dist_type : string + Name of the distribution. The default is `None`. + parameters : list + List of the parameters corresponding to the distribution type. The + default is `None`. + input_data : array + Available input data. The default is `[]`. + moments : list + List of the moments. + """ + + def __init__(self): + self.name = '$x_1$' + self.dist_type = None + self.parameters = None + self.input_data = [] + self.moments = None diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py new file mode 100644 index 000000000..96ef9c1d5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Jul 15 14:08:59 2022 + +@author: farid +""" +import numpy as np +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +from sklearn.utils import check_X_y + + +def corr(x, y): + return abs(x.dot(y))/np.sqrt((x**2).sum()) + + +class OrthogonalMatchingPursuit(LinearModel, RegressorMixin): + ''' + Regression with Orthogonal Matching Pursuit [1]. + + Parameters + ---------- + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + References + ---------- + [1] Pati, Y., Rezaiifar, R., Krishnaprasad, P. (1993). Orthogonal matching + pursuit: recursive function approximation with application to wavelet + decomposition. Proceedings of 27th Asilomar Conference on Signals, + Systems and Computers, 40-44. + ''' + + def __init__(self, fit_intercept=True, normalize=False, copy_X=True, + verbose=False): + self.fit_intercept = fit_intercept + self.normalize = normalize + self.copy_X = copy_X + self.verbose = verbose + + def _preprocess_data(self, X, y): + """Center and scale data. + Centers data to have mean zero along axis 0. If fit_intercept=False or + if the X is a sparse matrix, no centering is done, but normalization + can still be applied. The function returns the statistics necessary to + reconstruct the input data, which are X_offset, y_offset, X_scale, such + that the output + X = (X - X_offset) / X_scale + X_scale is the L2 norm of X - X_offset. + """ + + if self.copy_X: + X = X.copy(order='K') + + y = np.asarray(y, dtype=X.dtype) + + if self.fit_intercept: + X_offset = np.average(X, axis=0) + X -= X_offset + if self.normalize: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + std = np.sqrt(np.sum(X**2, axis=0)/(len(X)-1)) + X_scale[std != 0] = std[std != 0] + X /= X_scale + else: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + y_offset = np.mean(y) + y = y - y_offset + else: + X_offset = np.zeros(X.shape[1], dtype=X.dtype) + X_scale = np.ones(X.shape[1], dtype=X.dtype) + if y.ndim == 1: + y_offset = X.dtype.type(0) + else: + y_offset = np.zeros(y.shape[1], dtype=X.dtype) + + return X, y, X_offset, y_offset, X_scale + + def fit(self, X, y): + ''' + Fits Regression with Orthogonal Matching Pursuit Algorithm. + + Parameters + ----------- + X: {array-like, sparse matrix} of size (n_samples, n_features) + Training data, matrix of explanatory variables + + y: array-like of size [n_samples, n_features] + Target values + + Returns + ------- + self : object + Returns self. + ''' + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._preprocess_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # Normalize columns of Psi, so that each column has norm = 1 + norm_X = np.linalg.norm(X, axis=0) + X_norm = X/norm_X + + # Initialize residual vector to full model response and normalize + R = y + norm_y = np.sqrt(np.dot(y, y)) + r = y/norm_y + + # Check for constant regressors + const_indices = np.where(~np.diff(X, axis=0).any(axis=0))[0] + bool_const = not const_indices + + # Start regression using OPM algorithm + precision = 0 # Set precision criterion to precision of program + early_stop = True + cond_early = True # Initialize condition for early stop + ind = [] + iindx = [] # index of selected columns + indtot = np.arange(n_features) # Full index set for remaining columns + kmax = min(n_samples, n_features) # Maximum number of iterations + LOO = np.PINF * np.ones(kmax) # Store LOO error at each iteration + LOOmin = np.PINF # Initialize minimum value of LOO + coeff = np.zeros((n_features, kmax)) + count = 0 + k = 0.1 # Percentage of iteration history for early stop + + # Begin iteration over regressors set (Matrix X) + while (np.linalg.norm(R) > precision) and (count <= kmax-1) and \ + ((cond_early or early_stop) ^ ~cond_early): + + # Update index set of columns yet to select + if count != 0: + indtot = np.delete(indtot, iindx) + + # Find column of X that is most correlated with residual + h = abs(np.dot(r, X_norm)) + iindx = np.argmax(h[indtot]) + indx = indtot[iindx] + + # initialize with the constant regressor, if it exists in the basis + if (count == 0) and bool_const: + # overwrite values for iindx and indx + iindx = const_indices[0] + indx = indtot[iindx] + + # Invert the information matrix at the first iteration, later only + # update its value on the basis of the previously inverted one, + if count == 0: + M = 1 / np.dot(X[:, indx], X[:, indx]) + else: + x = np.dot(X[:, ind].T, X[:, indx]) + r = np.dot(X[:, indx], X[:, indx]) + M = self.blockwise_inverse(M, x, x.T, r) + + # Add newly found index to the selected indexes set + ind.append(indx) + + # Select regressors subset (Projection subspace) + Xpro = X[:, ind] + + # Obtain coefficient by performing OLS + TT = np.dot(y, Xpro) + beta = np.dot(M, TT) + coeff[ind, count] = beta + + # Compute LOO error + LOO[count] = self.loo_error(Xpro, M, y, beta) + + # Compute new residual due to new projection + R = y - np.dot(Xpro, beta) + + # Normalize residual + norm_R = np.sqrt(np.dot(R, R)) + r = R / norm_R + + # Update counters and early-stop criterions + countinf = max(0, int(count-k*kmax)) + LOOmin = min(LOOmin, LOO[count]) + + if count == 0: + cond_early = (LOO[0] <= LOOmin) + else: + cond_early = (min(LOO[countinf:count+1]) <= LOOmin) + + if self.verbose: + print(f'Iteration: {count+1}, mod. LOOCV error : ' + f'{LOO[count]:.2e}') + + # Update counter + count += 1 + + # Select projection with smallest cross-validation error + countmin = np.argmin(LOO[:-1]) + self.coef_ = coeff[:, countmin] + self.active = coeff[:, countmin] != 0.0 + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self, X): + ''' + Computes predictive distribution for test set. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + ''' + + y_hat = np.dot(X, self.coef_) + self.intercept_ + + return y_hat + + def loo_error(self, psi, inv_inf_matrix, y, coeffs): + """ + Calculates the corrected LOO error for regression on regressor + matrix `psi` that generated the coefficients based on [1] and [2]. + + [1] Blatman, G., 2009. Adaptive sparse polynomial chaos expansions for + uncertainty propagation and sensitivity analysis (Doctoral + dissertation, Clermont-Ferrand 2). + + [2] Blatman, G. and Sudret, B., 2011. Adaptive sparse polynomial chaos + expansion based on least angle regression. Journal of computational + Physics, 230(6), pp.2345-2367. + + Parameters + ---------- + psi : array of shape (n_samples, n_feature) + Orthogonal bases evaluated at the samples. + inv_inf_matrix : array + Inverse of the information matrix. + y : array of shape (n_samples, ) + Targets. + coeffs : array + Computed regresssor cofficients. + + Returns + ------- + loo_error : float + Modified LOOCV error. + + """ + + # NrEvaluation (Size of experimental design) + N, P = psi.shape + + # h factor (the full matrix is not calculated explicitly, + # only the trace is, to save memory) + PsiM = np.dot(psi, inv_inf_matrix) + + h = np.sum(np.multiply(PsiM, psi), axis=1, dtype=np.longdouble) + + # ------ Calculate Error Loocv for each measurement point ---- + # Residuals + residual = np.dot(psi, coeffs) - y + + # Variance + varY = np.var(y) + + if varY == 0: + norm_emp_error = 0 + loo_error = 0 + else: + norm_emp_error = np.mean(residual**2)/varY + + loo_error = np.mean(np.square(residual / (1-h))) / varY + + # if there are NaNs, just return an infinite LOO error (this + # happens, e.g., when a strongly underdetermined problem is solved) + if np.isnan(loo_error): + loo_error = np.inf + + # Corrected Error for over-determined system + tr_M = np.trace(np.atleast_2d(inv_inf_matrix)) + if tr_M < 0 or abs(tr_M) > 1e6: + tr_M = np.trace(np.linalg.pinv(np.dot(psi.T, psi))) + + # Over-determined system of Equation + if N > P: + T_factor = N/(N-P) * (1 + tr_M) + + # Under-determined system of Equation + else: + T_factor = np.inf + + loo_error *= T_factor + + return loo_error + + def blockwise_inverse(self, Ainv, B, C, D): + """ + non-singular square matrix M defined as M = [[A B]; [C D]] . + B, C and D can have any dimension, provided their combination defines + a square matrix M. + + Parameters + ---------- + Ainv : float or array + inverse of the square-submatrix A. + B : float or array + Information matrix with all new regressor. + C : float or array + Transpose of B. + D : float or array + Information matrix with all selected regressors. + + Returns + ------- + M : array + Inverse of the information matrix. + + """ + if np.isscalar(D): + # Inverse of D + Dinv = 1/D + # Schur complement + SCinv = 1/(D - np.dot(C, np.dot(Ainv, B[:, None])))[0] + else: + # Inverse of D + Dinv = np.linalg.solve(D, np.eye(D.shape)) + # Schur complement + SCinv = np.linalg.solve((D - C*Ainv*B), np.eye(D.shape)) + + T1 = np.dot(Ainv, np.dot(B[:, None], SCinv)) + T2 = np.dot(C, Ainv) + + # Assemble the inverse matrix + M = np.vstack(( + np.hstack((Ainv+T1*T2, -T1)), + np.hstack((-(SCinv)*T2, SCinv)) + )) + return M diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_ard.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_ard.py new file mode 100644 index 000000000..e6883a3ed --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_ard.py @@ -0,0 +1,475 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Mar 24 19:41:45 2020 + +@author: farid +""" +import numpy as np +from scipy.linalg import solve_triangular +from numpy.linalg import LinAlgError +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +import warnings +from sklearn.utils import check_X_y +from scipy.linalg import pinvh + + +def update_precisions(Q,S,q,s,A,active,tol,n_samples,clf_bias): + ''' + Selects one feature to be added/recomputed/deleted to model based on + effect it will have on value of log marginal likelihood. + ''' + # initialise vector holding changes in log marginal likelihood + deltaL = np.zeros(Q.shape[0]) + + # identify features that can be added , recomputed and deleted in model + theta = q**2 - s + add = (theta > 0) * (active == False) + recompute = (theta > 0) * (active == True) + delete = ~(add + recompute) + + # compute sparsity & quality parameters corresponding to features in + # three groups identified above + Qadd,Sadd = Q[add], S[add] + Qrec,Srec,Arec = Q[recompute], S[recompute], A[recompute] + Qdel,Sdel,Adel = Q[delete], S[delete], A[delete] + + # compute new alpha's (precision parameters) for features that are + # currently in model and will be recomputed + Anew = s[recompute]**2/ ( theta[recompute] + np.finfo(np.float32).eps) + delta_alpha = (1./Anew - 1./Arec) + + # compute change in log marginal likelihood + deltaL[add] = ( Qadd**2 - Sadd ) / Sadd + np.log(Sadd/Qadd**2 ) + deltaL[recompute] = Qrec**2 / (Srec + 1. / delta_alpha) - np.log(1 + Srec*delta_alpha) + deltaL[delete] = Qdel**2 / (Sdel - Adel) - np.log(1 - Sdel / Adel) + deltaL = deltaL / n_samples + + # find feature which caused largest change in likelihood + feature_index = np.argmax(deltaL) + + # no deletions or additions + same_features = np.sum( theta[~recompute] > 0) == 0 + + # changes in precision for features already in model is below threshold + no_delta = np.sum( abs( Anew - Arec ) > tol ) == 0 + # if same_features: print(abs( Anew - Arec )) + # print("same_features = {} no_delta = {}".format(same_features,no_delta)) + # check convergence: if no features to add or delete and small change in + # precision for current features then terminate + converged = False + if same_features and no_delta: + converged = True + return [A,converged] + + # if not converged update precision parameter of weights and return + if theta[feature_index] > 0: + A[feature_index] = s[feature_index]**2 / theta[feature_index] + if active[feature_index] == False: + active[feature_index] = True + else: + # at least two active features + if active[feature_index] == True and np.sum(active) >= 2: + # do not remove bias term in classification + # (in regression it is factored in through centering) + if not (feature_index == 0 and clf_bias): + active[feature_index] = False + A[feature_index] = np.PINF + + return [A,converged] + + +class RegressionFastARD(LinearModel, RegressorMixin): + ''' + Regression with Automatic Relevance Determination (Fast Version uses + Sparse Bayesian Learning) + https://github.com/AmazaspShumik/sklearn-bayes/blob/master/skbayes/rvm_ard_models/fast_rvm.py + + Parameters + ---------- + n_iter: int, optional (DEFAULT = 100) + Maximum number of iterations + + start: list, optional (DEFAULT = None) + Initial selected features. + + tol: float, optional (DEFAULT = 1e-3) + If absolute change in precision parameter for weights is below threshold + algorithm terminates. + + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + compute_score : bool, default=False + If True, compute the log marginal likelihood at each iteration of the + optimization. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + alpha_ : float + estimated precision of the noise + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + lambda_ : array, shape = (n_features) + estimated precisions of the coefficients + + sigma_ : array, shape = (n_features, n_features) + estimated covariance matrix of the weights, computed only + for non-zero coefficients + + scores_ : array-like of shape (n_iter_+1,) + If computed_score is True, value of the log marginal likelihood (to be + maximized) at each iteration of the optimization. + + References + ---------- + [1] Fast marginal likelihood maximisation for sparse Bayesian models + (Tipping & Faul 2003) (http://www.miketipping.com/papers/met-fastsbl.pdf) + [2] Analysis of sparse Bayesian learning (Tipping & Faul 2001) + (http://www.miketipping.com/abstracts.htm#Faul:NIPS01) + ''' + + def __init__(self, n_iter=300, start=None, tol=1e-3, fit_intercept=True, + normalize=False, copy_X=True, compute_score=False, verbose=False): + self.n_iter = n_iter + self.start = start + self.tol = tol + self.scores_ = list() + self.fit_intercept = fit_intercept + self.normalize = normalize + self.copy_X = copy_X + self.compute_score = compute_score + self.verbose = verbose + + def _preprocess_data(self, X, y): + """Center and scale data. + Centers data to have mean zero along axis 0. If fit_intercept=False or + if the X is a sparse matrix, no centering is done, but normalization + can still be applied. The function returns the statistics necessary to + reconstruct the input data, which are X_offset, y_offset, X_scale, such + that the output + X = (X - X_offset) / X_scale + X_scale is the L2 norm of X - X_offset. + """ + + if self.copy_X: + X = X.copy(order='K') + + y = np.asarray(y, dtype=X.dtype) + + if self.fit_intercept: + X_offset = np.average(X, axis=0) + X -= X_offset + if self.normalize: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + std = np.sqrt(np.sum(X**2, axis=0)/(len(X)-1)) + X_scale[std != 0] = std[std != 0] + X /= X_scale + else: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + y_offset = np.mean(y) + y = y - y_offset + else: + X_offset = np.zeros(X.shape[1], dtype=X.dtype) + X_scale = np.ones(X.shape[1], dtype=X.dtype) + if y.ndim == 1: + y_offset = X.dtype.type(0) + else: + y_offset = np.zeros(y.shape[1], dtype=X.dtype) + + return X, y, X_offset, y_offset, X_scale + + def fit(self, X, y): + ''' + Fits ARD Regression with Sequential Sparse Bayes Algorithm. + + Parameters + ----------- + X: {array-like, sparse matrix} of size (n_samples, n_features) + Training data, matrix of explanatory variables + + y: array-like of size [n_samples, n_features] + Target values + + Returns + ------- + self : object + Returns self. + ''' + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._preprocess_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # precompute X'*Y , X'*X for faster iterations & allocate memory for + # sparsity & quality vectors + XY = np.dot(X.T, y) + XX = np.dot(X.T, X) + XXd = np.diag(XX) + + # initialise precision of noise & and coefficients + var_y = np.var(y) + + # check that variance is non zero !!! + if var_y == 0: + beta = 1e-2 + self.var_y = True + else: + beta = 1. / np.var(y) + self.var_y = False + + A = np.PINF * np.ones(n_features) + active = np.zeros(n_features, dtype=np.bool) + + if self.start is not None and not hasattr(self, 'active_'): + start = self.start + # start from a given start basis vector + proj = XY**2 / XXd + active[start] = True + A[start] = XXd[start]/(proj[start] - var_y) + + else: + # in case of almost perfect multicollinearity between some features + # start from feature 0 + if np.sum(XXd - X_mean**2 < np.finfo(np.float32).eps) > 0: + A[0] = np.finfo(np.float16).eps + active[0] = True + + else: + # start from a single basis vector with largest projection on + # targets + proj = XY**2 / XXd + start = np.argmax(proj) + active[start] = True + A[start] = XXd[start]/(proj[start] - var_y + + np.finfo(np.float32).eps) + + warning_flag = 0 + scores_ = [] + for i in range(self.n_iter): + # Handle variance zero + if self.var_y: + A[0] = y_mean + active[0] = True + converged = True + break + + XXa = XX[active, :][:, active] + XYa = XY[active] + Aa = A[active] + + # mean & covariance of posterior distribution + Mn, Ri, cholesky = self._posterior_dist(Aa, beta, XXa, XYa) + if cholesky: + Sdiag = np.sum(Ri**2, 0) + else: + Sdiag = np.copy(np.diag(Ri)) + warning_flag += 1 + + # raise warning in case cholesky fails + if warning_flag == 1: + warnings.warn(("Cholesky decomposition failed! Algorithm uses " + "pinvh, which is significantly slower. If you " + "use RVR it is advised to change parameters of " + "the kernel!")) + + # compute quality & sparsity parameters + s, q, S, Q = self._sparsity_quality(XX, XXd, XY, XYa, Aa, Ri, + active, beta, cholesky) + + # update precision parameter for noise distribution + rss = np.sum((y - np.dot(X[:, active], Mn))**2) + + # if near perfect fit , then terminate + if (rss / n_samples/var_y) < self.tol: + warnings.warn('Early termination due to near perfect fit') + converged = True + break + beta = n_samples - np.sum(active) + np.sum(Aa * Sdiag) + beta /= rss + # beta /= (rss + np.finfo(np.float32).eps) + + # update precision parameters of coefficients + A, converged = update_precisions(Q, S, q, s, A, active, self.tol, + n_samples, False) + + if self.compute_score: + scores_.append(self.log_marginal_like(XXa, XYa, Aa, beta)) + + if self.verbose: + print(('Iteration: {0}, number of features ' + 'in the model: {1}').format(i, np.sum(active))) + + if converged or i == self.n_iter - 1: + if converged and self.verbose: + print('Algorithm converged!') + break + + # after last update of alpha & beta update parameters + # of posterior distribution + XXa, XYa, Aa = XX[active, :][:, active], XY[active], A[active] + Mn, Sn, cholesky = self._posterior_dist(Aa, beta, XXa, XYa, True) + self.coef_ = np.zeros(n_features) + self.coef_[active] = Mn + self.sigma_ = Sn + self.active_ = active + self.lambda_ = A + self.alpha_ = beta + self.converged = converged + if self.compute_score: + self.scores_ = np.array(scores_) + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + return self + + def log_marginal_like(self, XXa, XYa, Aa, beta): + """Computes the log of the marginal likelihood.""" + N, M = XXa.shape + A = np.diag(Aa) + + Mn, sigma_, cholesky = self._posterior_dist(Aa, beta, XXa, XYa, + full_covar=True) + + C = sigma_ + np.dot(np.dot(XXa.T, np.linalg.pinv(A)), XXa) + + score = np.dot(np.dot(XYa.T, np.linalg.pinv(C)), XYa) +\ + np.log(np.linalg.det(C)) + N * np.log(2 * np.pi) + + return -0.5 * score + + def predict(self, X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance based on + Ref.[1] Section 3.3.2. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + References + ---------- + [1] Bishop, C. M. (2006). Pattern recognition and machine learning. + springer. + ''' + + y_hat = np.dot(X, self.coef_) + self.intercept_ + + if return_std: + # Handle the zero variance case + if self.var_y: + return y_hat, np.zeros_like(y_hat) + + if self.normalize: + X -= self._x_mean_[self.active_] + X /= self._x_std[self.active_] + var_hat = 1./self.alpha_ + var_hat += np.sum(X.dot(self.sigma_) * X, axis=1) + std_hat = np.sqrt(var_hat) + return y_hat, std_hat + else: + return y_hat + + def _posterior_dist(self, A, beta, XX, XY, full_covar=False): + ''' + Calculates mean and covariance matrix of posterior distribution + of coefficients. + ''' + # compute precision matrix for active features + Sinv = beta * XX + np.fill_diagonal(Sinv, np.diag(Sinv) + A) + cholesky = True + + # try cholesky, if it fails go back to pinvh + try: + # find posterior mean : R*R.T*mean = beta*X.T*Y + # solve(R*z = beta*X.T*Y) =>find z=> solve(R.T*mean = z)=>find mean + R = np.linalg.cholesky(Sinv) + Z = solve_triangular(R, beta*XY, check_finite=True, lower=True) + Mn = solve_triangular(R.T, Z, check_finite=True, lower=False) + + # invert lower triangular matrix from cholesky decomposition + Ri = solve_triangular(R, np.eye(A.shape[0]), check_finite=False, + lower=True) + if full_covar: + Sn = np.dot(Ri.T, Ri) + return Mn, Sn, cholesky + else: + return Mn, Ri, cholesky + except LinAlgError: + cholesky = False + Sn = pinvh(Sinv) + Mn = beta*np.dot(Sinv, XY) + return Mn, Sn, cholesky + + def _sparsity_quality(self, XX, XXd, XY, XYa, Aa, Ri, active, beta, cholesky): + ''' + Calculates sparsity and quality parameters for each feature + + Theoretical Note: + ----------------- + Here we used Woodbury Identity for inverting covariance matrix + of target distribution + C = 1/beta + 1/alpha * X' * X + C^-1 = beta - beta^2 * X * Sn * X' + ''' + bxy = beta*XY + bxx = beta*XXd + if cholesky: + # here Ri is inverse of lower triangular matrix obtained from + # cholesky decomp + xxr = np.dot(XX[:, active], Ri.T) + rxy = np.dot(Ri, XYa) + S = bxx - beta**2 * np.sum(xxr**2, axis=1) + Q = bxy - beta**2 * np.dot(xxr, rxy) + else: + # here Ri is covariance matrix + XXa = XX[:, active] + XS = np.dot(XXa, Ri) + S = bxx - beta**2 * np.sum(XS*XXa, 1) + Q = bxy - beta**2 * np.dot(XS, XYa) + # Use following: + # (EQ 1) q = A*Q/(A - S) ; s = A*S/(A-S) + # so if A = np.PINF q = Q, s = S + qi = np.copy(Q) + si = np.copy(S) + # If A is not np.PINF, then it should be 'active' feature => use (EQ 1) + Qa, Sa = Q[active], S[active] + qi[active] = Aa * Qa / (Aa - Sa) + si[active] = Aa * Sa / (Aa - Sa) + + return [si, qi, S, Q] diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_laplace.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_laplace.py new file mode 100644 index 000000000..7fdcb5cf6 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/reg_fast_laplace.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import numpy as np +from sklearn.utils import as_float_array +from sklearn.model_selection import KFold + + +class RegressionFastLaplace(): + ''' + Sparse regression with Bayesian Compressive Sensing as described in Alg. 1 + (Fast Laplace) of Ref.[1], which updated formulas from [2]. + + sigma2: noise precision (sigma^2) + nu fixed to 0 + + uqlab/lib/uq_regression/BCS/uq_bsc.m + + Parameters + ---------- + n_iter: int, optional (DEFAULT = 1000) + Maximum number of iterations + + tol: float, optional (DEFAULT = 1e-7) + If absolute change in precision parameter for weights is below + threshold algorithm terminates. + + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + alpha_ : float + estimated precision of the noise + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + lambda_ : array, shape = (n_features) + estimated precisions of the coefficients + + sigma_ : array, shape = (n_features, n_features) + estimated covariance matrix of the weights, computed only + for non-zero coefficients + + References + ---------- + [1] Babacan, S. D., Molina, R., & Katsaggelos, A. K. (2009). Bayesian + compressive sensing using Laplace priors. IEEE Transactions on image + processing, 19(1), 53-63. + [2] Fast marginal likelihood maximisation for sparse Bayesian models + (Tipping & Faul 2003). + (http://www.miketipping.com/papers/met-fastsbl.pdf) + ''' + + def __init__(self, n_iter=1000, n_Kfold=10, tol=1e-7, fit_intercept=False, + bias_term=True, copy_X=True, verbose=False): + self.n_iter = n_iter + self.n_Kfold = n_Kfold + self.tol = tol + self.fit_intercept = fit_intercept + self.bias_term = bias_term + self.copy_X = copy_X + self.verbose = verbose + + def _center_data(self, X, y): + ''' Centers data''' + X = as_float_array(X, copy = self.copy_X) + + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype=X.dtype) + if self.fit_intercept: + X_mean = np.average(X, axis=0) + y_mean = np.average(y, axis=0) + X -= X_mean + y -= y_mean + else: + X_mean = np.zeros(X.shape[1], dtype=X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X, y, X_mean, y_mean, X_std + + def fit(self, X, y): + + k_fold = KFold(n_splits=self.n_Kfold) + + varY = np.var(y, ddof=1) if np.var(y, ddof=1) != 0 else 1.0 + sigma2s = len(y)*varY*(10**np.linspace(-16, -1, self.n_Kfold)) + + errors = np.zeros((len(sigma2s), self.n_Kfold)) + for s, sigma2 in enumerate(sigma2s): + for k, (train, test) in enumerate(k_fold.split(X, y)): + self.fit_(X[train], y[train], sigma2) + errors[s, k] = np.linalg.norm( + y[test] - self.predict(X[test]) + )**2/len(test) + + KfCVerror = np.sum(errors, axis=1)/self.n_Kfold/varY + i_minCV = np.argmin(KfCVerror) + + self.kfoldCVerror = np.min(KfCVerror) + + return self.fit_(X, y, sigma2s[i_minCV]) + + def fit_(self, X, y, sigma2): + + N, P = X.shape + # n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # check that variance is non zero !!! + if np.var(y) == 0: + self.var_y = True + else: + self.var_y = False + beta = 1./sigma2 + + # precompute X'*Y , X'*X for faster iterations & allocate memory for + # sparsity & quality vectors X=Psi + PsiTY = np.dot(X.T, y) + PsiTPsi = np.dot(X.T, X) + XXd = np.diag(PsiTPsi) + + # initialize with constant regressor, or if that one does not exist, + # with the one that has the largest correlation with Y + ind_global_to_local = np.zeros(P, dtype=np.int32) + + # identify constant regressors + constidx = np.where(~np.diff(X, axis=0).all(axis=0))[0] + + if self.bias_term and constidx.size != 0: + ind_start = constidx[0] + ind_global_to_local[ind_start] = True + else: + # start from a single basis vector with largest projection on + # targets + proj = np.divide(np.square(PsiTY), XXd) + ind_start = np.argmax(proj) + ind_global_to_local[ind_start] = True + + num_active = 1 + active_indices = [ind_start] + deleted_indices = [] + bcs_path = [ind_start] + gamma = np.zeros(P) + # for the initial value of gamma(ind_start), use the RVM formula + # gamma = (q^2 - s) / (s^2) + # and the fact that initially s = S = beta*Psi_i'*Psi_i and q = Q = + # beta*Psi_i'*Y + gamma[ind_start] = np.square(PsiTY[ind_start]) + gamma[ind_start] -= sigma2 * PsiTPsi[ind_start, ind_start] + gamma[ind_start] /= np.square(PsiTPsi[ind_start, ind_start]) + + Sigma = 1. / (beta * PsiTPsi[ind_start, ind_start] + + 1./gamma[ind_start]) + + mu = Sigma * PsiTY[ind_start] * beta + tmp1 = beta * PsiTPsi[ind_start] + S = beta * np.diag(PsiTPsi).T - Sigma * np.square(tmp1) + Q = beta * PsiTY.T - mu*(tmp1) + + tmp2 = np.ones(P) # alternative computation for the initial s,q + q0tilde = PsiTY[ind_start] + s0tilde = PsiTPsi[ind_start, ind_start] + tmp2[ind_start] = s0tilde / (q0tilde**2) / beta + s = np.divide(S, tmp2) + q = np.divide(Q, tmp2) + Lambda = 2*(num_active - 1) / np.sum(gamma) + + Delta_L_max = [] + for i in range(self.n_iter): + # Handle variance zero + if self.var_y: + mu = np.mean(y) + break + + if self.verbose: + print(' lambda = {0:.6e}\n'.format(Lambda)) + + # Calculate the potential updated value of each gamma[i] + if Lambda == 0.0: # RVM + gamma_potential = np.multiply(( + (q**2 - s) > Lambda), + np.divide(q**2 - s, s**2) + ) + else: + a = Lambda * s**2 + b = s**2 + 2*Lambda*s + c = Lambda + s - q**2 + gamma_potential = np.multiply( + (c < 0), np.divide( + -b + np.sqrt(b**2 - 4*np.multiply(a, c)), 2*a) + ) + + l_gamma = - np.log(np.absolute(1 + np.multiply(gamma, s))) + l_gamma += np.divide(np.multiply(q**2, gamma), + (1 + np.multiply(gamma, s))) + l_gamma -= Lambda*gamma # omitted the factor 1/2 + + # Contribution of each updated gamma(i) to L(gamma) + l_gamma_potential = - np.log( + np.absolute(1 + np.multiply(gamma_potential, s)) + ) + l_gamma_potential += np.divide( + np.multiply(q**2, gamma_potential), + (1 + np.multiply(gamma_potential, s)) + ) + # omitted the factor 1/2 + l_gamma_potential -= Lambda*gamma_potential + + # Check how L(gamma) would change if we replaced gamma(i) by the + # updated gamma_potential(i), for each i separately + Delta_L_potential = l_gamma_potential - l_gamma + + # deleted indices should not be chosen again + if len(deleted_indices) != 0: + values = -np.inf * np.ones(len(deleted_indices)) + Delta_L_potential[deleted_indices] = values + + Delta_L_max.append(np.nanmax(Delta_L_potential)) + ind_L_max = np.nanargmax(Delta_L_potential) + + # in case there is only 1 regressor in the model and it would now + # be deleted + if len(active_indices) == 1 and ind_L_max == active_indices[0] \ + and gamma_potential[ind_L_max] == 0.0: + Delta_L_potential[ind_L_max] = -np.inf + Delta_L_max[i] = np.max(Delta_L_potential) + ind_L_max = np.argmax(Delta_L_potential) + + # If L did not change significantly anymore, break + if Delta_L_max[i] <= 0.0 or\ + (i > 0 and all(np.absolute(Delta_L_max[i-1:]) + < sum(Delta_L_max)*self.tol)) or \ + (i > 0 and all(np.diff(bcs_path)[i-1:] == 0.0)): + if self.verbose: + print('Increase in L: {0:.6e} (eta = {1:.3e})\ + -- break\n'.format(Delta_L_max[i], self.tol)) + break + + # Print information + if self.verbose: + print(' Delta L = {0:.6e} \n'.format(Delta_L_max[i])) + + what_changed = int(gamma[ind_L_max] == 0.0) + what_changed -= int(gamma_potential[ind_L_max] == 0.0) + + # Print information + if self.verbose: + if what_changed < 0: + print(f'{i+1} - Remove regressor #{ind_L_max+1}..\n') + elif what_changed == 0: + print(f'{i+1} - Recompute regressor #{ind_L_max+1}..\n') + else: + print(f'{i+1} - Add regressor #{ind_L_max+1}..\n') + + # --- Update all quantities ---- + if what_changed == 1: + # adding a regressor + + # update gamma + gamma[ind_L_max] = gamma_potential[ind_L_max] + + Sigma_ii = 1.0 / (1.0/gamma[ind_L_max] + S[ind_L_max]) + try: + x_i = np.matmul( + Sigma, PsiTPsi[active_indices, ind_L_max].reshape(-1, 1) + ) + except ValueError: + x_i = Sigma * PsiTPsi[active_indices, ind_L_max] + tmp_1 = - (beta * Sigma_ii) * x_i + Sigma = np.vstack( + (np.hstack(((beta**2 * Sigma_ii) * np.dot(x_i, x_i.T) + + Sigma, tmp_1)), np.append(tmp_1.T, Sigma_ii)) + ) + mu_i = Sigma_ii * Q[ind_L_max] + mu = np.vstack((mu - (beta * mu_i) * x_i, mu_i)) + + tmp2_1 = PsiTPsi[:, ind_L_max] - beta * np.squeeze( + np.matmul(PsiTPsi[:, active_indices], x_i) + ) + if i == 0: + tmp2_1[0] /= 2 + tmp2 = beta * tmp2_1.T + S = S - Sigma_ii * np.square(tmp2) + Q = Q - mu_i * tmp2 + + num_active += 1 + ind_global_to_local[ind_L_max] = num_active + active_indices.append(ind_L_max) + bcs_path.append(ind_L_max) + + elif what_changed == 0: + # recomputation + # zero if regressor has not been chosen yet + if not ind_global_to_local[ind_L_max]: + raise Exception('Cannot recompute index{0} -- not yet\ + part of the model!'.format(ind_L_max)) + Sigma = np.atleast_2d(Sigma) + mu = np.atleast_2d(mu) + gamma_i_new = gamma_potential[ind_L_max] + gamma_i_old = gamma[ind_L_max] + # update gamma + gamma[ind_L_max] = gamma_potential[ind_L_max] + + # index of regressor in Sigma + local_ind = ind_global_to_local[ind_L_max]-1 + + kappa_i = (1.0/gamma_i_new - 1.0/gamma_i_old) + kappa_i = 1.0 / kappa_i + kappa_i += Sigma[local_ind, local_ind] + kappa_i = 1 / kappa_i + Sigma_i_col = Sigma[:, local_ind] + + Sigma = Sigma - kappa_i * (Sigma_i_col * Sigma_i_col.T) + mu_i = mu[local_ind] + mu = mu - (kappa_i * mu_i) * Sigma_i_col[:, None] + + tmp1 = beta * np.dot( + Sigma_i_col.reshape(1, -1), PsiTPsi[active_indices])[0] + S = S + kappa_i * np.square(tmp1) + Q = Q + (kappa_i * mu_i) * tmp1 + + # no change in active_indices or ind_global_to_local + bcs_path.append(ind_L_max + 0.1) + + elif what_changed == -1: + gamma[ind_L_max] = 0 + + # index of regressor in Sigma + local_ind = ind_global_to_local[ind_L_max]-1 + + Sigma_ii_inv = 1. / Sigma[local_ind, local_ind] + Sigma_i_col = Sigma[:, local_ind] + + Sigma = Sigma - Sigma_ii_inv * (Sigma_i_col * Sigma_i_col.T) + + Sigma = np.delete( + np.delete(Sigma, local_ind, axis=0), local_ind, axis=1) + + mu = mu - (mu[local_ind] * Sigma_ii_inv) * Sigma_i_col[:, None] + mu = np.delete(mu, local_ind, axis=0) + + tmp1 = beta * np.dot(Sigma_i_col, PsiTPsi[active_indices]) + S = S + Sigma_ii_inv * np.square(tmp1) + Q = Q + (mu_i * Sigma_ii_inv) * tmp1 + + num_active -= 1 + ind_global_to_local[ind_L_max] = 0.0 + v = ind_global_to_local[ind_global_to_local > local_ind] - 1 + ind_global_to_local[ind_global_to_local > local_ind] = v + del active_indices[local_ind] + deleted_indices.append(ind_L_max) + # and therefore ineligible + bcs_path.append(-ind_L_max) + + # same for all three cases + tmp3 = 1 - np.multiply(gamma, S) + s = np.divide(S, tmp3) + q = np.divide(Q, tmp3) + + # Update lambda + Lambda = 2*(num_active - 1) / np.sum(gamma) + + # Prepare the result object + self.coef_ = np.zeros(P) + self.coef_[active_indices] = np.squeeze(mu) + self.sigma_ = Sigma + self.active_ = active_indices + self.gamma = gamma + self.Lambda = Lambda + self.beta = beta + self.bcs_path = bcs_path + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self, X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance based on + Ref.[1] Section 3.3.2. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + + References + ---------- + [1] Bishop, C. M. (2006). Pattern recognition and machine learning. + springer. + ''' + y_hat = np.dot(X, self.coef_) + self.intercept_ + + if return_std: + # Handle the zero variance case + if self.var_y: + return y_hat, np.zeros_like(y_hat) + + var_hat = 1./self.beta + var_hat += np.sum(X.dot(self.sigma_) * X, axis=1) + std_hat = np.sqrt(var_hat) + return y_hat, std_hat + else: + return y_hat + +# l2norm = 0.0 +# for idx in range(10): +# sigma2 = np.genfromtxt('./test/sigma2_{0}.csv'.format(idx+1), delimiter=',') +# Psi_train = np.genfromtxt('./test/Psi_train_{0}.csv'.format(idx+1), delimiter=',') +# Y_train = np.genfromtxt('./test/Y_train_{0}.csv'.format(idx+1)) +# Psi_test = np.genfromtxt('./test/Psi_test_{0}.csv'.format(idx+1), delimiter=',') +# Y_test = np.genfromtxt('./test/Y_test_{0}.csv'.format(idx+1)) + +# clf = RegressionFastLaplace(verbose=True) +# clf.fit_(Psi_train, Y_train, sigma2) +# coeffs_fold = np.genfromtxt('./test/coeffs_fold_{0}.csv'.format(idx+1)) +# print("coeffs error: {0:.4g}".format(np.linalg.norm(clf.coef_ - coeffs_fold))) +# l2norm += np.linalg.norm(Y_test - clf.predict(Psi_test))**2/len(Y_test) +# print("l2norm error: {0:.4g}".format(l2norm)) diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/sequential_design.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/sequential_design.py new file mode 100644 index 000000000..e1feb7317 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/sequential_design.py @@ -0,0 +1,2187 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 28 09:21:18 2022 + +@author: farid +""" +import numpy as np +from scipy import stats, signal, linalg, sparse +from scipy.spatial import distance +from copy import deepcopy, copy +from tqdm import tqdm +import scipy.optimize as opt +from sklearn.metrics import mean_squared_error +import multiprocessing +import matplotlib.pyplot as plt +import sys +import os +import gc +import seaborn as sns +from joblib import Parallel, delayed +#import resource +from .exploration import Exploration + + +class SeqDesign(): + """ Sequential experimental design + This class provieds method for trainig the meta-model in an iterative + manners. + The main method to execute the task is `train_seq_design`, which + recieves a model object and returns the trained metamodel. + """ + + # ------------------------------------------------------------------------- + def train_seq_design(self, MetaModel): + """ + Starts the adaptive sequential design for refining the surrogate model + by selecting training points in a sequential manner. + + Parameters + ---------- + Model : object + An object containing all model specifications. + + Returns + ------- + MetaModel : object + Meta model object. + + """ + # MetaModel = self + Model = MetaModel.ModelObj + self.MetaModel = MetaModel + self.Model = Model + + # Initialization + MetaModel.SeqModifiedLOO = {} + MetaModel.seqValidError = {} + MetaModel.SeqBME = {} + MetaModel.SeqKLD = {} + MetaModel.SeqDistHellinger = {} + MetaModel.seqRMSEMean = {} + MetaModel.seqRMSEStd = {} + MetaModel.seqMinDist = [] + pce = True if MetaModel.meta_model_type.lower() != 'gpe' else False + mc_ref = True if bool(Model.mc_reference) else False + if mc_ref: + Model.read_mc_reference() + + if not hasattr(MetaModel, 'valid_likelihoods'): + MetaModel.valid_samples = [] + MetaModel.valid_model_runs = [] + MetaModel.valid_likelihoods = [] + + # Get the parameters + max_n_samples = MetaModel.ExpDesign.n_max_samples + mod_LOO_threshold = MetaModel.ExpDesign.mod_LOO_threshold + n_canddidate = MetaModel.ExpDesign.n_canddidate + post_snapshot = MetaModel.ExpDesign.post_snapshot + n_replication = MetaModel.ExpDesign.n_replication + util_func = MetaModel.ExpDesign.util_func + output_name = Model.Output.names + validError = None + # Handle if only one UtilityFunctions is provided + if not isinstance(util_func, list): + util_func = [MetaModel.ExpDesign.util_func] + + # Read observations or MCReference + if len(Model.observations) != 0 or Model.meas_file is not None: + self.observations = Model.read_observation() + obs_data = self.observations + else: + obs_data = [] + TotalSigma2 = {} + # ---------- Initial MetaModel ---------- + initMetaModel = deepcopy(MetaModel) + + # Validation error if validation set is provided. + if len(MetaModel.valid_model_runs) != 0: + init_rmse, init_valid_error = self.__validError(initMetaModel) + init_valid_error = list(init_valid_error.values()) + else: + init_rmse = None + + # Check if discrepancy is provided + if len(obs_data) != 0 and hasattr(MetaModel, 'Discrepancy'): + TotalSigma2 = MetaModel.Discrepancy.parameters + + # Calculate the initial BME + out = self.__BME_Calculator( + initMetaModel, obs_data, TotalSigma2, init_rmse) + init_BME, init_KLD, init_post, init_likes, init_dist_hellinger = out + print(f"\nInitial BME: {init_BME:.2f}") + print(f"Initial KLD: {init_KLD:.2f}") + + # Posterior snapshot (initial) + if post_snapshot: + parNames = MetaModel.ExpDesign.par_names + print('Posterior snapshot (initial) is being plotted...') + self.__posteriorPlot(init_post, parNames, 'SeqPosterior_init') + + # Check the convergence of the Mean & Std + if mc_ref and pce: + init_rmse_mean, init_rmse_std = self.__error_Mean_Std() + print(f"Initial Mean and Std error: {init_rmse_mean}," + f" {init_rmse_std}") + + # Read the initial experimental design + Xinit = initMetaModel.ExpDesign.X + init_n_samples = len(MetaModel.ExpDesign.X) + initYprev = initMetaModel.ModelOutputDict + initLCerror = initMetaModel.LCerror + n_itrs = max_n_samples - init_n_samples + + # Read the initial ModifiedLOO + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = initMetaModel.ExpDesign.Y[out_name] + Scores_all.append(list( + initMetaModel.score_dict['b_1'][out_name].values())) + if MetaModel.dim_red_method.lower() == 'pca': + pca = MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + + Scores = [item for sublist in Scores_all for item in sublist] + weights = [item for sublist in varExpDesignY for item in sublist] + init_mod_LOO = [np.average([1-score for score in Scores], + weights=weights)] + + prevMetaModel_dict = {} + # Replicate the sequential design + for repIdx in range(n_replication): + print(f'\n>>>> Replication: {repIdx+1}<<<<') + + # To avoid changes ub original aPCE object + MetaModel.ExpDesign.X = Xinit + MetaModel.ExpDesign.Y = initYprev + MetaModel.LCerror = initLCerror + + for util_f in util_func: + print(f'\n>>>> Utility Function: {util_f} <<<<') + # To avoid changes ub original aPCE object + MetaModel.ExpDesign.X = Xinit + MetaModel.ExpDesign.Y = initYprev + MetaModel.LCerror = initLCerror + + # Set the experimental design + Xprev = Xinit + total_n_samples = init_n_samples + Yprev = initYprev + + Xfull = [] + Yfull = [] + + # Store the initial ModifiedLOO + if pce: + print("\nInitial ModifiedLOO:", init_mod_LOO) + SeqModifiedLOO = np.array(init_mod_LOO) + + if len(MetaModel.valid_model_runs) != 0: + SeqValidError = np.array(init_valid_error) + + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.array([init_BME]) + SeqKLD = np.array([init_KLD]) + SeqDistHellinger = np.array([init_dist_hellinger]) + + if mc_ref and pce: + seqRMSEMean = np.array([init_rmse_mean]) + seqRMSEStd = np.array([init_rmse_std]) + + # ------- Start Sequential Experimental Design ------- + postcnt = 1 + for itr_no in range(1, n_itrs+1): + print(f'\n>>>> Iteration number {itr_no} <<<<') + + # Save the metamodel prediction before updating + prevMetaModel_dict[itr_no] = deepcopy(MetaModel) + if itr_no > 1: + pc_model = prevMetaModel_dict[itr_no-1] + self._y_hat_prev, _ = pc_model.eval_metamodel( + samples=Xfull[-1].reshape(1, -1)) + + # Optimal Bayesian Design + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + MetaModel.ExpDesignFlag = 'sequential' + Xnew, updatedPrior = self.opt_SeqDesign(TotalSigma2, + n_canddidate, + util_f) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + S = np.min(distance.cdist(Xinit, Xnew, 'euclidean')) + MetaModel.seqMinDist.append(S) + print(f"\nmin Dist from OldExpDesign: {S:2f}") + print("\n") + + # Evaluate the full model response at the new sample + Ynew, _ = Model.run_model_parallel( + Xnew, prevRun_No=total_n_samples + ) + total_n_samples += Xnew.shape[0] + # ------ Plot the surrogate model vs Origninal Model ------ + if hasattr(MetaModel, 'adapt_verbose') and \ + MetaModel.adapt_verbose: + from .adaptPlot import adaptPlot + y_hat, std_hat = MetaModel.eval_metamodel(samples=Xnew) + adaptPlot(MetaModel, Ynew, y_hat, std_hat, plotED=False) + + # -------- Retrain the surrogate model ------- + # Extend new experimental design + Xfull = np.vstack((Xprev, Xnew)) + + # Updating experimental design Y + for out_name in output_name: + Yfull = np.vstack((Yprev[out_name], Ynew[out_name])) + MetaModel.ModelOutputDict[out_name] = Yfull + + # Pass new design to the metamodel object + MetaModel.ExpDesign.sampling_method = 'user' + MetaModel.ExpDesign.X = Xfull + MetaModel.ExpDesign.Y = MetaModel.ModelOutputDict + + # Save the Experimental Design for next iteration + Xprev = Xfull + Yprev = MetaModel.ModelOutputDict + + # Pass the new prior as the input + MetaModel.input_obj.poly_coeffs_flag = False + if updatedPrior is not None: + MetaModel.input_obj.poly_coeffs_flag = True + print("updatedPrior:", updatedPrior.shape) + # Arbitrary polynomial chaos + for i in range(updatedPrior.shape[1]): + MetaModel.input_obj.Marginals[i].dist_type = None + x = updatedPrior[:, i] + MetaModel.input_obj.Marginals[i].raw_data = x + + # Train the surrogate model for new ExpDesign + MetaModel.train_norm_design(parallel=False) + m_3 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + + # -------- Evaluate the retrained surrogate model ------- + # Extract Modified LOO from Output + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = MetaModel.ExpDesign.Y[out_name] + Scores_all.append(list( + MetaModel.score_dict['b_1'][out_name].values())) + if MetaModel.dim_red_method.lower() == 'pca': + pca = MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, + axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + Scores = [item for sublist in Scores_all for item + in sublist] + weights = [item for sublist in varExpDesignY for item + in sublist] + ModifiedLOO = [np.average( + [1-score for score in Scores], weights=weights)] + + print('\n') + print(f"Updated ModifiedLOO {util_f}:\n", ModifiedLOO) + print('\n') + + # Compute the validation error + if len(MetaModel.valid_model_runs) != 0: + rmse, validError = self.__validError(MetaModel) + ValidError = list(validError.values()) + else: + rmse = None + + # Store updated ModifiedLOO + if pce: + SeqModifiedLOO = np.vstack( + (SeqModifiedLOO, ModifiedLOO)) + if len(MetaModel.valid_model_runs) != 0: + SeqValidError = np.vstack( + (SeqValidError, ValidError)) + m_4 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + # -------- Caclulation of BME as accuracy metric ------- + # Check if data is provided + if len(obs_data) != 0: + # Calculate the initial BME + out = self.__BME_Calculator(MetaModel, obs_data, + TotalSigma2, rmse) + BME, KLD, Posterior, likes, DistHellinger = out + print('\n') + print(f"Updated BME: {BME:.2f}") + print(f"Updated KLD: {KLD:.2f}") + print('\n') + + # Plot some snapshots of the posterior + step_snapshot = MetaModel.ExpDesign.step_snapshot + if post_snapshot and postcnt % step_snapshot == 0: + parNames = MetaModel.ExpDesign.par_names + print('Posterior snapshot is being plotted...') + self.__posteriorPlot(Posterior, parNames, + f'SeqPosterior_{postcnt}') + postcnt += 1 + m_5 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + + # Check the convergence of the Mean&Std + if mc_ref and pce: + print('\n') + RMSE_Mean, RMSE_std = self.__error_Mean_Std() + print(f"Updated Mean and Std error: {RMSE_Mean:.2f}, " + f"{RMSE_std:.2f}") + print('\n') + + # Store the updated BME & KLD + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.vstack((SeqBME, BME)) + SeqKLD = np.vstack((SeqKLD, KLD)) + SeqDistHellinger = np.vstack((SeqDistHellinger, + DistHellinger)) + if mc_ref and pce: + seqRMSEMean = np.vstack((seqRMSEMean, RMSE_Mean)) + seqRMSEStd = np.vstack((seqRMSEStd, RMSE_std)) + + if pce and any(LOO < mod_LOO_threshold + for LOO in ModifiedLOO): + break + + print(f"Memory itr {itr_no}: I: {m_2-m_1:.2f} MB") + print(f"Memory itr {itr_no}: II: {m_3-m_2:.2f} MB") + print(f"Memory itr {itr_no}: III: {m_4-m_3:.2f} MB") + print(f"Memory itr {itr_no}: IV: {m_5-m_4:.2f} MB") + m_6 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"Memory itr {itr_no}: total: {m_6:.2f} MB") + + # Clean up + if len(obs_data) != 0: + del out + gc.collect() + print() + print('-'*50) + print() + + # Store updated ModifiedLOO and BME in dictonary + strKey = f'{util_f}_rep_{repIdx+1}' + if pce: + MetaModel.SeqModifiedLOO[strKey] = SeqModifiedLOO + if len(MetaModel.valid_model_runs) != 0: + MetaModel.seqValidError[strKey] = SeqValidError + + # Check if data is provided + if len(obs_data) != 0: + MetaModel.SeqBME[strKey] = SeqBME + MetaModel.SeqKLD[strKey] = SeqKLD + if len(MetaModel.valid_likelihoods) != 0: + MetaModel.SeqDistHellinger[strKey] = SeqDistHellinger + if mc_ref and pce: + MetaModel.seqRMSEMean[strKey] = seqRMSEMean + MetaModel.seqRMSEStd[strKey] = seqRMSEStd + + return MetaModel + + # ------------------------------------------------------------------------- + def util_VarBasedDesign(self, X_can, index, util_func='Entropy'): + """ + Computes the exploitation scores based on: + active learning MacKay(ALM) and active learning Cohn (ALC) + Paper: Sequential Design with Mutual Information for Computer + Experiments (MICE): Emulation of a Tsunami Model by Beck and Guillas + (2016) + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + index : int + Model output index. + UtilMethod : string, optional + Exploitation utility function. The default is 'Entropy'. + + Returns + ------- + float + Score. + + """ + MetaModel = self.MetaModel + ED_X = MetaModel.ExpDesign.X + out_dict_y = MetaModel.ExpDesign.Y + out_names = MetaModel.ModelObj.Output.names + + # Run the Metamodel for the candidate + X_can = X_can.reshape(1, -1) + Y_PC_can, std_PC_can = MetaModel.eval_metamodel(samples=X_can) + + if util_func.lower() == 'alm': + # ----- Entropy/MMSE/active learning MacKay(ALM) ----- + # Compute perdiction variance of the old model + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + varPCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + varPCE[KeyIdx] = np.max(canPredVar[key], axis=1) + score = np.max(varPCE, axis=0) + + elif util_func.lower() == 'eigf': + # ----- Expected Improvement for Global fit ----- + # Find closest EDX to the candidate + distances = distance.cdist(ED_X, X_can, 'euclidean') + index = np.argmin(distances) + + # Compute perdiction error and variance of the old model + predError = {key: Y_PC_can[key] for key in out_names} + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + # Compute perdiction error and variance of the old model + # Eq (5) from Liu et al.(2018) + EIGF_PCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + residual = predError[key] - out_dict_y[key][int(index)] + var = canPredVar[key] + EIGF_PCE[KeyIdx] = np.max(residual**2 + var, axis=1) + score = np.max(EIGF_PCE, axis=0) + + return -1 * score # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianActiveDesign(self, X_can, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian active design criterion (var). + + It is based on the following paper: + Oladyshkin, Sergey, Farid Mohammadi, Ilja Kroeker, and Wolfgang Nowak. + "Bayesian3 active learning for the gaussian process emulator using + information theory." Entropy 22, no. 8 (2020): 890. + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + BAL design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # Evaluate the PCE metamodels at that location ??? + Y_mean_can, Y_std_can = self.MetaModel.eval_metamodel( + samples=np.array([X_can]) + ) + + # Get the data + obs_data = self.observations + n_obs = self.Model.n_obs + # TODO: Analytical DKL + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + + # priorMean, priorSigma2, Obs = np.empty((0)),np.empty((0)),np.empty((0)) + + # for key in list(Y_mean_can): + # # concatenate the measurement error + # Obs = np.hstack((Obs,ObservationData[key])) + + # # concatenate the mean and variance of prior predictive + # means, stds = Y_mean_can[key][0], Y_std_can[key][0] + # priorMean = np.hstack((priorSigma2,means)) + # priorSigma2 = np.hstack((priorSigma2,stds**2)) + + # # Covariance Matrix of prior + # covPrior = np.zeros((priorSigma2.shape[0], priorSigma2.shape[0]), float) + # np.fill_diagonal(covPrior, priorSigma2) + + # # Covariance Matrix of Likelihood + # covLikelihood = np.zeros((sigma2Dict.shape[0], sigma2Dict.shape[0]), float) + # np.fill_diagonal(covLikelihood, sigma2Dict) + + # # Calculate moments of the posterior (Analytical derivation) + # n = priorSigma2.shape[0] + # covPost = np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))),covLikelihood/n) + + # meanPost = np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))) , Obs) + \ + # np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))), + # priorMean/n) + # # Compute DKL from prior to posterior + # term1 = np.trace(np.dot(np.linalg.inv(covPrior),covPost)) + # deltaMean = priorMean-meanPost + # term2 = np.dot(np.dot(deltaMean,np.linalg.inv(covPrior)),deltaMean[:,None]) + # term3 = np.log(np.linalg.det(covPrior)/np.linalg.det(covPost)) + # DKL = 0.5 * (term1 + term2 - n + term3)[0] + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = 20000 + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + Y_MC, std_MC = {}, {} + logPriorLikelihoods = np.zeros((MCsize)) + for key in list(Y_mean_can): + means, stds = Y_mean_can[key][0], Y_std_can[key][0] + # cov = np.zeros((means.shape[0], means.shape[0]), float) + # np.fill_diagonal(cov, stds**2) + + Y_MC[key] = np.zeros((MCsize, n_obs)) + logsamples = np.zeros((MCsize, n_obs)) + for i in range(n_obs): + NormalDensity = stats.norm(means[i], stds[i]) + Y_MC[key][:, i] = NormalDensity.rvs(MCsize) + logsamples[:, i] = NormalDensity.logpdf(Y_MC[key][:, i]) + + logPriorLikelihoods = np.sum(logsamples, axis=1) + std_MC[key] = np.zeros((MCsize, means.shape[0])) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self.__normpdf(Y_MC, std_MC, obs_data, sigma2Dict) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.nansum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + # Utility function Eq.2 in Ref. (2) + # Posterior covariance matrix after observing data y + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # TODO: Calculate the correction factor for BME + # BMECorrFactor = self.BME_Corr_Weight(PCE_SparseBayes_can, + # ObservationData, sigma2Dict) + # BME += BMECorrFactor + # Haun et al implementation + # U_J_d = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + U_J_d = postExpLikelihoods - logBME + + # Marginal log likelihood + elif var == 'BME': + U_J_d = logBME + + # Entropy-based information gain + elif var == 'infEntropy': + logBME = np.log(np.nanmean(likelihoods)) + infEntropy = logBME - postExpPrior - postExpLikelihoods + U_J_d = infEntropy * -1 # -1 for minimization + + # Bayesian information criterion + elif var == 'BIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxL = np.nanmax(likelihoods) + U_J_d = -2 * np.log(maxL) + np.log(n_obs) * nModelParams + + # Akaike information criterion + elif var == 'AIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxlogL = np.log(np.nanmax(likelihoods)) + AIC = -2 * maxlogL + 2 * nModelParams + # 2 * nModelParams * (nModelParams+1) / (n_obs-nModelParams-1) + penTerm = 0 + U_J_d = 1*(AIC + penTerm) + + # Deviance information criterion + elif var == 'DIC': + # D_theta_bar = np.mean(-2 * Likelihoods) + N_star_p = 0.5 * np.var(np.log(likelihoods[likelihoods != 0])) + Likelihoods_theta_mean = self.__normpdf( + Y_mean_can, Y_std_can, obs_data, sigma2Dict + ) + DIC = -2 * np.log(Likelihoods_theta_mean) + 2 * N_star_p + + U_J_d = DIC + + else: + print('The algorithm you requested has not been implemented yet!') + + # Handle inf and NaN (replace by zero) + if np.isnan(U_J_d) or U_J_d == -np.inf or U_J_d == np.inf: + U_J_d = 0.0 + + # Clear memory + del likelihoods + del Y_MC + del std_MC + gc.collect(generation=2) + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def update_metamodel(self, MetaModel, output, y_hat_can, univ_p_val, index, + new_pca=False): + BasisIndices = MetaModel.basis_dict[output]["y_"+str(index+1)] + clf_poly = MetaModel.clf_poly[output]["y_"+str(index+1)] + Mn = clf_poly.coef_ + Sn = clf_poly.sigma_ + beta = clf_poly.alpha_ + active = clf_poly.active_ + Psi = self.MetaModel.create_psi(BasisIndices, univ_p_val) + + Sn_new_inv = np.linalg.inv(Sn) + Sn_new_inv += beta * np.dot(Psi[:, active].T, Psi[:, active]) + Sn_new = np.linalg.inv(Sn_new_inv) + + Mn_new = np.dot(Sn_new_inv, Mn[active]).reshape(-1, 1) + Mn_new += beta * np.dot(Psi[:, active].T, y_hat_can) + Mn_new = np.dot(Sn_new, Mn_new).flatten() + + # Compute the old and new moments of PCEs + mean_old = Mn[0] + mean_new = Mn_new[0] + std_old = np.sqrt(np.sum(np.square(Mn[1:]))) + std_new = np.sqrt(np.sum(np.square(Mn_new[1:]))) + + # Back transformation if PCA is selected. + if MetaModel.dim_red_method.lower() == 'pca': + old_pca = MetaModel.pca[output] + mean_old = old_pca.mean_[index] + mean_old += np.sum(mean_old * old_pca.components_[:, index]) + std_old = np.sqrt(np.sum(std_old**2 * + old_pca.components_[:, index]**2)) + mean_new = new_pca.mean_[index] + mean_new += np.sum(mean_new * new_pca.components_[:, index]) + std_new = np.sqrt(np.sum(std_new**2 * + new_pca.components_[:, index]**2)) + # print(f"mean_old: {mean_old:.2f} mean_new: {mean_new:.2f}") + # print(f"std_old: {std_old:.2f} std_new: {std_new:.2f}") + # Store the old and new moments of PCEs + results = { + 'mean_old': mean_old, + 'mean_new': mean_new, + 'std_old': std_old, + 'std_new': std_new + } + return results + + # ------------------------------------------------------------------------- + def util_BayesianDesign_old(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + Model = self.Model + MetaModel = deepcopy(self.MetaModel) + old_EDY = MetaModel.ExpDesign.Y + + # Evaluate the PCE metamodels using the candidate design + Y_PC_can, Y_std_can = self.MetaModel.eval_metamodel( + samples=np.array([X_can]) + ) + + # Generate y from posterior predictive + m_size = 100 + y_hat_samples = {} + for idx, key in enumerate(Model.Output.names): + means, stds = Y_PC_can[key][0], Y_std_can[key][0] + y_hat_samples[key] = np.random.multivariate_normal( + means, np.diag(stds), m_size) + + # Create the SparseBayes-based PCE metamodel: + MetaModel.input_obj.poly_coeffs_flag = False + univ_p_val = self.MetaModel.univ_basis_vals(X_can) + G_n_m_all = np.zeros((m_size, len(Model.Output.names), Model.n_obs)) + + for i in range(m_size): + for idx, key in enumerate(Model.Output.names): + if MetaModel.dim_red_method.lower() == 'pca': + # Equal number of components + new_outputs = np.vstack( + (old_EDY[key], y_hat_samples[key][i]) + ) + new_pca, _ = MetaModel.pca_transformation(new_outputs) + target = new_pca.transform( + y_hat_samples[key][i].reshape(1, -1) + )[0] + else: + new_pca, target = False, y_hat_samples[key][i] + + for j in range(len(target)): + + # Update surrogate + result = self.update_metamodel( + MetaModel, key, target[j], univ_p_val, j, new_pca) + + # Compute Expected Information Gain (Eq. 39) + G_n_m = np.log(result['std_old']/result['std_new']) - 1./2 + G_n_m += result['std_new']**2 / (2*result['std_old']**2) + G_n_m += (result['mean_new'] - result['mean_old'])**2 /\ + (2*result['std_old']**2) + + G_n_m_all[i, idx, j] = G_n_m + + U_J_d = G_n_m_all.mean(axis=(1, 2)).mean() + return -1 * U_J_d + + # ------------------------------------------------------------------------- + def util_BayesianDesign(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + Model = self.Model + MetaModel = deepcopy(self.MetaModel) + out_names = MetaModel.ModelObj.Output.names + if X_can.ndim == 1: + X_can = X_can.reshape(1, -1) + + # Compute the mean and std based on the MetaModel + # pce_means, pce_stds = self._compute_pce_moments(MetaModel) + if var == 'ALC': + Y_MC, Y_MC_std = MetaModel.eval_metamodel(samples=X_MC) + + # Old Experimental design + oldExpDesignX = MetaModel.ExpDesign.X + oldExpDesignY = MetaModel.ExpDesign.Y + + # Evaluate the PCE metamodels at that location ??? + Y_PC_can, Y_std_can = MetaModel.eval_metamodel(samples=X_can) + + # Add all suggestion as new ExpDesign + NewExpDesignX = np.vstack((oldExpDesignX, X_can)) + + NewExpDesignY = {} + for key in oldExpDesignY.keys(): + try: + NewExpDesignY[key] = np.vstack((oldExpDesignY[key], + Y_PC_can[key])) + except: + NewExpDesignY[key] = oldExpDesignY[key] + + MetaModel.ExpDesign.sampling_method = 'user' + MetaModel.ExpDesign.X = NewExpDesignX + MetaModel.ExpDesign.Y = NewExpDesignY + + # Train the model for the observed data using x_can + MetaModel.input_obj.poly_coeffs_flag = False + MetaModel.train_norm_design(parallel=False) + PCE_Model_can = MetaModel + + if var.lower() == 'mi': + # Mutual information based on Krause et al + # Adapted from Beck & Guillas (MICE) paper + _, std_PC_can = PCE_Model_can.eval_metamodel(samples=X_can) + std_can = {key: std_PC_can[key] for key in out_names} + + std_old = {key: Y_std_can[key] for key in out_names} + + varPCE = np.zeros((len(out_names))) + for i, key in enumerate(out_names): + varPCE[i] = np.mean(std_old[key]**2/std_can[key]**2) + score = np.mean(varPCE) + + return -1 * score + + elif var.lower() == 'alc': + # Active learning based on Gramyc and Lee + # Adaptive design and analysis of supercomputer experiments Techno- + # metrics, 51 (2009), pp. 130–145. + + # Evaluate the MetaModel at the given samples + Y_MC_can, Y_MC_std_can = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Compute the score + score = [] + for i, key in enumerate(out_names): + pce_var = Y_MC_std_can[key]**2 + pce_var_can = Y_MC_std[key]**2 + score.append(np.mean(pce_var-pce_var_can, axis=0)) + score = np.mean(score) + + return -1 * score + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = X_MC.shape[0] + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Enriching Monte Carlo samples if need be + if ESS != 0: + X_MC = self.MetaModel.ExpDesign.generate_samples( + MCsize, 'random' + ) + + # Evaluate the MetaModel at the given samples + Y_MC, std_MC = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self.__normpdf( + Y_MC, std_MC, self.observations, sigma2Dict + ) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.sum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + print("--- increasing MC size---") + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # -------------------- Utility functions -------------------- + # Utility function Eq.2 in Ref. (2) + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods, dtype=np.float128)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Haun et al implementation + U_J_d = np.mean(np.log(likelihoods[likelihoods != 0]) - logBME) + + # U_J_d = np.sum(G_n_m_all) + # Ryan et al (2014) implementation + # importanceWeights = Likelihoods[Likelihoods!=0]/np.sum(Likelihoods[Likelihoods!=0]) + # U_J_d = np.mean(importanceWeights*np.log(Likelihoods[Likelihoods!=0])) - logBME + + # U_J_d = postExpLikelihoods - logBME + + # Marginal likelihood + elif var == 'BME': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + U_J_d = logBME + + # Bayes risk likelihood + elif var == 'BayesRisk': + + U_J_d = -1 * np.var(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] / np.nansum(likelihoods[accepted]) + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + infEntropy = logBME - postExpPrior - postExpLikelihoods + + U_J_d = infEntropy * -1 # -1 for minimization + + # D-Posterior-precision + elif var == 'DPP': + X_Posterior = X_MC[accepted] + # covariance of the posterior parameters + U_J_d = -np.log(np.linalg.det(np.cov(X_Posterior))) + + # A-Posterior-precision + elif var == 'APP': + X_Posterior = X_MC[accepted] + # trace of the posterior parameters + U_J_d = -np.log(np.trace(np.cov(X_Posterior))) + + else: + print('The algorithm you requested has not been implemented yet!') + + # Clear memory + del likelihoods + del Y_MC + del std_MC + gc.collect(generation=2) + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def subdomain(self, Bounds, n_new_samples): + """ + Divides a domain defined by Bounds into sub domains. + + Parameters + ---------- + Bounds : list of tuples + List of lower and upper bounds. + n_new_samples : TYPE + DESCRIPTION. + + Returns + ------- + Subdomains : TYPE + DESCRIPTION. + + """ + n_params = self.MetaModel.n_params + n_subdomains = n_new_samples + 1 + LinSpace = np.zeros((n_params, n_subdomains)) + + for i in range(n_params): + LinSpace[i] = np.linspace(start=Bounds[i][0], stop=Bounds[i][1], + num=n_subdomains) + Subdomains = [] + for k in range(n_subdomains-1): + mylist = [] + for i in range(n_params): + mylist.append((LinSpace[i, k+0], LinSpace[i, k+1])) + Subdomains.append(tuple(mylist)) + + return Subdomains + + # ------------------------------------------------------------------------- + def run_util_func(self, method, candidates, index, sigma2Dict=None, + var=None, X_MC=None): + """ + Runs the utility function based on the given method. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + candidates : array of shape (n_samples, n_params) + All candidate parameter sets. + index : int + ExpDesign index. + sigma2Dict : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + var : string, optional + Utility function. The default is None. + X_MC : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + index : TYPE + DESCRIPTION. + List + Scores. + + """ + + if method.lower() == 'varoptdesign': + # U_J_d = self.util_VarBasedDesign(candidates, index, var) + U_J_d = np.zeros((candidates.shape[0])) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="varoptdesign"): + U_J_d[idx] = self.util_VarBasedDesign(X_can, index, var) + + elif method.lower() == 'bayesactdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianActiveDesign(X_can, sigma2Dict, + var) + elif method.lower() == 'bayesoptdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianDesign(X_can, X_MC, sigma2Dict, + var) + return (index, -1 * U_J_d) + + # ------------------------------------------------------------------------- + def dual_annealing(self, method, Bounds, sigma2Dict, var, Run_No, + verbose=False): + """ + Exploration algorithim to find the optimum parameter space. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + Bounds : list of tuples + List of lower and upper boundaries of parameters. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + Run_No : int + Run number. + verbose : bool, optional + Print out a summary. The default is False. + + Returns + ------- + Run_No : int + Run number. + array + Optimial candidate. + + """ + + Model = self.Model + max_func_itr = self.MetaModel.ExpDesign.max_func_itr + + if method == 'VarOptDesign': + Res_Global = opt.dual_annealing(self.util_VarBasedDesign, + bounds=Bounds, + args=(Model, var), + maxfun=max_func_itr) + + elif method == 'BayesOptDesign': + Res_Global = opt.dual_annealing(self.util_BayesianDesign, + bounds=Bounds, + args=(Model, sigma2Dict, var), + maxfun=max_func_itr) + + if verbose: + print(f"Global minimum: xmin = {Res_Global.x}, " + f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}") + + return (Run_No, Res_Global.x) + + # ------------------------------------------------------------------------- + def tradoff_weights(self, tradeoff_scheme, old_EDX, old_EDY): + """ + Calculates weights for exploration scores based on the requested + scheme: `None`, `equal`, `epsilon-decreasing` and `adaptive`. + + `None`: No exploration. + `equal`: Same weights for exploration and exploitation scores. + `epsilon-decreasing`: Start with more exploration and increase the + influence of exploitation along the way with a exponential decay + function + `adaptive`: An adaptive method based on: + Liu, Haitao, Jianfei Cai, and Yew-Soon Ong. "An adaptive sampling + approach for Kriging metamodeling by maximizing expected prediction + error." Computers & Chemical Engineering 106 (2017): 171-182. + + Parameters + ---------- + tradeoff_scheme : string + Trade-off scheme for exloration and exploitation scores. + old_EDX : array (n_samples, n_params) + Old experimental design (training points). + old_EDY : dict + Old model responses (targets). + + Returns + ------- + exploration_weight : float + Exploration weight. + exploitation_weight: float + Exploitation weight. + + """ + if tradeoff_scheme is None: + exploration_weight = 0 + + elif tradeoff_scheme == 'equal': + exploration_weight = 0.5 + + elif tradeoff_scheme == 'epsilon-decreasing': + # epsilon-decreasing scheme + # Start with more exploration and increase the influence of + # exploitation along the way with a exponential decay function + initNSamples = self.MetaModel.ExpDesign.n_init_samples + n_max_samples = self.MetaModel.ExpDesign.n_max_samples + + itrNumber = (self.MetaModel.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.MetaModel.ExpDesign.n_new_samples + + tau2 = -(n_max_samples-initNSamples-1) / np.log(1e-8) + exploration_weight = signal.exponential(n_max_samples-initNSamples, + 0, tau2, False)[itrNumber] + + elif tradeoff_scheme == 'adaptive': + + # Extract itrNumber + initNSamples = self.MetaModel.ExpDesign.n_init_samples + n_max_samples = self.MetaModel.ExpDesign.n_max_samples + itrNumber = (self.MetaModel.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.MetaModel.ExpDesign.n_new_samples + + if itrNumber == 0: + exploration_weight = 0.5 + else: + # New adaptive trade-off according to Liu et al. (2017) + # Mean squared error for last design point + last_EDX = old_EDX[-1].reshape(1, -1) + lastPCEY, _ = self.MetaModel.eval_metamodel(samples=last_EDX) + pce_y = np.array(list(lastPCEY.values()))[:, 0] + y = np.array(list(old_EDY.values()))[:, -1, :] + mseError = mean_squared_error(pce_y, y) + + # Mean squared CV - error for last design point + pce_y_prev = np.array(list(self._y_hat_prev.values()))[:, 0] + mseCVError = mean_squared_error(pce_y_prev, y) + + exploration_weight = min([0.5*mseError/mseCVError, 1]) + + # Exploitation weight + exploitation_weight = 1 - exploration_weight + + return exploration_weight, exploitation_weight + + # ------------------------------------------------------------------------- + def opt_SeqDesign(self, sigma2, n_candidates=5, var='DKL'): + """ + Runs optimal sequential design. + + Parameters + ---------- + sigma2 : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + n_candidates : int, optional + Number of candidate samples. The default is 5. + var : string, optional + Utility function. The default is None. + + Raises + ------ + NameError + Wrong utility function. + + Returns + ------- + Xnew : array (n_samples, n_params) + Selected new training point(s). + """ + + # Initialization + MetaModel = self.MetaModel + Bounds = MetaModel.bound_tuples + n_new_samples = MetaModel.ExpDesign.n_new_samples + explore_method = MetaModel.ExpDesign.explore_method + exploit_method = MetaModel.ExpDesign.exploit_method + n_cand_groups = MetaModel.ExpDesign.n_cand_groups + tradeoff_scheme = MetaModel.ExpDesign.tradeoff_scheme + + old_EDX = MetaModel.ExpDesign.X + old_EDY = MetaModel.ExpDesign.Y.copy() + ndim = MetaModel.ExpDesign.X.shape[1] + OutputNames = MetaModel.ModelObj.Output.names + + # ----------------------------------------- + # ----------- CUSTOMIZED METHODS ---------- + # ----------------------------------------- + # Utility function exploit_method provided by user + if exploit_method.lower() == 'user': + + Xnew, filteredSamples = MetaModel.ExpDesign.ExploitFunction(self) + + print("\n") + print("\nXnew:\n", Xnew) + + return Xnew, filteredSamples + + # ----------------------------------------- + # ---------- EXPLORATION METHODS ---------- + # ----------------------------------------- + if explore_method == 'dual annealing': + # ------- EXPLORATION: OPTIMIZATION ------- + import time + start_time = time.time() + + # Divide the domain to subdomains + args = [] + subdomains = self.subdomain(Bounds, n_new_samples) + for i in range(n_new_samples): + args.append((exploit_method, subdomains[i], sigma2, var, i)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + + # With Pool.starmap_async() + results = pool.starmap_async(self.dual_annealing, args).get() + + # Close the pool + pool.close() + + Xnew = np.array([results[i][1] for i in range(n_new_samples)]) + + print("\nXnew:\n", Xnew) + + elapsed_time = time.time() - start_time + print("\n") + print(f"Elapsed_time: {round(elapsed_time,2)} sec.") + print('-'*20) + + elif explore_method == 'LOOCV': + # ----------------------------------------------------------------- + # TODO: LOOCV model construnction based on Feng et al. (2020) + # 'LOOCV': + # Initilize the ExploitScore array + + # Generate random samples + allCandidates = MetaModel.ExpDesign.generate_samples(n_candidates, + 'random') + + # Construct error model based on LCerror + errorModel = MetaModel.create_ModelError(old_EDX, self.LCerror) + self.errorModel.append(copy(errorModel)) + + # Evaluate the error models for allCandidates + eLCAllCands, _ = errorModel.eval_errormodel(allCandidates) + # Select the maximum as the representative error + eLCAllCands = np.dstack(eLCAllCands.values()) + eLCAllCandidates = np.max(eLCAllCands, axis=1)[:, 0] + + # Normalize the error w.r.t the maximum error + scoreExploration = eLCAllCandidates / np.sum(eLCAllCandidates) + + else: + # ------- EXPLORATION: SPACE-FILLING DESIGN ------- + # Generate candidate samples from Exploration class + explore = Exploration(MetaModel, n_candidates) + explore.w = 100 # * ndim #500 + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + allCandidates, scoreExploration = explore.get_exploration_samples() + + # Temp: ---- Plot all candidates ----- + if ndim == 2: + def plotter(points, allCandidates, Method, + scoreExploration=None): + if Method == 'Voronoi': + from scipy.spatial import Voronoi, voronoi_plot_2d + vor = Voronoi(points) + fig = voronoi_plot_2d(vor) + ax1 = fig.axes[0] + else: + fig = plt.figure() + ax1 = fig.add_subplot(111) + ax1.scatter(points[:, 0], points[:, 1], s=10, c='r', + marker="s", label='Old Design Points') + ax1.scatter(allCandidates[:, 0], allCandidates[:, 1], s=10, + c='b', marker="o", label='Design candidates') + for i in range(points.shape[0]): + txt = 'p'+str(i+1) + ax1.annotate(txt, (points[i, 0], points[i, 1])) + if scoreExploration is not None: + for i in range(allCandidates.shape[0]): + txt = str(round(scoreExploration[i], 5)) + ax1.annotate(txt, (allCandidates[i, 0], + allCandidates[i, 1])) + + plt.xlim(self.bound_tuples[0]) + plt.ylim(self.bound_tuples[1]) + # plt.show() + plt.legend(loc='upper left') + + # ----------------------------------------- + # --------- EXPLOITATION METHODS ---------- + # ----------------------------------------- + if exploit_method == 'BayesOptDesign' or\ + exploit_method == 'BayesActDesign': + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\n Exploration weight={explore_w:0.3f} " + f"Exploitation weight={exploit_w:0.3f}\n") + + # ------- EXPLOITATION: BayesOptDesign & ActiveLearning ------- + if explore_w != 1.0: + + # Create a sample pool for rejection sampling + MCsize = 15000 + X_MC = MetaModel.ExpDesign.generate_samples(MCsize, 'random') + candidates = MetaModel.ExpDesign.generate_samples( + MetaModel.ExpDesign.max_func_itr, 'latin_hypercube') + + # Split the candidates in groups for multiprocessing + split_cand = np.array_split( + candidates, n_cand_groups, axis=0 + ) + + results = Parallel(n_jobs=-1, backend='threading')( + delayed(self.run_util_func)( + exploit_method, split_cand[i], i, sigma2, var, X_MC) + for i in range(n_cand_groups)) + # out = map(self.run_util_func, + # [exploit_method]*n_cand_groups, + # split_cand, + # range(n_cand_groups), + # [sigma2] * n_cand_groups, + # [var] * n_cand_groups, + # [X_MC] * n_cand_groups + # ) + # results = list(out) + + # Retrieve the results and append them + U_J_d = np.concatenate([results[NofE][1] for NofE in + range(n_cand_groups)]) + + # Check if all scores are inf + if np.isinf(U_J_d).all() or np.isnan(U_J_d).all(): + U_J_d = np.ones(len(U_J_d)) + + # Get the expected value (mean) of the Utility score + # for each cell + if explore_method == 'Voronoi': + U_J_d = np.mean(U_J_d.reshape(-1, n_candidates), axis=1) + + # create surrogate model for U_J_d + from sklearn.preprocessing import MinMaxScaler + # Take care of inf entries + good_indices = [i for i, arr in enumerate(U_J_d) + if np.isfinite(arr).all()] + scaler = MinMaxScaler() + X_S = scaler.fit_transform(candidates[good_indices]) + gp = MetaModel.gaussian_process_emulator( + X_S, U_J_d[good_indices], autoSelect=True + ) + U_J_d = gp.predict(scaler.transform(allCandidates)) + + # Normalize U_J_d + norm_U_J_d = U_J_d / np.sum(U_J_d) + print("norm_U_J_d:\n", norm_U_J_d) + else: + norm_U_J_d = np.zeros((len(scoreExploration))) + + # ------- Calculate Total score ------- + # ------- Trade off between EXPLORATION & EXPLOITATION ------- + # Total score + totalScore = exploit_w * norm_U_J_d + totalScore += explore_w * scoreExploration + + # temp: Plot + # dim = self.ExpDesign.X.shape[1] + # if dim == 2: + # plotter(self.ExpDesign.X, allCandidates, explore_method) + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + # select the requested number of samples + if explore_method == 'Voronoi': + Xnew = np.zeros((n_new_samples, ndim)) + for i, idx in enumerate(bestIdx): + X_can = explore.closestPoints[idx] + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + else: + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + elif exploit_method == 'VarOptDesign': + # ------- EXPLOITATION: VarOptDesign ------- + UtilMethod = var + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\nweightExploration={explore_w:0.3f} " + f"weightExploitation={exploit_w:0.3f}") + + # Generate candidate samples from Exploration class + nMeasurement = old_EDY[OutputNames[0]].shape[1] + + # Find sensitive region + if UtilMethod == 'LOOCV': + LCerror = MetaModel.LCerror + allModifiedLOO = np.zeros((len(old_EDX), len(OutputNames), + nMeasurement)) + for y_idx, y_key in enumerate(OutputNames): + for idx, key in enumerate(LCerror[y_key].keys()): + allModifiedLOO[:, y_idx, idx] = abs( + LCerror[y_key][key]) + + ExploitScore = np.max(np.max(allModifiedLOO, axis=1), axis=1) + + elif UtilMethod in ['EIGF', 'ALM']: + # ----- All other in ['EIGF', 'ALM'] ----- + # Initilize the ExploitScore array + ExploitScore = np.zeros((len(old_EDX), len(OutputNames))) + + # Split the candidates in groups for multiprocessing + if explore_method != 'Voronoi': + split_cand = np.array_split(allCandidates, + n_cand_groups, + axis=0) + goodSampleIdx = range(n_cand_groups) + else: + # Find indices of the Vornoi cells with samples + goodSampleIdx = [] + for idx in range(len(explore.closest_points)): + if len(explore.closest_points[idx]) != 0: + goodSampleIdx.append(idx) + split_cand = explore.closest_points + + # Split the candidates in groups for multiprocessing + args = [] + for index in goodSampleIdx: + args.append((exploit_method, split_cand[index], index, + sigma2, var)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + # With Pool.starmap_async() + results = pool.starmap_async(self.run_util_func, args).get() + + # Close the pool + pool.close() + # out = map(self.run_util_func, + # [exploit_method]*len(goodSampleIdx), + # split_cand, + # range(len(goodSampleIdx)), + # [sigma2] * len(goodSampleIdx), + # [var] * len(goodSampleIdx) + # ) + # results = list(out) + + # Retrieve the results and append them + if explore_method == 'Voronoi': + ExploitScore = [np.mean(results[k][1]) for k in + range(len(goodSampleIdx))] + else: + ExploitScore = np.concatenate( + [results[k][1] for k in range(len(goodSampleIdx))]) + + else: + raise NameError('The requested utility function is not ' + 'available.') + + # print("ExploitScore:\n", ExploitScore) + + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + # Total score + # Normalize U_J_d + ExploitScore = ExploitScore / np.sum(ExploitScore) + totalScore = exploit_w * ExploitScore + totalScore += explore_w * scoreExploration + + temp = totalScore.copy() + sorted_idxtotalScore = np.argsort(temp, axis=0)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + Xnew = np.zeros((n_new_samples, ndim)) + if explore_method != 'Voronoi': + Xnew = allCandidates[bestIdx] + else: + for i, idx in enumerate(bestIdx.flatten()): + X_can = explore.closest_points[idx] + # plotter(self.ExpDesign.X, X_can, explore_method, + # scoreExploration=None) + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + + elif exploit_method == 'alphabetic': + # ------- EXPLOITATION: ALPHABETIC ------- + Xnew = self.util_AlphOptDesign(allCandidates, var) + + elif exploit_method == 'Space-filling': + # ------- EXPLOITATION: SPACE-FILLING ------- + totalScore = scoreExploration + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + + # select the requested number of samples + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + else: + raise NameError('The requested design method is not available.') + + print("\n") + print("\nRun No. {}:".format(old_EDX.shape[0]+1)) + print("Xnew:\n", Xnew) + gc.collect() + + return Xnew, None + + # ------------------------------------------------------------------------- + def util_AlphOptDesign(self, candidates, var='D-Opt'): + """ + Enriches the Experimental design with the requested alphabetic + criterion based on exploring the space with number of sampling points. + + Ref: Hadigol, M., & Doostan, A. (2018). Least squares polynomial chaos + expansion: A review of sampling strategies., Computer Methods in + Applied Mechanics and Engineering, 332, 382-407. + + Arguments + --------- + NCandidate : int + Number of candidate points to be searched + + var : string + Alphabetic optimality criterion + + Returns + ------- + X_new : array of shape (1, n_params) + The new sampling location in the input space. + """ + MetaModelOrig = self + Model = self.Model + n_new_samples = MetaModelOrig.ExpDesign.n_new_samples + NCandidate = candidates.shape[0] + + # TODO: Loop over outputs + OutputName = Model.Output.names[0] + + # To avoid changes ub original aPCE object + MetaModel = deepcopy(MetaModelOrig) + + # Old Experimental design + oldExpDesignX = MetaModel.ExpDesign.X + + # TODO: Only one psi can be selected. + # Suggestion: Go for the one with the highest LOO error + Scores = list(MetaModel.score_dict[OutputName].values()) + ModifiedLOO = [1-score for score in Scores] + outIdx = np.argmax(ModifiedLOO) + + # Initialize Phi to save the criterion's values + Phi = np.zeros((NCandidate)) + + BasisIndices = MetaModelOrig.basis_dict[OutputName]["y_"+str(outIdx+1)] + P = len(BasisIndices) + + # ------ Old Psi ------------ + univ_p_val = MetaModelOrig.univ_basis_vals(oldExpDesignX) + Psi = MetaModelOrig.create_psi(BasisIndices, univ_p_val) + + # ------ New candidates (Psi_c) ------------ + # Assemble Psi_c + univ_p_val_c = self.univ_basis_vals(candidates) + Psi_c = self.create_psi(BasisIndices, univ_p_val_c) + + for idx in range(NCandidate): + + # Include the new row to the original Psi + Psi_cand = np.vstack((Psi, Psi_c[idx])) + + # Information matrix + PsiTPsi = np.dot(Psi_cand.T, Psi_cand) + M = PsiTPsi / (len(oldExpDesignX)+1) + + if np.linalg.cond(PsiTPsi) > 1e-12 \ + and np.linalg.cond(PsiTPsi) < 1 / sys.float_info.epsilon: + # faster + invM = linalg.solve(M, sparse.eye(PsiTPsi.shape[0]).toarray()) + else: + # stabler + invM = np.linalg.pinv(M) + + # ---------- Calculate optimality criterion ---------- + # Optimality criteria according to Section 4.5.1 in Ref. + + # D-Opt + if var == 'D-Opt': + Phi[idx] = (np.linalg.det(invM)) ** (1/P) + + # A-Opt + elif var == 'A-Opt': + Phi[idx] = np.trace(invM) + + # K-Opt + elif var == 'K-Opt': + Phi[idx] = np.linalg.cond(M) + + else: + raise Exception('The optimality criterion you requested has ' + 'not been implemented yet!') + + # find an optimal point subset to add to the initial design + # by minimization of the Phi + sorted_idxtotalScore = np.argsort(Phi) + + # select the requested number of samples + Xnew = candidates[sorted_idxtotalScore[:n_new_samples]] + + return Xnew + + # ------------------------------------------------------------------------- + def __normpdf(self, y_hat_pce, std_pce, obs_data, total_sigma2s, + rmse=None): + + Model = self.Model + likelihoods = 1.0 + + # Loop over the outputs + for idx, out in enumerate(Model.Output.names): + + # (Meta)Model Output + nsamples, nout = y_hat_pce[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout].values + + # Surrogate error if valid dataset is given. + if rmse is not None: + tot_sigma2s += rmse[out]**2 + + likelihoods *= stats.multivariate_normal.pdf( + y_hat_pce[out], data, np.diag(tot_sigma2s), + allow_singular=True) + self.Likelihoods = likelihoods + + return likelihoods + + # ------------------------------------------------------------------------- + def __corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = MetaModel.ExpDesign.X # valid_samples + model_outputs = MetaModel.ExpDesign.Y # valid_model_runs + Model = MetaModel.ModelObj + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = Model.Output.names + + # TODO: Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + # covMatrix = np.diag(stdOutputRS[out][i]**2) + covMatrix = np.diag((y_m-y_m_hat)**2) + covMatrix = np.diag( + np.mean((model_outputs[out]-OutputRS[out]), axis=0)**2 + ) + + # Compute likelilhood output vs data + logLik_data[i] += self.__logpdf( + y_m_hat, data, covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += self.__logpdf(y_m_hat, y_m, covMatrix) + + # Weight + logLik_data -= logBME + weights = np.exp(logLik_model+logLik_data) + + return np.log(np.mean(weights)) + + # ------------------------------------------------------------------------- + def __logpdf(self, x, mean, cov): + """ + computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = linalg.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(linalg.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + + return log_lik + + # ------------------------------------------------------------------------- + def __posteriorPlot(self, posterior, par_names, key): + + # Initialization + newpath = (r'Outputs_SeqPosteriorComparison/posterior') + os.makedirs(newpath, exist_ok=True) + + bound_tuples = self.MetaModel.bound_tuples + n_params = len(par_names) + font_size = 40 + if n_params == 2: + + figPosterior, ax = plt.subplots(figsize=(15, 15)) + + sns.kdeplot(x=posterior[:, 0], y=posterior[:, 1], + fill=True, ax=ax, cmap=plt.cm.jet, + clip=bound_tuples) + # Axis labels + plt.xlabel(par_names[0], fontsize=font_size) + plt.ylabel(par_names[1], fontsize=font_size) + + # Set axis limit + plt.xlim(bound_tuples[0]) + plt.ylim(bound_tuples[1]) + + # Increase font size + plt.xticks(fontsize=font_size) + plt.yticks(fontsize=font_size) + + # Switch off the grids + plt.grid(False) + + else: + import corner + figPosterior = corner.corner(posterior, labels=par_names, + title_fmt='.2e', show_titles=True, + title_kwargs={"fontsize": 12}) + + figPosterior.savefig(f'./{newpath}/{key}.pdf', bbox_inches='tight') + plt.close() + + # Save the posterior as .npy + np.save(f'./{newpath}/{key}.npy', posterior) + + return figPosterior + + # ------------------------------------------------------------------------- + def __hellinger_distance(self, P, Q): + """ + Hellinger distance between two continuous distributions. + + The maximum distance 1 is achieved when P assigns probability zero to + every set to which Q assigns a positive probability, and vice versa. + 0 (identical) and 1 (maximally different) + + Parameters + ---------- + P : array + Reference likelihood. + Q : array + Estimated likelihood. + + Returns + ------- + float + Hellinger distance of two distributions. + + """ + mu1 = P.mean() + Sigma1 = np.std(P) + + mu2 = Q.mean() + Sigma2 = np.std(Q) + + term1 = np.sqrt(2*Sigma1*Sigma2 / (Sigma1**2 + Sigma2**2)) + + term2 = np.exp(-.25 * (mu1 - mu2)**2 / (Sigma1**2 + Sigma2**2)) + + H_squared = 1 - term1 * term2 + + return np.sqrt(H_squared) + + # ------------------------------------------------------------------------- + def __BME_Calculator(self, MetaModel, obs_data, sigma2Dict, rmse=None): + """ + This function computes the Bayesian model evidence (BME) via Monte + Carlo integration. + + """ + # Initializations + valid_likelihoods = MetaModel.valid_likelihoods + + post_snapshot = MetaModel.ExpDesign.post_snapshot + if post_snapshot or len(valid_likelihoods) != 0: + newpath = (r'Outputs_SeqPosteriorComparison/likelihood_vs_ref') + os.makedirs(newpath, exist_ok=True) + + SamplingMethod = 'random' + MCsize = 10000 + ESS = 0 + + # Estimation of the integral via Monte Varlo integration + while (ESS > MCsize) or (ESS < 1): + + # Generate samples for Monte Carlo simulation + X_MC = MetaModel.ExpDesign.generate_samples( + MCsize, SamplingMethod + ) + + # Monte Carlo simulation for the candidate design + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + Y_MC, std_MC = MetaModel.eval_metamodel(samples=X_MC) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"\nMemory eval_metamodel in BME: {m_2-m_1:.2f} MB") + + # Likelihood computation (Comparison of data and + # simulation results via PCE with candidate design) + Likelihoods = self.__normpdf( + Y_MC, std_MC, obs_data, sigma2Dict, rmse + ) + + # Check the Effective Sample Size (1000<ESS<MCsize) + ESS = 1 / np.sum(np.square(Likelihoods/np.sum(Likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if (ESS > MCsize) or (ESS < 1): + print(f'ESS={ESS} MC size should be larger.') + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + X_Posterior = X_MC[accepted] + + # ------------------------------------------------------------ + # --- Kullback-Leibler Divergence & Information Entropy ------ + # ------------------------------------------------------------ + # Prior-based estimation of BME + logBME = np.log(np.nanmean(Likelihoods)) + + # TODO: Correction factor + # log_weight = self.__corr_factor_BME(obs_data, sigma2Dict, logBME) + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean(np.log(Likelihoods[accepted])) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean( + np.log(MetaModel.ExpDesign.JDist.pdf(X_Posterior.T)) + ) + + # Calculate Kullback-Leibler Divergence + # KLD = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + KLD = postExpLikelihoods - logBME + + # Information Entropy based on Entropy paper Eq. 38 + infEntropy = logBME - postExpPrior - postExpLikelihoods + + # If post_snapshot is True, plot likelihood vs refrence + if post_snapshot or len(valid_likelihoods) != 0: + # Hellinger distance + ref_like = np.log(valid_likelihoods[valid_likelihoods > 0]) + est_like = np.log(Likelihoods[Likelihoods > 0]) + distHellinger = self.__hellinger_distance(ref_like, est_like) + + idx = len([name for name in os.listdir(newpath) if 'Likelihoods_' + in name and os.path.isfile(os.path.join(newpath, name))]) + fig, ax = plt.subplots() + try: + sns.kdeplot(np.log(valid_likelihoods[valid_likelihoods > 0]), + shade=True, color="g", label='Ref. Likelihood') + sns.kdeplot(np.log(Likelihoods[Likelihoods > 0]), shade=True, + color="b", label='Likelihood with PCE') + except: + pass + + text = f"Hellinger Dist.={distHellinger:.3f}\n logBME={logBME:.3f}" + "\n DKL={KLD:.3f}" + + plt.text(0.05, 0.75, text, bbox=dict(facecolor='wheat', + edgecolor='black', + boxstyle='round,pad=1'), + transform=ax.transAxes) + + fig.savefig(f'./{newpath}/Likelihoods_{idx}.pdf', + bbox_inches='tight') + plt.close() + + else: + distHellinger = 0.0 + + # Bayesian inference with Emulator only for 2D problem + if post_snapshot and MetaModel.n_params == 2 and not idx % 5: + from bayes_inference.bayes_inference import BayesInference + from bayes_inference.discrepancy import Discrepancy + import pandas as pd + BayesOpts = BayesInference(MetaModel) + BayesOpts.emulator = True + BayesOpts.plot_post_pred = False + + # Select the inference method + import emcee + BayesOpts.inference_method = "MCMC" + # Set the MCMC parameters passed to self.mcmc_params + BayesOpts.mcmc_params = { + 'n_steps': 1e5, + 'n_walkers': 30, + 'moves': emcee.moves.KDEMove(), + 'verbose': False + } + + # ----- Define the discrepancy model ------- + obs_data = pd.DataFrame(obs_data, columns=self.Model.Output.names) + BayesOpts.measurement_error = obs_data + + # # -- (Option B) -- + DiscrepancyOpts = Discrepancy('') + DiscrepancyOpts.type = 'Gaussian' + DiscrepancyOpts.parameters = obs_data**2 + BayesOpts.Discrepancy = DiscrepancyOpts + # Start the calibration/inference + Bayes_PCE = BayesOpts.create_inference() + X_Posterior = Bayes_PCE.posterior_df.values + + # Clean up + del Y_MC, std_MC + gc.collect() + + return (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + # ------------------------------------------------------------------------- + def __validError(self, MetaModel): + + # MetaModel = self.MetaModel + Model = MetaModel.ModelObj + OutputName = Model.Output.names + + # Extract the original model with the generated samples + valid_samples = MetaModel.valid_samples + valid_model_runs = MetaModel.valid_model_runs + + # Run the PCE model with the generated samples + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + valid_PCE_runs, valid_PCE_std = MetaModel.eval_metamodel(samples=valid_samples) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"\nMemory eval_metamodel: {m_2-m_1:.2f} MB") + + rms_error = {} + valid_error = {} + # Loop over the keys and compute RMSE error. + for key in OutputName: + rms_error[key] = mean_squared_error( + valid_model_runs[key], valid_PCE_runs[key], + multioutput='raw_values', + sample_weight=None, + squared=False) + + # Validation error + valid_error[key] = (rms_error[key]**2) + valid_error[key] /= np.var(valid_model_runs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Updated Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(rms_error[key], + valid_error[key])))) + + return rms_error, valid_error + + # ------------------------------------------------------------------------- + def __error_Mean_Std(self): + + MetaModel = self.MetaModel + # Extract the mean and std provided by user + df_MCReference = MetaModel.ModelObj.mc_reference + + # Compute the mean and std based on the MetaModel + pce_means, pce_stds = self._compute_pce_moments(MetaModel) + + # Compute the root mean squared error + for output in MetaModel.ModelObj.Output.names: + + # Compute the error between mean and std of MetaModel and OrigModel + RMSE_Mean = mean_squared_error( + df_MCReference['mean'], pce_means[output], squared=False + ) + RMSE_std = mean_squared_error( + df_MCReference['std'], pce_means[output], squared=False + ) + + return RMSE_Mean, RMSE_std + + # ------------------------------------------------------------------------- + def _compute_pce_moments(self, MetaModel): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moment (mean) of the surrogate. + pce_stds: dict + The second moment (standard deviation) of the surrogate. + + """ + outputs = MetaModel.ModelObj.Output.names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(MetaModel.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = MetaModel.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = MetaModel.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = MetaModel.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if MetaModel.dim_red_method.lower() == 'pca': + PCA = MetaModel.pca[f'b_{b_i+1}'][output] + means[output] = PCA.mean_ + np.dot( + pce_mean, PCA.components_) + stds[output] = np.sqrt(np.dot(pce_var, + PCA.components_**2)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + return pce_means, pce_stds diff --git a/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/surrogate_models.py b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/surrogate_models.py new file mode 100644 index 000000000..a6d31ccd1 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/bayesvalidrox/surrogate_models/surrogate_models.py @@ -0,0 +1,1473 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import warnings +import numpy as np +import math +import h5py +import matplotlib.pyplot as plt +from sklearn.preprocessing import MinMaxScaler +import scipy as sp +from tqdm import tqdm +from sklearn.decomposition import PCA as sklearnPCA +import sklearn.linear_model as lm +from sklearn.gaussian_process import GaussianProcessRegressor +import sklearn.gaussian_process.kernels as kernels +import os +from joblib import Parallel, delayed +import copy + +from .input_space import InputSpace +from .glexindex import glexindex +from .eval_rec_rule import eval_univ_basis +from .reg_fast_ard import RegressionFastARD +from .reg_fast_laplace import RegressionFastLaplace +from .orthogonal_matching_pursuit import OrthogonalMatchingPursuit +from .bayes_linear import VBLinearRegression, EBLinearRegression +from .apoly_construction import apoly_construction +warnings.filterwarnings("ignore") +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class MetaModel(): + """ + Meta (surrogate) model + + This class trains a surrogate model. It accepts an input object (input_obj) + containing the specification of the distributions for uncertain parameters + and a model object with instructions on how to run the computational model. + + Attributes + ---------- + input_obj : obj + Input object with the information on the model input parameters. + meta_model_type : str + Surrogate model types. Three surrogate model types are supported: + polynomial chaos expansion (`PCE`), arbitrary PCE (`aPCE`) and + Gaussian process regression (`GPE`). Default is PCE. + pce_reg_method : str + PCE regression method to compute the coefficients. The following + regression methods are available: + + 1. OLS: Ordinary Least Square method + 2. BRR: Bayesian Ridge Regression + 3. LARS: Least angle regression + 4. ARD: Bayesian ARD Regression + 5. FastARD: Fast Bayesian ARD Regression + 6. VBL: Variational Bayesian Learning + 7. EBL: Emperical Bayesian Learning + Default is `OLS`. + bootstrap_method : str + Bootstraping method. Options are `'normal'` and `'fast'`. The default + is `'fast'`. It means that in each iteration except the first one, only + the coefficent are recalculated with the ordinary least square method. + n_bootstrap_itrs : int + Number of iterations for the bootstrap sampling. The default is `1`. + pce_deg : int or list of int + Polynomial degree(s). If a list is given, an adaptive algorithm is used + to find the best degree with the lowest Leave-One-Out cross-validation + (LOO) error (or the highest score=1-LOO). Default is `1`. + pce_q_norm : float + Hyperbolic (or q-norm) truncation for multi-indices of multivariate + polynomials. Default is `1.0`. + dim_red_method : str + Dimensionality reduction method for the output space. The available + method is based on principal component analysis (PCA). The Default is + `'no'`. There are two ways to select number of components: use + percentage of the explainable variance threshold (between 0 and 100) + (Option A) or direct prescription of components' number (Option B): + + >>> MetaModelOpts.dim_red_method = 'PCA' + >>> MetaModelOpts.var_pca_threshold = 99.999 # Option A + >>> MetaModelOpts.n_pca_components = 12 # Option B + + verbose : bool + Prints summary of the regression results. Default is `False`. + + Note + ------- + To define the sampling methods and the training set, an experimental design + instance shall be defined. This can be done by: + + >>> MetaModelOpts.add_InputSpace() + + Two experimental design schemes are supported: one-shot (`normal`) and + adaptive sequential (`sequential`) designs. + For experimental design refer to `InputSpace`. + + """ + + def __init__(self, input_obj, meta_model_type='PCE', + pce_reg_method='OLS', bootstrap_method='fast', + n_bootstrap_itrs=1, pce_deg=1, pce_q_norm=1.0, + dim_red_method='no', verbose=False): + + self.input_obj = input_obj + self.meta_model_type = meta_model_type + self.pce_reg_method = pce_reg_method + self.bootstrap_method = bootstrap_method + self.n_bootstrap_itrs = n_bootstrap_itrs + self.pce_deg = pce_deg + self.pce_q_norm = pce_q_norm + self.dim_red_method = dim_red_method + self.verbose = verbose + + def build_metamodel(self, n_init_samples = None) -> None: + """ + Builds the parts for the metamodel (polynomes,...) that are neede before fitting. + + Returns + ------- + None + DESCRIPTION. + + """ + + # Add InputSpace to MetaModel if it does not have any + if not hasattr(self, 'InputSpace'): + self.InputSpace = InputSpace(self.input_obj) + self.InputSpace.n_init_samples = n_init_samples + self.InputSpace.init_param_space(np.max(self.pce_deg)) + + self.ndim = self.InputSpace.ndim + + if not hasattr(self, 'CollocationPoints'): + raise AttributeError('Please provide samples to the metamodel before building it.') + + self.n_params = len(self.input_obj.Marginals) + + # Generate polynomials + if self.meta_model_type.lower() != 'gpe': + self.generate_polynomials(np.max(self.pce_deg)) + + # Initialize the nested dictionaries + if self.meta_model_type.lower() == 'gpe': + self.gp_poly = self.auto_vivification() + self.x_scaler = self.auto_vivification() + self.LCerror = self.auto_vivification() + else: + self.deg_dict = self.auto_vivification() + self.q_norm_dict = self.auto_vivification() + self.coeffs_dict = self.auto_vivification() + self.basis_dict = self.auto_vivification() + self.score_dict = self.auto_vivification() + self.clf_poly = self.auto_vivification() + self.LCerror = self.auto_vivification() + if self.dim_red_method.lower() == 'pca': + self.pca = self.auto_vivification() + + # Define an array containing the degrees + self.CollocationPoints = np.array(self.CollocationPoints) + self.n_samples, ndim = self.CollocationPoints.shape + if self.ndim != ndim: + raise AttributeError('The given samples do not match the given number of priors. The samples should be a 2D array of size (#samples, #priors)') + + self.deg_array = self.__select_degree(ndim, self.n_samples) + + # Generate all basis indices + self.allBasisIndices = self.auto_vivification() + for deg in self.deg_array: + keys = self.allBasisIndices.keys() + if deg not in np.fromiter(keys, dtype=float): + # Generate the polynomial basis indices + for qidx, q in enumerate(self.pce_q_norm): + basis_indices = glexindex(start=0, stop=deg+1, + dimensions=self.n_params, + cross_truncation=q, + reverse=False, graded=True) + self.allBasisIndices[str(deg)][str(q)] = basis_indices + + + + def fit(self, X, y, parallel = True, verbose = False): + """ + Fits the surrogate to the given data (samples X, outputs y). + Note here that the samples X should be the transformed samples provided + by the experimental design if the transformation is used there. + + Parameters + ---------- + X : 2D list or np.array of shape (#samples, #dim) + The parameter value combinations that the model was evaluated at. + y : dict of 2D lists or arrays of shape (#samples, #timesteps) + The respective model evaluations. + + Returns + ------- + None. + + """ + X = np.array(X) + for key in y.keys(): + y_val = np.array(y[key]) + if y_val.ndim !=2: + raise ValueError('The given outputs y should be 2D') + y[key] = np.array(y[key]) + + # Output names are the same as the keys in y + self.out_names = list(y.keys()) + + # Build the MetaModel on the static samples + self.CollocationPoints = X + + # TODO: other option: rebuild every time + if not hasattr(self, 'deg_array'): + self.build_metamodel(n_init_samples = X.shape[1]) + + # Evaluate the univariate polynomials on InputSpace + if self.meta_model_type.lower() != 'gpe': + self.univ_p_val = self.univ_basis_vals(self.CollocationPoints) + + # --- Loop through data points and fit the surrogate --- + if verbose: + print(f"\n>>>> Training the {self.meta_model_type} metamodel " + "started. <<<<<<\n") + + # --- Bootstrap sampling --- + # Correct number of bootstrap if PCA transformation is required. + if self.dim_red_method.lower() == 'pca' and self.n_bootstrap_itrs == 1: + self.n_bootstrap_itrs = 100 + + # Check if fast version (update coeffs with OLS) is selected. + if self.bootstrap_method.lower() == 'fast': + fast_bootstrap = True + first_out = {} + n_comp_dict = {} + else: + fast_bootstrap = False + + # Prepare tqdm iteration maessage + if verbose and self.n_bootstrap_itrs > 1: + enum_obj = tqdm(range(self.n_bootstrap_itrs), + total=self.n_bootstrap_itrs, + desc="Bootstrapping the metamodel", + ascii=True) + else: + enum_obj = range(self.n_bootstrap_itrs) + + # Loop over the bootstrap iterations + for b_i in enum_obj: + if b_i > 0: + b_indices = np.random.randint(self.n_samples, size=self.n_samples) + else: + b_indices = np.arange(len(X)) + + X_train_b = X[b_indices] + + if verbose and self.n_bootstrap_itrs == 1: + items = tqdm(y.items(), desc="Fitting regression") + else: + items = y.items() + + # For loop over the components/outputs + for key, Output in items: + + # Dimensionality reduction with PCA, if specified + if self.dim_red_method.lower() == 'pca': + + # Use the stored n_comp for fast bootsrtrapping + if fast_bootstrap and b_i > 0: + self.n_pca_components = n_comp_dict[key] + + # Start transformation + pca, target, n_comp = self.pca_transformation( + Output[b_indices], verbose=False + ) + self.pca[f'b_{b_i+1}'][key] = pca + # Store the number of components for fast bootsrtrapping + if fast_bootstrap and b_i == 0: + n_comp_dict[key] = n_comp + else: + target = Output[b_indices] + + # Parallel fit regression + if self.meta_model_type.lower() == 'gpe': + # Prepare the input matrix + scaler = MinMaxScaler() + X_S = scaler.fit_transform(X_train_b) + + self.x_scaler[f'b_{b_i+1}'][key] = scaler + if parallel: + out = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.gaussian_process_emulator)( + X_S, target[:, idx]) for idx in + range(target.shape[1])) + else: + results = map(self.gaussian_process_emulator, + [X_train_b]*target.shape[1], + [target[:, idx] for idx in + range(target.shape[1])] + ) + out = list(results) + + for idx in range(target.shape[1]): + self.gp_poly[f'b_{b_i+1}'][key][f"y_{idx+1}"] = out[idx] + + else: + self.univ_p_val = self.univ_p_val[b_indices] + if parallel and (not fast_bootstrap or b_i == 0): + out = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.adaptive_regression)(X_train_b, + target[:, idx], + idx) + for idx in range(target.shape[1])) + elif not parallel and (not fast_bootstrap or b_i == 0): + results = map(self.adaptive_regression, + [X_train_b]*target.shape[1], + [target[:, idx] for idx in + range(target.shape[1])], + range(target.shape[1])) + out = list(results) + + # Store the first out dictionary + if fast_bootstrap and b_i == 0: + first_out[key] = copy.deepcopy(out) + + if b_i > 0 and fast_bootstrap: + + # fast bootstrap + out = self.update_pce_coeffs( + X_train_b, target, first_out[key]) + + for i in range(target.shape[1]): + # Create a dict to pass the variables + self.deg_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['degree'] + self.q_norm_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['qnorm'] + self.coeffs_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['coeffs'] + self.basis_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['multi_indices'] + self.score_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['LOOCVScore'] + self.clf_poly[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['clf_poly'] + #self.LCerror[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['LCerror'] + + if verbose: + print(f"\n>>>> Training the {self.meta_model_type} metamodel" + " sucessfully completed. <<<<<<\n") + + # ------------------------------------------------------------------------- + def update_pce_coeffs(self, X, y, out_dict = None): + """ + Updates the PCE coefficents using only the ordinary least square method + for the fast version of the bootstrapping. + + Parameters + ---------- + X : array of shape (n_samples, n_params) + Training set. + y : array of shape (n_samples, n_outs) + The (transformed) model responses. + out_dict : dict + The training output dictionary of the first iteration, i.e. + the surrogate model for the original experimental design. + + Returns + ------- + final_out_dict : dict + The updated training output dictionary. + + """ + # Make a copy + final_out_dict = copy.deepcopy(out_dict) + + # Loop over the points + for i in range(y.shape[1]): + + + # Extract nonzero basis indices + nnz_idx = np.nonzero(out_dict[i]['coeffs'])[0] + if len(nnz_idx) != 0: + basis_indices = out_dict[i]['multi_indices'] + + # Evaluate the multivariate polynomials on CollocationPoints + psi = self.create_psi(basis_indices, self.univ_p_val) + + # Calulate the cofficients of surrogate model + updated_out = self.regression( + psi, y[:, i], basis_indices, reg_method='OLS', + sparsity=False + ) + + # Update coeffs in out_dict + final_out_dict[i]['coeffs'][nnz_idx] = updated_out['coeffs'] + + return final_out_dict + + # ------------------------------------------------------------------------- + def add_InputSpace(self): + """ + Instanciates experimental design object. + + Returns + ------- + None. + + """ + self.InputSpace = InputSpace(self.input_obj, + meta_Model_type=self.meta_model_type) + + # ------------------------------------------------------------------------- + def univ_basis_vals(self, samples, n_max=None): + """ + Evaluates univariate regressors along input directions. + + Parameters + ---------- + samples : array of shape (n_samples, n_params) + Samples. + n_max : int, optional + Maximum polynomial degree. The default is `None`. + + Returns + ------- + univ_basis: array of shape (n_samples, n_params, n_max+1) + All univariate regressors up to n_max. + """ + # Extract information + poly_types = self.InputSpace.poly_types + if samples.ndim != 2: + samples = samples.reshape(1, len(samples)) + n_max = np.max(self.pce_deg) if n_max is None else n_max + + # Extract poly coeffs + if self.InputSpace.input_data_given or self.InputSpace.apce: + apolycoeffs = self.polycoeffs + else: + apolycoeffs = None + + # Evaluate univariate basis + univ_basis = eval_univ_basis(samples, n_max, poly_types, apolycoeffs) + + return univ_basis + + # ------------------------------------------------------------------------- + def create_psi(self, basis_indices, univ_p_val): + """ + This function assemble the design matrix Psi from the given basis index + set INDICES and the univariate polynomial evaluations univ_p_val. + + Parameters + ---------- + basis_indices : array of shape (n_terms, n_params) + Multi-indices of multivariate polynomials. + univ_p_val : array of (n_samples, n_params, n_max+1) + All univariate regressors up to `n_max`. + + Raises + ------ + ValueError + n_terms in arguments do not match. + + Returns + ------- + psi : array of shape (n_samples, n_terms) + Multivariate regressors. + + """ + # Check if BasisIndices is a sparse matrix + sparsity = sp.sparse.issparse(basis_indices) + if sparsity: + basis_indices = basis_indices.toarray() + + # Initialization and consistency checks + # number of input variables + n_params = univ_p_val.shape[1] + + # Size of the experimental design + n_samples = univ_p_val.shape[0] + + # number of basis terms + n_terms = basis_indices.shape[0] + + # check that the variables have consistent sizes + if n_params != basis_indices.shape[1]: + raise ValueError( + f"The shapes of basis_indices ({basis_indices.shape[1]}) and " + f"univ_p_val ({n_params}) don't match!!" + ) + + # Preallocate the Psi matrix for performance + psi = np.ones((n_samples, n_terms)) + # Assemble the Psi matrix + for m in range(basis_indices.shape[1]): + aa = np.where(basis_indices[:, m] > 0)[0] + try: + basisIdx = basis_indices[aa, m] + bb = univ_p_val[:, m, basisIdx].reshape(psi[:, aa].shape) + psi[:, aa] = np.multiply(psi[:, aa], bb) + except ValueError as err: + raise err + return psi + + # ------------------------------------------------------------------------- + def regression(self, X, y, basis_indices, reg_method=None, sparsity=True): + """ + Fit regression using the regression method provided. + + Parameters + ---------- + X : array of shape (n_samples, n_features) + Training vector, where n_samples is the number of samples and + n_features is the number of features. + y : array of shape (n_samples,) + Target values. + basis_indices : array of shape (n_terms, n_params) + Multi-indices of multivariate polynomials. + reg_method : str, optional + DESCRIPTION. The default is None. + + Returns + ------- + return_out_dict : Dict + Fitted estimator, spareMulti-Index, sparseX and coefficients. + + """ + if reg_method is None: + reg_method = self.pce_reg_method + + bias_term = self.dim_red_method.lower() != 'pca' + + compute_score = True if self.verbose else False + + # inverse of the observed variance of the data + if np.var(y) != 0: + Lambda = 1 / np.var(y) + else: + Lambda = 1e-6 + + # Bayes sparse adaptive aPCE + if reg_method.lower() == 'ols': + clf_poly = lm.LinearRegression(fit_intercept=False) + elif reg_method.lower() == 'brr': + clf_poly = lm.BayesianRidge(n_iter=1000, tol=1e-7, + fit_intercept=False, + #normalize=True, + compute_score=compute_score, + alpha_1=1e-04, alpha_2=1e-04, + lambda_1=Lambda, lambda_2=Lambda) + clf_poly.converged = True + + elif reg_method.lower() == 'ard': + if X.shape[0]<2: + raise ValueError('Regression with ARD can only be performed for more than 2 samples') + clf_poly = lm.ARDRegression(fit_intercept=False, + #normalize=True, + compute_score=compute_score, + n_iter=1000, tol=0.0001, + alpha_1=1e-3, alpha_2=1e-3, + lambda_1=Lambda, lambda_2=Lambda) + + elif reg_method.lower() == 'fastard': + clf_poly = RegressionFastARD(fit_intercept=False, + normalize=True, + compute_score=compute_score, + n_iter=300, tol=1e-10) + + elif reg_method.lower() == 'bcs': + if X.shape[0]<10: + raise ValueError('Regression with BCS can only be performed for more than 10 samples') + clf_poly = RegressionFastLaplace(fit_intercept=False, + bias_term=bias_term, + n_iter=1000, tol=1e-7) + + elif reg_method.lower() == 'lars': + if X.shape[0]<10: + raise ValueError('Regression with LARS can only be performed for more than 5 samples') + clf_poly = lm.LassoLarsCV(fit_intercept=False) + + elif reg_method.lower() == 'sgdr': + clf_poly = lm.SGDRegressor(fit_intercept=False, + max_iter=5000, tol=1e-7) + + elif reg_method.lower() == 'omp': + clf_poly = OrthogonalMatchingPursuit(fit_intercept=False) + + elif reg_method.lower() == 'vbl': + clf_poly = VBLinearRegression(fit_intercept=False) + + elif reg_method.lower() == 'ebl': + clf_poly = EBLinearRegression(optimizer='em') + + # Fit + clf_poly.fit(X, y) + + # Select the nonzero entries of coefficients + if sparsity: + nnz_idx = np.nonzero(clf_poly.coef_)[0] + else: + nnz_idx = np.arange(clf_poly.coef_.shape[0]) + + # This is for the case where all outputs are zero, thereby + # all coefficients are zero + if (y == 0).all(): + nnz_idx = np.insert(np.nonzero(clf_poly.coef_)[0], 0, 0) + + sparse_basis_indices = basis_indices[nnz_idx] + sparse_X = X[:, nnz_idx] + coeffs = clf_poly.coef_[nnz_idx] + clf_poly.coef_ = coeffs + + # Create a dict to pass the outputs + return_out_dict = dict() + return_out_dict['clf_poly'] = clf_poly + return_out_dict['spareMulti-Index'] = sparse_basis_indices + return_out_dict['sparePsi'] = sparse_X + return_out_dict['coeffs'] = coeffs + return return_out_dict + + # -------------------------------------------------------------------------------------------------------- + def adaptive_regression(self, ED_X, ED_Y, varIdx, verbose=False): + """ + Adaptively fits the PCE model by comparing the scores of different + degrees and q-norm. + + Parameters + ---------- + ED_X : array of shape (n_samples, n_params) + Experimental design. + ED_Y : array of shape (n_samples,) + Target values, i.e. simulation results for the Experimental design. + varIdx : int + Index of the output. + verbose : bool, optional + Print out summary. The default is False. + + Returns + ------- + returnVars : Dict + Fitted estimator, best degree, best q-norm, LOOCVScore and + coefficients. + + """ + + n_samples, n_params = ED_X.shape + # Initialization + qAllCoeffs, AllCoeffs = {}, {} + qAllIndices_Sparse, AllIndices_Sparse = {}, {} + qAllclf_poly, Allclf_poly = {}, {} + qAllnTerms, AllnTerms = {}, {} + qAllLCerror, AllLCerror = {}, {} + + # Extract degree array and qnorm array + deg_array = np.array([*self.allBasisIndices], dtype=int) + qnorm = [*self.allBasisIndices[str(int(deg_array[0]))]] + + # Some options for EarlyStop + errorIncreases = False + # Stop degree, if LOO error does not decrease n_checks_degree times + n_checks_degree = 3 + # Stop qNorm, if criterion isn't fulfilled n_checks_qNorm times + n_checks_qNorm = 2 + nqnorms = len(qnorm) + qNormEarlyStop = True + if nqnorms < n_checks_qNorm+1: + qNormEarlyStop = False + + # ===================================================================== + # basis adaptive polynomial chaos: repeat the calculation by increasing + # polynomial degree until the highest accuracy is reached + # ===================================================================== + # For each degree check all q-norms and choose the best one + scores = -np.inf * np.ones(deg_array.shape[0]) + qNormScores = -np.inf * np.ones(nqnorms) + + for degIdx, deg in enumerate(deg_array): + + for qidx, q in enumerate(qnorm): + + # Extract the polynomial basis indices from the pool of + # allBasisIndices + BasisIndices = self.allBasisIndices[str(deg)][str(q)] + + # Assemble the Psi matrix + Psi = self.create_psi(BasisIndices, self.univ_p_val) + + # Calulate the cofficients of the meta model + outs = self.regression(Psi, ED_Y, BasisIndices) + + # Calculate and save the score of LOOCV + score, LCerror = self.corr_loocv_error(outs['clf_poly'], + outs['sparePsi'], + outs['coeffs'], + ED_Y) + + # Check the convergence of noise for FastARD + if self.pce_reg_method == 'FastARD' and \ + outs['clf_poly'].alpha_ < np.finfo(np.float32).eps: + score = -np.inf + + qNormScores[qidx] = score + qAllCoeffs[str(qidx+1)] = outs['coeffs'] + qAllIndices_Sparse[str(qidx+1)] = outs['spareMulti-Index'] + qAllclf_poly[str(qidx+1)] = outs['clf_poly'] + qAllnTerms[str(qidx+1)] = BasisIndices.shape[0] + qAllLCerror[str(qidx+1)] = LCerror + + # EarlyStop check + # if there are at least n_checks_qNorm entries after the + # best one, we stop + if qNormEarlyStop and \ + sum(np.isfinite(qNormScores)) > n_checks_qNorm: + # If the error has increased the last two iterations, stop! + qNormScores_nonInf = qNormScores[np.isfinite(qNormScores)] + deltas = np.sign(np.diff(qNormScores_nonInf)) + if sum(deltas[-n_checks_qNorm+1:]) == 2: + # stop the q-norm loop here + break + if np.var(ED_Y) == 0: + break + + # Store the score in the scores list + best_q = np.nanargmax(qNormScores) + scores[degIdx] = qNormScores[best_q] + + AllCoeffs[str(degIdx+1)] = qAllCoeffs[str(best_q+1)] + AllIndices_Sparse[str(degIdx+1)] = qAllIndices_Sparse[str(best_q+1)] + Allclf_poly[str(degIdx+1)] = qAllclf_poly[str(best_q+1)] + AllnTerms[str(degIdx+1)] = qAllnTerms[str(best_q+1)] + AllLCerror[str(degIdx+1)] = qAllLCerror[str(best_q+1)] + + # Check the direction of the error (on average): + # if it increases consistently stop the iterations + if len(scores[scores != -np.inf]) > n_checks_degree: + scores_nonInf = scores[scores != -np.inf] + ss = np.sign(scores_nonInf - np.max(scores_nonInf)) + # ss<0 error decreasing + errorIncreases = np.sum(np.sum(ss[-2:])) <= -1*n_checks_degree + + if errorIncreases: + break + + # Check only one degree, if target matrix has zero variance + if np.var(ED_Y) == 0: + break + + # ------------------ Summary of results ------------------ + # Select the one with the best score and save the necessary outputs + best_deg = np.nanargmax(scores)+1 + coeffs = AllCoeffs[str(best_deg)] + basis_indices = AllIndices_Sparse[str(best_deg)] + clf_poly = Allclf_poly[str(best_deg)] + LOOCVScore = np.nanmax(scores) + P = AllnTerms[str(best_deg)] + LCerror = AllLCerror[str(best_deg)] + degree = deg_array[np.nanargmax(scores)] + qnorm = float(qnorm[best_q]) + + # ------------------ Print out Summary of results ------------------ + if self.verbose: + # Create PSI_Sparse by removing redundent terms + nnz_idx = np.nonzero(coeffs)[0] + BasisIndices_Sparse = basis_indices[nnz_idx] + + print(f'Output variable {varIdx+1}:') + print('The estimation of PCE coefficients converged at polynomial ' + f'degree {deg_array[best_deg-1]} with ' + f'{len(BasisIndices_Sparse)} terms (Sparsity index = ' + f'{round(len(BasisIndices_Sparse)/P, 3)}).') + + print(f'Final ModLOO error estimate: {1-max(scores):.3e}') + print('\n'+'-'*50) + + if verbose: + print('='*50) + print(' '*10 + ' Summary of results ') + print('='*50) + + print("Scores:\n", scores) + print("Degree of best score:", self.deg_array[best_deg-1]) + print("No. of terms:", len(basis_indices)) + print("Sparsity index:", round(len(basis_indices)/P, 3)) + print("Best Indices:\n", basis_indices) + + if self.pce_reg_method in ['BRR', 'ARD']: + fig, ax = plt.subplots(figsize=(12, 10)) + plt.title("Marginal log-likelihood") + plt.plot(clf_poly.scores_, color='navy', linewidth=2) + plt.ylabel("Score") + plt.xlabel("Iterations") + if self.pce_reg_method.lower() == 'bbr': + text = f"$\\alpha={clf_poly.alpha_:.1f}$\n" + f"$\\lambda={clf_poly.lambda_:.3f}$\n" + f"$L={clf_poly.scores_[-1]:.1f}$" + else: + text = f"$\\alpha={clf_poly.alpha_:.1f}$\n$" + f"\\L={clf_poly.scores_[-1]:.1f}$" + + plt.text(0.75, 0.5, text, fontsize=18, transform=ax.transAxes) + plt.show() + print('='*80) + + # Create a dict to pass the outputs + returnVars = dict() + returnVars['clf_poly'] = clf_poly + returnVars['degree'] = degree + returnVars['qnorm'] = qnorm + returnVars['coeffs'] = coeffs + returnVars['multi_indices'] = basis_indices + returnVars['LOOCVScore'] = LOOCVScore + returnVars['LCerror'] = LCerror + + return returnVars + + # ------------------------------------------------------------------------- + def corr_loocv_error(self, clf, psi, coeffs, y): + """ + Calculates the corrected LOO error for regression on regressor + matrix `psi` that generated the coefficients based on [1] and [2]. + + [1] Blatman, G., 2009. Adaptive sparse polynomial chaos expansions for + uncertainty propagation and sensitivity analysis (Doctoral + dissertation, Clermont-Ferrand 2). + + [2] Blatman, G. and Sudret, B., 2011. Adaptive sparse polynomial chaos + expansion based on least angle regression. Journal of computational + Physics, 230(6), pp.2345-2367. + + Parameters + ---------- + clf : object + Fitted estimator. + psi : array of shape (n_samples, n_features) + The multivariate orthogonal polynomials (regressor). + coeffs : array-like of shape (n_features,) + Estimated cofficients. + y : array of shape (n_samples,) + Target values. + + Returns + ------- + R_2 : float + LOOCV Validation score (1-LOOCV erro). + residual : array of shape (n_samples,) + Residual values (y - predicted targets). + + """ + psi = np.array(psi, dtype=float) + + # Create PSI_Sparse by removing redundent terms + nnz_idx = np.nonzero(coeffs)[0] + if len(nnz_idx) == 0: + nnz_idx = [0] + psi_sparse = psi[:, nnz_idx] + + # NrCoeffs of aPCEs + P = len(nnz_idx) + # NrEvaluation (Size of experimental design) + N = psi.shape[0] + + # Build the projection matrix + PsiTPsi = np.dot(psi_sparse.T, psi_sparse) + + if np.linalg.cond(PsiTPsi) > 1e-12: #and \ + # np.linalg.cond(PsiTPsi) < 1/sys.float_info.epsilon: + # faster + try: + M = sp.linalg.solve(PsiTPsi, + sp.sparse.eye(PsiTPsi.shape[0]).toarray()) + except: + raise AttributeError('There are too few samples for the corrected loo-cv error. Fit surrogate on at least as many samples as parameters to use this') + else: + # stabler + M = np.linalg.pinv(PsiTPsi) + + # h factor (the full matrix is not calculated explicitly, + # only the trace is, to save memory) + PsiM = np.dot(psi_sparse, M) + + h = np.sum(np.multiply(PsiM, psi_sparse), axis=1, dtype=np.longdouble)#float128) + + # ------ Calculate Error Loocv for each measurement point ---- + # Residuals + try: + residual = clf.predict(psi) - y + except: + residual = np.dot(psi, coeffs) - y + + # Variance + var_y = np.var(y) + + if var_y == 0: + norm_emp_error = 0 + loo_error = 0 + LCerror = np.zeros((y.shape)) + return 1-loo_error, LCerror + else: + norm_emp_error = np.mean(residual**2)/var_y + + # LCerror = np.divide(residual, (1-h)) + LCerror = residual / (1-h) + loo_error = np.mean(np.square(LCerror)) / var_y + # if there are NaNs, just return an infinite LOO error (this + # happens, e.g., when a strongly underdetermined problem is solved) + if np.isnan(loo_error): + loo_error = np.inf + + # Corrected Error for over-determined system + tr_M = np.trace(M) + if tr_M < 0 or abs(tr_M) > 1e6: + tr_M = np.trace(np.linalg.pinv(np.dot(psi.T, psi))) + + # Over-determined system of Equation + if N > P: + T_factor = N/(N-P) * (1 + tr_M) + + # Under-determined system of Equation + else: + T_factor = np.inf + + corrected_loo_error = loo_error * T_factor + + R_2 = 1 - corrected_loo_error + + return R_2, LCerror + + # ------------------------------------------------------------------------- + def pca_transformation(self, target, verbose=False): + """ + Transforms the targets (outputs) via Principal Component Analysis + + Parameters + ---------- + target : array of shape (n_samples,) + Target values. + + Returns + ------- + pca : obj + Fitted sklearnPCA object. + OutputMatrix : array of shape (n_samples,) + Transformed target values. + n_pca_components : int + Number of selected principal components. + + """ + # Transform via Principal Component Analysis + if hasattr(self, 'var_pca_threshold'): + var_pca_threshold = self.var_pca_threshold + else: + var_pca_threshold = 100.0 + n_samples, n_features = target.shape + + if hasattr(self, 'n_pca_components'): + n_pca_components = self.n_pca_components + else: + # Instantiate and fit sklearnPCA object + covar_matrix = sklearnPCA(n_components=None) + covar_matrix.fit(target) + var = np.cumsum(np.round(covar_matrix.explained_variance_ratio_, + decimals=5)*100) + # Find the number of components to explain self.varPCAThreshold of + # variance + try: + n_components = np.where(var >= var_pca_threshold)[0][0] + 1 + except IndexError: + n_components = min(n_samples, n_features) + + n_pca_components = min(n_samples, n_features, n_components) + + # Print out a report + if verbose: + print() + print('-' * 50) + print(f"PCA transformation is performed with {n_pca_components}" + " components.") + print('-' * 50) + print() + + # Fit and transform with the selected number of components + pca = sklearnPCA(n_components=n_pca_components, svd_solver='arpack') + scaled_target = pca.fit_transform(target) + + return pca, scaled_target, n_pca_components + + # ------------------------------------------------------------------------- + def gaussian_process_emulator(self, X, y, nug_term=None, autoSelect=False, + varIdx=None): + """ + Fits a Gaussian Process Emulator to the target given the training + points. + + Parameters + ---------- + X : array of shape (n_samples, n_params) + Training points. + y : array of shape (n_samples,) + Target values. + nug_term : float, optional + Nugget term. The default is None, i.e. variance of y. + autoSelect : bool, optional + Loop over some kernels and select the best. The default is False. + varIdx : int, optional + The index number. The default is None. + + Returns + ------- + gp : object + Fitted estimator. + + """ + + nug_term = nug_term if nug_term else np.var(y) + + Kernels = [nug_term * kernels.RBF(length_scale=1.0, + length_scale_bounds=(1e-25, 1e15)), + nug_term * kernels.RationalQuadratic(length_scale=0.2, + alpha=1.0), + nug_term * kernels.Matern(length_scale=1.0, + length_scale_bounds=(1e-15, 1e5), + nu=1.5)] + + # Automatic selection of the kernel + if autoSelect: + gp = {} + BME = [] + for i, kernel in enumerate(Kernels): + gp[i] = GaussianProcessRegressor(kernel=kernel, + n_restarts_optimizer=3, + normalize_y=False) + + # Fit to data using Maximum Likelihood Estimation + gp[i].fit(X, y) + + # Store the MLE as BME score + BME.append(gp[i].log_marginal_likelihood()) + + gp = gp[np.argmax(BME)] + + else: + gp = GaussianProcessRegressor(kernel=Kernels[0], + n_restarts_optimizer=3, + normalize_y=False) + gp.fit(X, y) + + # Compute score + if varIdx is not None: + Score = gp.score(X, y) + print('-'*50) + print(f'Output variable {varIdx}:') + print('The estimation of GPE coefficients converged,') + print(f'with the R^2 score: {Score:.3f}') + print('-'*50) + + return gp + + # ------------------------------------------------------------------------- + def eval_metamodel(self, samples): + """ + Evaluates meta-model at the requested samples. One can also generate + nsamples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate meta-model at. The default is None. + nsamples : int, optional + Number of samples to generate, if no `samples` is provided. The + default is None. + sampling_method : str, optional + Type of sampling, if no `samples` is provided. The default is + 'random'. + return_samples : bool, optional + Retun samples, if no `samples` is provided. The default is False. + + Returns + ------- + mean_pred : dict + Mean of the predictions. + std_pred : dict + Standard deviatioon of the predictions. + """ + # Transform into np array - can also be given as list + samples = np.array(samples) + + # Transform samples to the independent space + samples = self.InputSpace.transform( + samples, + method='user' + ) + # Compute univariate bases for the given samples + if self.meta_model_type.lower() != 'gpe': + univ_p_val = self.univ_basis_vals( + samples, + n_max=np.max(self.pce_deg) + ) + + mean_pred_b = {} + std_pred_b = {} + # Loop over bootstrap iterations + for b_i in range(self.n_bootstrap_itrs): + + # Extract model dictionary + if self.meta_model_type.lower() == 'gpe': + model_dict = self.gp_poly[f'b_{b_i+1}'] + else: + model_dict = self.coeffs_dict[f'b_{b_i+1}'] + + # Loop over outputs + mean_pred = {} + std_pred = {} + for output, values in model_dict.items(): + + mean = np.empty((len(samples), len(values))) + std = np.empty((len(samples), len(values))) + idx = 0 + for in_key, InIdxValues in values.items(): + + # Prediction with GPE + if self.meta_model_type.lower() == 'gpe': + X_T = self.x_scaler[f'b_{b_i+1}'][output].transform(samples) + gp = self.gp_poly[f'b_{b_i+1}'][output][in_key] + y_mean, y_std = gp.predict(X_T, return_std=True) + + else: + # Prediction with PCE + # Assemble Psi matrix + basis = self.basis_dict[f'b_{b_i+1}'][output][in_key] + psi = self.create_psi(basis, univ_p_val) + + # Prediction + if self.bootstrap_method != 'fast' or b_i == 0: + # with error bar, i.e. use clf_poly + clf_poly = self.clf_poly[f'b_{b_i+1}'][output][in_key] + try: + y_mean, y_std = clf_poly.predict( + psi, return_std=True + ) + except TypeError: + y_mean = clf_poly.predict(psi) + y_std = np.zeros_like(y_mean) + else: + # without error bar + coeffs = self.coeffs_dict[f'b_{b_i+1}'][output][in_key] + y_mean = np.dot(psi, coeffs) + y_std = np.zeros_like(y_mean) + + mean[:, idx] = y_mean + std[:, idx] = y_std + idx += 1 + + # Save predictions for each output + if self.dim_red_method.lower() == 'pca': + PCA = self.pca[f'b_{b_i+1}'][output] + mean_pred[output] = PCA.inverse_transform(mean) + std_pred[output] = np.zeros(mean.shape) + else: + mean_pred[output] = mean + std_pred[output] = std + + # Save predictions for each bootstrap iteration + mean_pred_b[b_i] = mean_pred + std_pred_b[b_i] = std_pred + + # Change the order of nesting + mean_pred_all = {} + for i in sorted(mean_pred_b): + for k, v in mean_pred_b[i].items(): + if k not in mean_pred_all: + mean_pred_all[k] = [None] * len(mean_pred_b) + mean_pred_all[k][i] = v + + # Compute the moments of predictions over the predictions + for output in self.out_names: + # Only use bootstraps with finite values + finite_rows = np.isfinite( + mean_pred_all[output]).all(axis=2).all(axis=1) + outs = np.asarray(mean_pred_all[output])[finite_rows] + # Compute mean + mean_pred[output] = np.mean(outs, axis=0) + # Compute standard deviation + if self.n_bootstrap_itrs > 1: + std_pred[output] = np.std(outs, axis=0) + else: + std_pred[output] = std_pred_b[b_i][output] + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + def create_model_error(self, X, y, Model, name='Calib'): + """ + Fits a GPE-based model error. + + Parameters + ---------- + X : array of shape (n_outputs, n_inputs) + Input array. It can contain any forcing inputs or coordinates of + extracted data. + y : array of shape (n_outputs,) + The model response for the MAP parameter set. + name : str, optional + Calibration or validation. The default is `'Calib'`. + + Returns + ------- + self: object + Self object. + + """ + outputNames = self.out_names + self.errorRegMethod = 'GPE' + self.errorclf_poly = self.auto_vivification() + self.errorScale = self.auto_vivification() + + # Read data + # TODO: do this call outside the metamodel + MeasuredData = Model.read_observation(case=name) + + # Fitting GPR based bias model + for out in outputNames: + nan_idx = ~np.isnan(MeasuredData[out]) + # Select data + try: + data = MeasuredData[out].values[nan_idx] + except AttributeError: + data = MeasuredData[out][nan_idx] + + # Prepare the input matrix + scaler = MinMaxScaler() + delta = data # - y[out][0] + BiasInputs = np.hstack((X[out], y[out].reshape(-1, 1))) + X_S = scaler.fit_transform(BiasInputs) + gp = self.gaussian_process_emulator(X_S, delta) + + self.errorScale[out]["y_1"] = scaler + self.errorclf_poly[out]["y_1"] = gp + + return self + + # ------------------------------------------------------------------------- + def eval_model_error(self, X, y_pred): + """ + Evaluates the error model. + + Parameters + ---------- + X : array + Inputs. + y_pred : dict + Predictions. + + Returns + ------- + mean_pred : dict + Mean predition of the GPE-based error model. + std_pred : dict + standard deviation of the GPE-based error model. + + """ + mean_pred = {} + std_pred = {} + + for Outkey, ValuesDict in self.errorclf_poly.items(): + + pred_mean = np.zeros_like(y_pred[Outkey]) + pred_std = np.zeros_like(y_pred[Outkey]) + + for Inkey, InIdxValues in ValuesDict.items(): + + gp = self.errorclf_poly[Outkey][Inkey] + scaler = self.errorScale[Outkey][Inkey] + + # Transform Samples using scaler + for j, pred in enumerate(y_pred[Outkey]): + BiasInputs = np.hstack((X[Outkey], pred.reshape(-1, 1))) + Samples_S = scaler.transform(BiasInputs) + y_hat, y_std = gp.predict(Samples_S, return_std=True) + pred_mean[j] = y_hat + pred_std[j] = y_std + # pred_mean[j] += pred + + mean_pred[Outkey] = pred_mean + std_pred[Outkey] = pred_std + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + class auto_vivification(dict): + """ + Implementation of perl's AutoVivification feature. + + Source: https://stackoverflow.com/a/651879/18082457 + """ + + def __getitem__(self, item): + try: + return dict.__getitem__(self, item) + except KeyError: + value = self[item] = type(self)() + return value + + # ------------------------------------------------------------------------- + def copy_meta_model_opts(self): + """ + This method is a convinient function to copy the metamodel options. + + Returns + ------- + new_MetaModelOpts : object + The copied object. + + """ + # TODO: what properties should be moved to the new object? + new_MetaModelOpts = copy.deepcopy(self) + new_MetaModelOpts.input_obj = self.input_obj#InputObj + new_MetaModelOpts.InputSpace = self.InputSpace + #new_MetaModelOpts.InputSpace.meta_Model = 'aPCE' + #new_MetaModelOpts.InputSpace.InputObj = self.input_obj + #new_MetaModelOpts.InputSpace.ndim = len(self.input_obj.Marginals) + new_MetaModelOpts.n_params = len(self.input_obj.Marginals) + #new_MetaModelOpts.InputSpace.hdf5_file = None + + return new_MetaModelOpts + + # ------------------------------------------------------------------------- + def __select_degree(self, ndim, n_samples): + """ + Selects degree based on the number of samples and parameters in the + sequential design. + + Parameters + ---------- + ndim : int + Dimension of the parameter space. + n_samples : int + Number of samples. + + Returns + ------- + deg_array: array + Array containing the arrays. + + """ + # Define the deg_array + max_deg = np.max(self.pce_deg) + min_Deg = np.min(self.pce_deg) + + # TODO: remove the options for sequential? + #nitr = n_samples - self.InputSpace.n_init_samples + + # Check q-norm + if not np.isscalar(self.pce_q_norm): + self.pce_q_norm = np.array(self.pce_q_norm) + else: + self.pce_q_norm = np.array([self.pce_q_norm]) + + def M_uptoMax(maxDeg): + n_combo = np.zeros(maxDeg) + for i, d in enumerate(range(1, maxDeg+1)): + n_combo[i] = math.factorial(ndim+d) + n_combo[i] /= math.factorial(ndim) * math.factorial(d) + return n_combo + + deg_new = max_deg + #d = nitr if nitr != 0 and self.n_params > 5 else 1 + # d = 1 + # min_index = np.argmin(abs(M_uptoMax(max_deg)-ndim*n_samples*d)) + # deg_new = range(1, max_deg+1)[min_index] + + if deg_new > min_Deg and self.pce_reg_method.lower() != 'fastard': + deg_array = np.arange(min_Deg, deg_new+1) + else: + deg_array = np.array([deg_new]) + + return deg_array + + def generate_polynomials(self, max_deg=None): + # Check for InputSpace + if not hasattr(self, 'InputSpace'): + raise AttributeError('Generate or add InputSpace before generating polynomials') + + ndim = self.InputSpace.ndim + # Create orthogonal polynomial coefficients if necessary + if (self.meta_model_type.lower()!='gpe') and max_deg is not None:# and self.input_obj.poly_coeffs_flag: + self.polycoeffs = {} + for parIdx in tqdm(range(ndim), ascii=True, + desc="Computing orth. polynomial coeffs"): + poly_coeffs = apoly_construction( + self.InputSpace.raw_data[parIdx], + max_deg + ) + self.polycoeffs[f'p_{parIdx+1}'] = poly_coeffs + else: + raise AttributeError('MetaModel cannot generate polynomials in the given scenario!') + + # ------------------------------------------------------------------------- + def _compute_pce_moments(self): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moment (mean) of the surrogate. + pce_stds: dict + The second moment (standard deviation) of the surrogate. + + """ + + # Check if its truly a pce-surrogate + if self.meta_model_type.lower() == 'gpe': + raise AttributeError('Moments can only be computed for pce-type surrogates') + + outputs = self.out_names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(self.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = self.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = self.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = self.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if self.dim_red_method.lower() == 'pca': + PCA = self.pca[f'b_{b_i+1}'][output] + means[output] = PCA.inverse_transform(pce_mean) + stds[output] = PCA.inverse_transform(np.sqrt(pce_var)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + return pce_means, pce_stds diff --git a/examples/umbridge_tsunamitutorial - Copy/test_umbridge.py b/examples/umbridge_tsunamitutorial - Copy/test_umbridge.py new file mode 100644 index 000000000..b83175cf7 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/test_umbridge.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Dec 11 14:03:23 2023 + +Example and test for using umbridge with bayesvalidrox. +Example model is the tsunami model by +docker run -it -p 4242:4242 -v ~/tsunami_output:/output linusseelinger/model-exahype-tsunami + +@author: rkohlhaas +""" + +import joblib +import numpy as np +import umbridge + +import bayesvalidrox as bv + + +if __name__ == '__main__': + + # This model has 2 inputs and four outputs + n_prior_sample = 1000 + priors = bv.Input() + priors.add_marginals() + priors.Marginals[0].name = 'x' + priors.Marginals[0].input_data = np.random.uniform(50,150,n_prior_sample) + priors.add_marginals() + priors.Marginals[1].name = 'y' + priors.Marginals[1].input_data = np.random.uniform(50,150,n_prior_sample) + + # Define the model - level 0 + model0 = bv.PyLinkForwardModel() + #model.link_type = 'Function' + model0.link_type = 'umbridge' + model0.py_file = 'tsunami_model' + model0.name = 'tsunami_model' + model0.Output.names = ['T1', 'T2', 'H1', 'H2'] + #model.observations = data_dict1_times + + # Define the model - level 1 + model1 = bv.PyLinkForwardModel() + #model.link_type = 'Function' + model1.link_type = 'umbridge' + model1.py_file = 'tsunami_model1' + model1.name = 'tsunami_model1' + model1.Output.names = ['T1', 'T2', 'H1', 'H2'] + #model.observations = data_dict1_times + + # Create the surrogate + surrogate_opts0 = bv.MetaModel(priors, model0) + + # Select your metamodel method + surrogate_opts0.meta_model_type = 'aPCE' + surrogate_opts0.pce_reg_method = 'FastARD' + surrogate_opts0.pce_deg = np.arange(1, 5) + surrogate_opts0.pce_q_norm = 0.4#1.0 + + # Select your metamodel method + surrogate_opts0.add_ExpDesign() + surrogate_opts0.ExpDesign.method = 'normal' + surrogate_opts0.ExpDesign.n_init_samples = 50 + surrogate_opts0.ExpDesign.sampling_method = 'latin-hypercube' + surrogate0 = surrogate_opts0.create_metamodel() + print('Surrogate 0 completed') + print('') + + # Create the surrogate + surrogate_opts1 = bv.MetaModel(priors, model1) + + # Select your metamodel method + surrogate_opts1.meta_model_type = 'aPCE' + surrogate_opts1.pce_reg_method = 'FastARD' + surrogate_opts1.pce_deg = np.arange(1, 5) + surrogate_opts1.pce_q_norm = 0.4#1.0 + + # Select your metamodel method + surrogate_opts1.add_ExpDesign() + surrogate_opts1.ExpDesign.method = 'normal' + surrogate_opts1.ExpDesign.n_init_samples = 50 + surrogate_opts1.ExpDesign.sampling_method = 'latin-hypercube' + surrogate1 = surrogate_opts1.create_metamodel() + print('Surrogate 1 completed') + print('') + + # Save surrogate + with open('tsunami0.pk1', 'wb') as output: + joblib.dump(surrogate0, output, 2) + + # Save surrogate + with open('tsunami1.pk1', 'wb') as output: + joblib.dump(surrogate1, output, 2) + + if 0: + # Post processing + L2_PostPCE = bv.PostProcessing(surrogate1) + L2_PostPCE.plot_moments(plot_type='line') + # Plot to check validation visually. + L2_PostPCE.valid_metamodel(n_samples=1) + # Compute and print RMSE error + L2_PostPCE.check_accuracy(n_samples=300) + total_sobol = L2_PostPCE.sobol_indices() + + # Test BayesInference + import copy + from tsunami_model import tsunami_model + true_data = tsunami_model(np.array([[90.0,60.0]])) + model0.observations = true_data + model1.observations = true_data + true_data_nox = copy.deepcopy(true_data) + true_data_nox.pop('x_values') + + # Test surrogate output shape + mean, std = surrogate1.eval_metamodel(np.array([[90.0,60.0]])) + + # Bayesian Inference + if 0: + # Set uncertainty + import pandas as pd + obsData = pd.DataFrame(true_data_nox, columns=model0.Output.names) + DiscrepancyOpts = bv.Discrepancy('') + DiscrepancyOpts.type = 'Gaussian' + DiscrepancyOpts.parameters = (obsData*0.15)**2 + + # Parameter estimation / single model validation via TOM + BayesOpts = bv.BayesInference(surrogate1) + BayesOpts.emulator= True + BayesOpts.plot_post_pred = True + #BayesOpts.inference_method = 'rejection' + BayesOpts.Discrepancy = DiscrepancyOpts + BayesOpts.bootstrap = True + BayesOpts.n_bootstrap_itrs = 10 + BayesOpts.bootstrap_noise = 0.05 + BayesOpts.out_dir = '' + + # Set the MCMC parameters + import emcee + BayesOpts.inference_method = "MCMC" + BayesOpts.mcmc_params = { + 'n_steps': 1e3, + 'n_walkers': 30, + 'moves': emcee.moves.KDEMove(), + 'multiprocessing': False, + 'verbose': False + } + + Bayes = BayesOpts.create_inference() + # Pkl the inference results + with open(f'Bayes_{model0.name}.pkl', 'wb') as output: + joblib.dump(Bayes, output, 2) + + # Model Comparison + if 1: + # Set the models + meta_models = { + "M0": surrogate0, + "M1": surrogate1, + } + + # BME Bootstrap options + opts_bootstrap = { + "bootstrap": True, + "n_samples": 1000, + "Discrepancy": DiscrepancyOpts, + "emulator": True, + "plot_post_pred": False + } + + # Run model comparison + BayesOpts = bv.BayesModelComparison( + justifiability=True, + n_bootstarp=10, + just_n_meas=2 + ) + output_dict = BayesOpts.create_model_comparison( + meta_models, + opts_bootstrap + ) + + import pickle as pkl + # save model comparison results + with open('ModelComparison.pkl', 'wb') as f: + pkl.dump(output_dict, f) + \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial - Copy/test_umbridge_testmodel.py b/examples/umbridge_tsunamitutorial - Copy/test_umbridge_testmodel.py new file mode 100644 index 000000000..68b288f0a --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/test_umbridge_testmodel.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Dec 11 14:03:23 2023 + +Example and test for using umbridge with bayesvalidrox. +Example model is the tsunami model by +docker run -it -p 4242:4242 -v ~/tsunami_output:/output linusseelinger/model-exahype-tsunami + +@author: rkohlhaas +""" + +import joblib +import numpy as np +import umbridge +import bayesvalidrox as bv + +from bayesvalidrox.pylink.pylink import PyLinkForwardModel +from bayesvalidrox.surrogate_models.inputs import Input +from bayesvalidrox.surrogate_models.exp_designs import ExpDesigns +from bayesvalidrox.surrogate_models.surrogate_models import MetaModel +from bayesvalidrox.post_processing.post_processing import PostProcessing +from bayesvalidrox.surrogate_models.engine import Engine + + +if __name__ == '__main__': + + # This model has 2 inputs and four outputs + n_prior_sample = 1000 + priors = bv.Input() + priors.add_marginals() + priors.Marginals[0].name = 'x' + priors.Marginals[0].input_data = np.random.uniform(50,150,n_prior_sample) + priors.add_marginals() + priors.Marginals[1].name = 'y' + priors.Marginals[1].input_data = np.random.uniform(50,150,n_prior_sample) + + # Define the model - level 0 + model = PyLinkForwardModel() + model.link_type = 'Function' + model.py_file = 'testmodel' + model.name = 'testmodel' + #model.link_type = 'um-bridge' + #model.host = 'http://testmodel.linusseelinger.de' + #model.modelparams = {} + #model.name = 'testmodel' + model.Output.names = ['y'] + #model.output_type = 'single-valued' + + # Create the surrogate + surrogate_opts = MetaModel(priors) + + # Select your metamodel method + surrogate_opts.meta_model_type = 'aPCE' + surrogate_opts.pce_reg_method = 'FastARD' + surrogate_opts.pce_deg = np.arange(1, 5) + surrogate_opts.pce_q_norm = 0.4 + + # Select your metamodel method + ExpDesign = ExpDesigns(priors) + ExpDesign.n_init_samples = 50 + ExpDesign.sampling_method = 'latin-hypercube' + + engine = Engine(surrogate_opts, model, ExpDesign) + engine.start_engine() + engine.train_normal(parallel = False) + print('Surrogate completed') + print('') + + # Save surrogate + with open('testmodel.pk1', 'wb') as output: + joblib.dump(engine.MetaModel, output, 2) + + # Post processing + L2_PostPCE = PostProcessing(engine) + L2_PostPCE.plot_moments(plot_type='line') + # Plot to check validation visually. + L2_PostPCE.valid_metamodel(n_samples=1) + # Compute and print RMSE error + L2_PostPCE.check_accuracy(n_samples=300) + total_sobol = L2_PostPCE.sobol_indices() diff --git a/examples/umbridge_tsunamitutorial - Copy/testmodel.py b/examples/umbridge_tsunamitutorial - Copy/testmodel.py new file mode 100644 index 000000000..e4da164cf --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/testmodel.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +Runs the umbridge command for the tsunami model + +@author: Rebecca Kohlhaas +""" +import umbridge +import numpy as np + +def testmodel(params): + model = umbridge.HTTPModel('http://testmodel.linusseelinger.de', 'forward') + + out = np.array(model([[11.0]])) + + return {'y':out,'x_values':[0]} + + + \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial - Copy/tsunami_model.py b/examples/umbridge_tsunamitutorial - Copy/tsunami_model.py new file mode 100644 index 000000000..7f8e54170 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/tsunami_model.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +Runs the umbridge command for the tsunami model + +@author: Rebecca Kohlhaas +""" +import umbridge +import numpy as np + +def tsunami_model(params): + model = umbridge.HTTPModel('http://localhost:4242', 'forward') + out = np.array(model(np.ndarray.tolist(params), {'level':0})) + + return {'T1':out[:,0], 'T2':out[:,1], 'H1':out[:,2], 'H2':out[:,3], + 'x_values':[0]} + + + \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial - Copy/tsunami_model1.py b/examples/umbridge_tsunamitutorial - Copy/tsunami_model1.py new file mode 100644 index 000000000..3e56801e5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial - Copy/tsunami_model1.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Runs the umbridge command for the tsunami model + +@author: Rebecca Kohlhaas +""" +import umbridge +import numpy as np + +def tsunami_model1(params): + model = umbridge.HTTPModel('http://localhost:4242', 'forward') + out = np.array(model(np.ndarray.tolist(params), {'level':1})) + + return {'T1': out[:,0], 'T2': out[:,1], 'H1': out[:,2], 'H2': out[:,3], 'x_values': [0]} + + \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/__init__.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/__init__.py new file mode 100644 index 000000000..8e865af80 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +__version__ = "0.0.5" + +from .pylink.pylink import PyLinkForwardModel +from .surrogate_models.surrogate_models import MetaModel +#from .surrogate_models.meta_model_engine import MetaModelEngine +from .surrogate_models.engine import Engine +from .surrogate_models.inputs import Input +from .post_processing.post_processing import PostProcessing +from .bayes_inference.bayes_inference import BayesInference +from .bayes_inference.bayes_model_comparison import BayesModelComparison +from .bayes_inference.discrepancy import Discrepancy + +__all__ = [ + "__version__", + "PyLinkForwardModel", + "Input", + "Discrepancy", + "MetaModel", + #"MetaModelEngine", + "Engine", + "PostProcessing", + "BayesInference", + "BayesModelComparison" + ] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..beaab3c798a63fcfbc361982388fdf10830a787e GIT binary patch literal 795 zcmZWn%Wl*#6m>Gm%w#4reNc%7iwY!=W|MT&9YUy-LJ>tHAvWGvZenJv`VrYl%kVku z_$5oMSn&(2uy5%A!BI}mJ-L3IBkS30g8WGCJ!aoxguaL3@8LD{+`qQ*P$P`$sE$P> zV;o0;55zzwI02rBR1WbFcq&G6jK{!-B9jw50X`B_nd2PzSj^-c&w*!RNABX?2(3^( z`4Zv1diowM^3Ul}aa0`ti2Ux0$n7sTZ@IcU)8>Yn`a;)Ccs09VExjvtw#7@e;)?nI z>A7mU)|2^C+jePm#jNFO6_gXYVfI{oWQM6KG#`KhtG&>&p@v(nygohUwlb`ts@g0v zHznkn8OyaI#DtJc8XyZW2#^FA1{ehxdw93lHz92|Yc|5$C~iM6-95COF?vN?Mr811 zi@pHsx<`Gvkly|69Kygd?CtLV*T_Q*77pqT8y^K}wpkRt8jkJ`FGD<p-{n*EYVhWs z^wi&7V1rcK5FrEipx<2o$ra*rBSNSUgnUKjAVe47=bKWhwyeqz)~8;YE4>zLN^N<n zt4=c2+VT}|Uw4<~nb0>&+OA93=b8#$8~v#y-UM$6@tM2vQ-8EhuxH^`*|2;P<#8VU H^TfXZNO$QO literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..522dab9e775d3ce6f28ac1ac7102d1843b71523e GIT binary patch literal 968 zcmZuvO>5LZ7@q7$vb)(`Yw-(uC|-nB3_U1_iU(V@1uF~UB?N}qWV#(XA7Lh`T~GTj zyn7KZ`d4yXa$4}@ZK1cGoEf{7geEV~Jnxe?Gw=H(-v@&p(AQ-C6K^#E_-&H))wm?* zQj@PB0U=17q(L3l2pf*!P1<Cwuw{9RwwW8cmba<LI$_6hmv&h%>{;$npY_AO<sCX; z!*FPMm)>9-;f4dIAnAQ`!kdZz5sdm@+B?Bc@br(P&mTGE=6Lp=@RPSfenv7m6bYtU z?H=L`trPbRpAwF>+&<uGo@p{13zdzfh_O<HPmS^#&9FM)M_6JWo8ntmv777)mLf@% z;9B?hh>9gn5szo1Zs|jKilrigLnyUdK)MEugR*6yZNM|oG0@fUVYDfIy_SP?Ms@eW zzs0^@-dDMlVu~^hnHfg~b;0gi-mS|4wsYD8uX#$$?8<gmZl`*Fm|htW)N<QzxjiwS zK(aO^sO5H`@<C0#tg^ks_{upuc)3+CPX3!|Ju5v35v36R0O#5vaKUz;N1v2-IFcvg zm>wgfqCFAk4D(Dy??|?vPa?bPDWW8i;w-{vh@}*(C}$H%k|~Cn$~j^r%QGPfqP2Rc zM<f}9`ZHW~Uh2kkieJfl`gHS?sb3maO~-MT!`pLz2_6^KSb%3mHJ0E}QH=$7SX5&H gUKG{1PT4O&B^KaGQH@p0_uUm(!`w5syrX;m3*dMy2><{9 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5ebaedb4c8b77b5d7dbd0a6945f09079d8b10e4 GIT binary patch literal 860 zcmZWm&x_MQ6i(8gY18gn1P>k-JqSG{?6T}dM8vK_!Ae02G6aU%%(M=jnS`07Zujif zf5Mypf>*&mqE}D;3!Z#4b*sh+`SQIlZ{E!N9vKXJ9;^>vzS3`j=Y6-q-wQPF8N8+d zpdRw5PXpo000q9~4bhNI)O5TlTC$DWj<-Zdc2U>ywg_bp^&IbrzKl@hcvlSM5Dgs< z#gRNl$G*4nXz!Dc?$G`lZyepUPLtE*;)f5XkNw?fzJ0~j`em-)6HRA1WdhW2#!7M< z936reYQ+_U|E;MisuIX>o||&6^Nbn8)ygW*$(EU^S~AU4W|Qwa#Z{Z+vLKq9T!G%d z<R;UsAS&CA!(AWa4bz6_3S(_e(k%<2g@%Qug|>x`g)YGB@km>@(V*B0Xd~Hw+;;T9 zR9fdNQZg)UUnZ#wt}c35mlFxy@AqKlT6Slnd;cYJYlCqYMJEMVfs2C|NiB9)M<-X- z9?Wn3Nouj{4Lz!<zq4E$I6Ii=JV5vB$@Gt}&c0m-V<H5`pFJH}>n!~IIC-2d3^<-@ zw$9H|TFL5qkFkU?Ya;j!DPbP*l995~ES^s0@#SK+czd2)q*oOeG|nVhvy>EtNO@MI z3?P=vbjcMFnwd(JW^?uq+bmtF)LnH0m8s6JQw%=v5@Q(KuKNVKs|0&$M{h;|%^>ps Gd4gX;Q2|8& literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__init__.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__init__.py new file mode 100644 index 000000000..df8d93568 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from .bayes_inference import BayesInference +from .mcmc import MCMC + +__all__ = [ + "BayesInference", + "MCMC" + ] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..430b9885a8c8bd658da24bbc4ac1a6a0a74f69e6 GIT binary patch literal 303 zcmYjNJ5B>J5cMx4LJ1UHffU=|3m}9D;!`9-LNwc0j&0Z#_8Qq<AV=W{T*)mJSD-+Q z7ez4AJilkZnbFwKX1fT29n8%eoF7H}4+7#8G9ChGq_IT~*BBR0EOE4^z^P^rq-J__ zi>jSZ4Au(gy)(Hn@w&S=!F0;N4O=dji%?ny3b3k1d4F9@qTRZN*UX%9YVhQ-5Yk#9 z-ccBr!UA74cU|I&-$fH550AdFjg*m}d(}JBrN}Sabk(o<h4n8tGBtb{^DJ$vgMa;1 ie?z$d-X<ZAo;G=M?7Z%+IVo$z@;g&9#e@<(`ThY0HBIvX literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b22adcbe445e7b81edc8dac6cb9ba03678c61ab9 GIT binary patch literal 354 zcmZ3^%ge<81T4a;sWXA}V-N=hn4pZ$YCy(xh7^Vr#vF!R#wbQc5SuB7DVI5l8OUZ% zVM%9-Vo6~QX3%7N$p}=e$#{#;DX}uO*fTFJwJ0?&ITa|v;_K||T*M5NE@A-^ewwVe z_>(}2;xl2Yz_Pbka+7nD!D?=?$Hyn;<iy9XWcUo!!tg81*(xTqIJKxarYJi<BPSy< zu{g#hKe;qFHLs*N#yzvdqckbTEhoP`Ah9GP25fp+VoqjCQGNx4hp;Oq9>~rtiI3MS zsQkrYlbfGXnv-f*#0|6t<b`58An}2jk&*EO8v~=x1qN+obb~?c0xANkVimo?!u5fb PnVYSF9R!OwfkprT7ZzXr literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..287257c1ca9b3f3a6d7e176e006ad432f8c685bf GIT binary patch literal 368 zcmYk1K}rKL6ow}=(^{m}OStJ`3Ps$Ah&XP#s0cD3Lm;G+HyWDE49TRlE<J%4@Bm)H zt+$x1E3e=}d}$GVkT3tA{CT|a(P%%wdU|^o&$xeh^S?qg7r5*ZLIi@SK$DyhuR|5; zD34G_BEApvSoCg#asQKGbWFN~OTGa+t4c6X6@Vx4Je{Y;w=@yrdfe*{7e2(~Z)$s+ z$GXtPHq-4f#+731H86eu(BtbRJ*AliW2u2<J*C2Fx85<)vI4`EeB`aHtE2?pIs?fp zy-BXJd3JX^IiU+Dl}HNBmq2;bC@PDF0wU2REoH@(0qaz2SJMaPQ^r+vJLw8L3sbLm h?r(0&P|KFFNwet&XSx<n!MXpX9Uz8e7=<MK{sG1iY1;q* literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e89dfb5e6b3a873ac2f40dcc2084aa52caaedcd6 GIT binary patch literal 31276 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f059bde3e71ad6231b8a26e02849bd6298052797 GIT binary patch literal 60952 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_inference.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a37330680c29bbfdba5a1bfd98041dda24957604 GIT binary patch literal 31419 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57322b839ff7d50ea32d3b36ce011c09cf91e232 GIT binary patch literal 15645 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37d75830876e7d6e44eb45cc242d1f6636c8d2f6 GIT binary patch literal 27157 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%0A5<{ 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 Kk9o_6!v6ugi7!zA literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/bayes_model_comparison.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b58f792ac36504c702205afc34228600f9bbba77 GIT binary patch literal 15716 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc71688a4cae4f74ec3a67838fca659881c520c9 GIT binary patch literal 3806 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 I`#)>`7Zrzs-v9sr literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f1c5c8635a64bcf45f856426c8597e67374b985 GIT binary patch literal 4661 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 BCMo~` literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/discrepancy.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f154800917aeaef9c499abf13d47fcca6ffc639b GIT binary patch literal 3869 zcmb7H%WfRU744pv$RQOefMPgV1cg9=I0`w4ZDd2(MkLV|m_W2)ORzz7)U4^MnJKbg zuBs+Ed;meDZC3dKd6_>5vdv%gHY@)^Hp#iwj~R(xBu%i;kE;7P_uNx8{PyjkhwIP( z_^0^vj_3W09#*d|9)5>^^ALmZgdcl}f9U&k--$a(_ps}GPd(8Uz1N=Tz3LqHg#WcS z>i>ZG-oeN(ho7D2d(x;`Y9e~KdbQSng}2f>^o4iW5&mIUtc$)Fy!K)3mRNi39ri^J zR)^)ro-&b^IZvYn|NENf4H>SLmn@38F>IP?_Lwi=m#0jnQ>kSdNtQ@E&&1d*`bIJ# zrz(}q&Lz{bnS+&D@>tmgvl*L6Cci6qO!sGVZrPb+5o{)zkTK(_VBA>~5^*UP7qe0) zEZAa!%#Dh(lm(+PgS#k8jS^Bjhtn*Mvon=as0p{bLucmx{lLm|JDFZCuER@re_2O! zea${$0jAC)9$!AY-U<-6<s<g%*3tI;`<0oqITC(51bF)D<>f(mnH3hMf)TRJwKOud z#sx$u$mvu@c+RFSnnZF_XqjLRlUf5AO1Mg0r96rX&7;MbeU2|iC3&nOz_!hlbr=D= z3Sr@_af9WI3!$t!mFy`mj4O{&rmiSEQ+CcSq|V?OQ{ilesVR^<<r<}oWEB^;TAjQ6 zzE-n@Bbz0DE$E17iPr(}s=r+QW}5|W9m>)mwx2o>P$I$~0JLeIN^KO1h#UdDnrLqE zxJ|ia6C?GhduDm2QtP6l$}fwkSODnTx-A^^3Q$xmyQo&fA8!$HR)7kUoD}4&!o^{7 z%Hu*(c)?a{bA<~iE1~w|c)3+|>cq*0ax4dz8rEGkv|1q>fwwYY$w3z>b>RPWHH;lK zpg#xYnm(AZET>$745-Ubxr+HDmUUepvM=0M_Gp)VLnJv#v$GTs3MHsJmkBdOSCONt zF%UtAxj<DaWG*p)&MVY5H4v?j$F+|l{Xe{HI~O_EoJ2;e3khj3R3=BYI(PJR&BE)^ zCjnG3;V(aI>9T(vIxB6PB6!yl%Sa#~lyB1x&OvR4DoS;DJ_o&=2A!!mCIvetZpMpB z2rG-!?FITtTMl}vG%qZxg9qPTOFLsUPo;GaY_mmHuv8*7$YHIXoaI`fITEgC5Cz1h zI6K-Wi$|3jkJ&+HtIo9~p}?dKnIYCJMQj`jlFnku47!ZNToGFZMS)zBm{S}=@mU5B zE-(~PD@jsSH*N#TO#;;QePpYKlExX>X)pKa0;Y|G?V_)b-8(|ly{9)2MyU84YDBTT zn}a;hF`)tmh`TKZ>}<_6C2-{=152>k)=^FF$48^_K9r|Q9c^A%s>@7gMeh2dHCO8@ zn=IJTGun#AU%0vB6!bGk+f4FkUQ1YQg~|qAWNgk)WyKWA??(9ws)Nh%ogzM`638h> zbX2vY2M>-aGmxq%w2NE<I*3*q<a2se*C)-CskZ~jf0mB1zS#jD9JMSkMV@Dxa5Nd4 za$PxC!D<&Qh@j6J0H%VQ@gBGQb85QQ?H_7sc&Am~DjD{uu^hLIV#KCJ9cydorl{1( zxB@x8S;<n`zhf4w6B(;{mI)LeI|Z_>cTqyQsqiB}=IobVxz^-=5cO70MRec6{}cS1 z_b^=fS6=8{buju@U5p*!;V|SMjJoA|OWSh2Ekik60ygTEJtO0(9>9{mMFUPv-rqb; z2fu&6d9oY4z$Rt_El;u!0#PKzc{T1NI2&o~c-0oQGnL%pFtD@#<jbAC7tdaN`_cHf z!K6^J*ohK;A_Jc1aiF3+kQjE7X@J8Ok8#8RVa(|V^N?ogA`K>VFvCWsgwD>Zr?5Sv z1(Zg89vJ6~axKI+WyA1e#A_%E&mZ9L;vO|?GqITz5pvB%NcQpXko*&FDkLrNJnp>m zuRB+r<L;F&e9;lzzYwxLhjQNz-rT~sweM+WKU}v%T5-Jb$``$puD+Ogn7e6jFW<lN z_q;#;;u<!NH{blEntj#%Ii9}veeb)MctZ!+KL4v<pIM0&PbDD?4jGQa6U3}hx>a?l zsk$nFj;@vXwPdC5jRfx8WG*;KGk%P@0K7eE)a<0-zO1$~aHI9nD&|i6Dh-?1cftGW z07R?lIw+C}<Qq-X%-L#*$&9q7IfBsSuO!%&-tg5ray!O{q1$VAaYoSG^{bh4h|E?S z#x_es=fsTKrDT2;(I%XgWXpkuoMg!lD33Slly_Xj5W=wf$xv=2{5;Gf845YmZql7{ zz4fYzcCN+BjagmP@Uy*gb2aL6z5OXv_KoG%l$*2q5FDNeS*~e*77FND+5bJrZOd*f z({lY;y|J3IN9tbo5$a5q1N0jXGozkfC+9z<;U0#=jb?!o=dR1EVFTaF;Y`}PVvq4` z-pAnG9r#1P=MVm~)*E#1cJHFQ?)mR`F5X-1u;s#0S5s$cYORCOfI5`o3d3?3hWK$% z#B{$IhV;9s{&Fh}MHYpj-lUbkq=EEjWuWkM7X!(Y>+?0g_t9|R-i`X@hKW?Z7(3kb z&oJlk;afT~#xE6}&CpF0gN)4>TQaJJ3Z$m04_ROF=mK!4tbJUC{VC;TXxQ{OyZ;5X C(w;v6 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d2122246d54ec5697803cbce28900e077b2306a GIT binary patch literal 18924 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 W6YnAs1G%l!A8`@AH@FHoxc@Kt+VTSc literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e0ec7bf61abc72bc8218d603f606f1eca2cc9ab GIT binary patch literal 35893 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 IcNqr$ACvc7^8f$< literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/__pycache__/mcmc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9fe4689524895c2149048d489b22b08e85026df GIT binary patch literal 18959 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	o4MB>fKYEXpNq!HIDoLFs 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_inference.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_inference.py new file mode 100644 index 000000000..1898a8ae6 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_inference.py @@ -0,0 +1,1532 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import os +import copy +import pandas as pd +from tqdm import tqdm +from scipy import stats +import scipy.linalg as spla +import joblib +import seaborn as sns +import corner +import h5py +import multiprocessing +import gc +from sklearn.metrics import mean_squared_error, r2_score +from sklearn import preprocessing +from matplotlib.patches import Patch +import matplotlib.lines as mlines +from matplotlib.backends.backend_pdf import PdfPages +import matplotlib.pylab as plt + +from .mcmc import MCMC + +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class BayesInference: + """ + A class to perform Bayesian Analysis. + + + Attributes + ---------- + MetaModel : obj + Meta model object. + discrepancy : obj + The discrepancy object for the sigma2s, i.e. the diagonal entries + of the variance matrix for a multivariate normal likelihood. + name : str, optional + The type of analysis, either calibration (`Calib`) or validation + (`Valid`). The default is `'Calib'`. + emulator : bool, optional + Analysis with emulator (MetaModel). The default is `True`. + bootstrap : bool, optional + Bootstrap the analysis. The default is `False`. + req_outputs : list, optional + The list of requested output to be used for the analysis. + The default is `None`. If None, all the defined outputs for the model + object is used. + selected_indices : dict, optional + A dictionary with the selected indices of each model output. The + default is `None`. If `None`, all measurement points are used in the + analysis. + samples : array of shape (n_samples, n_params), optional + The samples to be used in the analysis. The default is `None`. If + None the samples are drawn from the probablistic input parameter + object of the MetaModel object. + n_samples : int, optional + Number of samples to be used in the analysis. The default is `500000`. + If samples is not `None`, this argument will be assigned based on the + number of samples given. + measured_data : dict, optional + A dictionary containing the observation data. The default is `None`. + if `None`, the observation defined in the Model object of the + MetaModel is used. + inference_method : str, optional + A method for approximating the posterior distribution in the Bayesian + inference step. The default is `'rejection'`, which stands for + rejection sampling. A Markov Chain Monte Carlo sampler can be simply + selected by passing `'MCMC'`. + mcmc_params : dict, optional + A dictionary with args required for the Bayesian inference with + `MCMC`. The default is `None`. + + Pass the mcmc_params like the following: + + >>> mcmc_params:{ + 'init_samples': None, # initial samples + 'n_walkers': 100, # number of walkers (chain) + 'n_steps': 100000, # number of maximum steps + 'n_burn': 200, # number of burn-in steps + 'moves': None, # Moves for the emcee sampler + 'multiprocessing': False, # multiprocessing + 'verbose': False # verbosity + } + The items shown above are the default values. If any parmeter is + not defined, the default value will be assigned to it. + bayes_loocv : bool, optional + Bayesian Leave-one-out Cross Validation. The default is `False`. If + `True`, the LOOCV procedure is used to estimate the bayesian Model + Evidence (BME). + n_bootstrap_itrs : int, optional + Number of bootstrap iteration. The default is `1`. If bayes_loocv is + `True`, this is qualt to the total length of the observation data + set. + perturbed_data : array of shape (n_bootstrap_itrs, n_obs), optional + User defined perturbed data. The default is `[]`. + bootstrap_noise : float, optional + A noise level to perturb the data set. The default is `0.05`. + just_analysis : bool, optional + Justifiability analysis. The default is False. + valid_metrics : list, optional + List of the validation metrics. The following metrics are supported: + + 1. log_BME : logarithm of the Bayesian model evidence + 2. KLD : Kullback-Leibler Divergence + 3. inf_entropy: Information entropy + The default is `['log_BME']`. + plot_post_pred : bool, optional + Plot posterior predictive plots. The default is `True`. + plot_map_pred : bool, optional + Plot the model outputs vs the metamodel predictions for the maximum + a posteriori (defined as `max_a_posteriori`) parameter set. The + default is `False`. + max_a_posteriori : str, optional + Maximum a posteriori. `'mean'` and `'mode'` are available. The default + is `'mean'`. + corner_title_fmt : str, optional + Title format for the posterior distribution plot with python + package `corner`. The default is `'.2e'`. + + """ + + def __init__(self, engine, MetaModel = None, discrepancy=None, emulator=True, + name='Calib', bootstrap=False, req_outputs=None, + selected_indices=None, samples=None, n_samples=100000, + measured_data=None, inference_method='rejection', + mcmc_params=None, bayes_loocv=False, n_bootstrap_itrs=1, + perturbed_data=[], bootstrap_noise=0.05, just_analysis=False, + valid_metrics=['BME'], plot_post_pred=True, + plot_map_pred=False, max_a_posteriori='mean', + corner_title_fmt='.2e'): + + self.engine = engine + self.MetaModel = engine.MetaModel + self.Discrepancy = discrepancy + self.emulator = emulator + self.name = name + self.bootstrap = bootstrap + self.req_outputs = req_outputs + self.selected_indices = selected_indices + self.samples = samples + self.n_samples = n_samples + self.measured_data = measured_data + self.inference_method = inference_method + self.mcmc_params = mcmc_params + self.perturbed_data = perturbed_data + self.bayes_loocv = bayes_loocv + self.n_bootstrap_itrs = n_bootstrap_itrs + self.bootstrap_noise = bootstrap_noise + self.just_analysis = just_analysis + self.valid_metrics = valid_metrics + self.plot_post_pred = plot_post_pred + self.plot_map_pred = plot_map_pred + self.max_a_posteriori = max_a_posteriori + self.corner_title_fmt = corner_title_fmt + + # ------------------------------------------------------------------------- + def create_inference(self): + """ + Starts the inference. + + Returns + ------- + BayesInference : obj + The Bayes inference object. + + """ + + # Set some variables + MetaModel = self.MetaModel + Model = self.engine.Model + n_params = MetaModel.n_params + output_names = Model.Output.names + par_names = self.engine.ExpDesign.par_names + + # If the prior is set by the user, take it. + if self.samples is None: + self.samples = self.engine.ExpDesign.generate_samples( + self.n_samples, 'random') + else: + try: + samples = self.samples.values + except AttributeError: + samples = self.samples + + # Take care of an additional Sigma2s + self.samples = samples[:, :n_params] + + # Update number of samples + self.n_samples = self.samples.shape[0] + + # ---------- Preparation of observation data ---------- + # Read observation data and perturb it if requested. + if self.measured_data is None: + self.measured_data = Model.read_observation(case=self.name) + # Convert measured_data to a data frame + if not isinstance(self.measured_data, pd.DataFrame): + self.measured_data = pd.DataFrame(self.measured_data) + + # Extract the total number of measurement points + if self.name.lower() == 'calib': + self.n_tot_measurement = Model.n_obs + else: + self.n_tot_measurement = Model.n_obs_valid + + # Find measurement error (if not given) for post predictive plot + if not hasattr(self, 'measurement_error'): + if isinstance(self.Discrepancy, dict): + Disc = self.Discrepancy['known'] + else: + Disc = self.Discrepancy + if isinstance(Disc.parameters, dict): + self.measurement_error = {k: np.sqrt(Disc.parameters[k]) for k + in Disc.parameters.keys()} + else: + try: + self.measurement_error = np.sqrt(Disc.parameters) + except TypeError: + pass + + # ---------- Preparation of variance for covariance matrix ---------- + # Independent and identically distributed + total_sigma2 = dict() + opt_sigma_flag = isinstance(self.Discrepancy, dict) + opt_sigma = None + for key_idx, key in enumerate(output_names): + + # Find opt_sigma + if opt_sigma_flag and opt_sigma is None: + # Option A: known error with unknown bias term + opt_sigma = 'A' + known_discrepancy = self.Discrepancy['known'] + self.Discrepancy = self.Discrepancy['infer'] + sigma2 = np.array(known_discrepancy.parameters[key]) + + elif opt_sigma == 'A' or self.Discrepancy.parameters is not None: + # Option B: The sigma2 is known (no bias term) + if opt_sigma == 'A': + sigma2 = np.array(known_discrepancy.parameters[key]) + else: + opt_sigma = 'B' + sigma2 = np.array(self.Discrepancy.parameters[key]) + + elif not isinstance(self.Discrepancy.InputDisc, str): + # Option C: The sigma2 is unknown (bias term including error) + opt_sigma = 'C' + self.Discrepancy.opt_sigma = opt_sigma + n_measurement = self.measured_data[key].values.shape + sigma2 = np.zeros((n_measurement[0])) + + total_sigma2[key] = sigma2 + + self.Discrepancy.opt_sigma = opt_sigma + self.Discrepancy.total_sigma2 = total_sigma2 + + # If inferred sigma2s obtained from e.g. calibration are given + try: + self.sigma2s = self.Discrepancy.get_sample(self.n_samples) + except: + pass + + # ---------------- Bootstrap & TOM -------------------- + if self.bootstrap or self.bayes_loocv or self.just_analysis: + if len(self.perturbed_data) == 0: + # zero mean noise Adding some noise to the observation function + self.perturbed_data = self._perturb_data( + self.measured_data, output_names + ) + else: + self.n_bootstrap_itrs = len(self.perturbed_data) + + # -------- Model Discrepancy ----------- + if hasattr(self, 'error_model') and self.error_model \ + and self.name.lower() != 'calib': + # Select posterior mean as MAP + MAP_theta = self.samples.mean(axis=0).reshape((1, n_params)) + # MAP_theta = stats.mode(self.samples,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_MAP, y_std_MAP = MetaModel.eval_metamodel(samples=MAP_theta) + + # Train a GPR meta-model using MAP + self.error_MetaModel = MetaModel.create_model_error( + self.bias_inputs, y_MAP, Name=self.name + ) + + # ----------------------------------------------------- + # ----- Loop over the perturbed observation data ------ + # ----------------------------------------------------- + # Initilize arrays + logLikelihoods = np.zeros((self.n_samples, self.n_bootstrap_itrs), + dtype=np.float16) + BME_Corr = np.zeros((self.n_bootstrap_itrs)) + log_BME = np.zeros((self.n_bootstrap_itrs)) + KLD = np.zeros((self.n_bootstrap_itrs)) + inf_entropy = np.zeros((self.n_bootstrap_itrs)) + + # Compute the prior predtions + # Evaluate the MetaModel + if self.emulator: + y_hat, y_std = MetaModel.eval_metamodel(samples=self.samples) + self.__mean_pce_prior_pred = y_hat + self._std_pce_prior_pred = y_std + + # Correct the predictions with Model discrepancy + if hasattr(self, 'error_model') and self.error_model: + y_hat_corr, y_std = self.error_MetaModel.eval_model_error( + self.bias_inputs, self.__mean_pce_prior_pred + ) + self.__mean_pce_prior_pred = y_hat_corr + self._std_pce_prior_pred = y_std + + # Surrogate model's error using RMSE of test data + if hasattr(MetaModel, 'rmse'): + surrError = MetaModel.rmse + else: + surrError = None + + else: + # Evaluate the original model + self.__model_prior_pred = self._eval_model( + samples=self.samples, key='PriorPred' + ) + surrError = None + + # Start the likelihood-BME computations for the perturbed data + for itr_idx, data in tqdm( + enumerate(self.perturbed_data), + total=self.n_bootstrap_itrs, + desc="Bootstrapping the BME calculations", ascii=True + ): + + # ---------------- Likelihood calculation ---------------- + if self.emulator: + model_evals = self.__mean_pce_prior_pred + else: + model_evals = self.__model_prior_pred + + # Leave one out + if self.bayes_loocv or self.just_analysis: + self.selected_indices = np.nonzero(data)[0] + + # Prepare data dataframe + nobs = list(self.measured_data.count().values[1:]) + numbers = list(np.cumsum(nobs)) + indices = list(zip([0] + numbers, numbers)) + data_dict = { + output_names[i]: data[j:k] for i, (j, k) in + enumerate(indices) + } + #print(output_names) + #print(indices) + #print(numbers) + #print(nobs) + #print(self.measured_data) + #for i, (j, k) in enumerate(indices): + # print(i,j,k) + #print(data) + #print(data_dict) + #stop + + # Unknown sigma2 + if opt_sigma == 'C' or hasattr(self, 'sigma2s'): + logLikelihoods[:, itr_idx] = self.normpdf( + model_evals, data_dict, total_sigma2, + sigma2=self.sigma2s, std=surrError + ) + else: + # known sigma2 + logLikelihoods[:, itr_idx] = self.normpdf( + model_evals, data_dict, total_sigma2, + std=surrError + ) + + # ---------------- BME Calculations ---------------- + # BME (log) + log_BME[itr_idx] = np.log( + np.nanmean(np.exp(logLikelihoods[:, itr_idx], + dtype=np.longdouble))#float128)) + ) + + # BME correction when using Emulator + if self.emulator: + BME_Corr[itr_idx] = self.__corr_factor_BME( + data_dict, total_sigma2, log_BME[itr_idx] + ) + + # Rejection Step + if 'kld' in list(map(str.lower, self.valid_metrics)) and\ + 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + # Random numbers between 0 and 1 + unif = np.random.rand(1, self.n_samples)[0] + + # Reject the poorly performed prior + Likelihoods = np.exp(logLikelihoods[:, itr_idx], + dtype=np.float64) + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + posterior = self.samples[accepted] + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean( + logLikelihoods[:, itr_idx][accepted] + ) + + # Calculate Kullback-Leibler Divergence + KLD[itr_idx] = postExpLikelihoods - log_BME[itr_idx] + + # Posterior-based expectation of prior densities + if 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + n_thread = int(0.875 * multiprocessing.cpu_count()) + with multiprocessing.Pool(n_thread) as p: + postExpPrior = np.mean(np.concatenate( + p.map( + self.engine.ExpDesign.JDist.pdf, + np.array_split(posterior.T, n_thread, axis=1)) + ) + ) + # Information Entropy based on Entropy paper Eq. 38 + inf_entropy[itr_idx] = log_BME[itr_idx] - postExpPrior - \ + postExpLikelihoods + + # Clear memory + gc.collect(generation=2) + + # ---------- Store metrics for perturbed data set ---------------- + # Likelihoods (Size: n_samples, n_bootstrap_itr) + self.log_likes = logLikelihoods + + # BME (log), KLD, infEntropy (Size: 1,n_bootstrap_itr) + self.log_BME = log_BME + + # BMECorrFactor (log) (Size: 1,n_bootstrap_itr) + if self.emulator: + self.log_BME_corr_factor = BME_Corr + + if 'kld' in list(map(str.lower, self.valid_metrics)): + self.KLD = KLD + if 'inf_entropy' in list(map(str.lower, self.valid_metrics)): + self.inf_entropy = inf_entropy + + # BME = BME + BMECorrFactor + if self.emulator: + self.log_BME += self.log_BME_corr_factor + + # ---------------- Parameter Bayesian inference ---------------- + if self.inference_method.lower() == 'mcmc': + # Instantiate the MCMC object + MCMC_Obj = MCMC(self) + self.posterior_df = MCMC_Obj.run_sampler( + self.measured_data, total_sigma2 + ) + + elif self.name.lower() == 'valid': + # Convert to a dataframe if samples are provided after calibration. + self.posterior_df = pd.DataFrame(self.samples, columns=par_names) + + else: + # Rejection sampling + self.posterior_df = self._rejection_sampling() + + # Provide posterior's summary + print('\n') + print('-'*15 + 'Posterior summary' + '-'*15) + pd.options.display.max_columns = None + pd.options.display.max_rows = None + print(self.posterior_df.describe()) + print('-'*50) + + # -------- Model Discrepancy ----------- + if hasattr(self, 'error_model') and self.error_model \ + and self.name.lower() == 'calib': + if self.inference_method.lower() == 'mcmc': + self.error_MetaModel = MCMC_Obj.error_MetaModel + else: + # Select posterior mean as MAP + if opt_sigma == "B": + posterior_df = self.posterior_df.values + else: + posterior_df = self.posterior_df.values[:, :-Model.n_outputs] + + # Select posterior mean as Maximum a posteriori + map_theta = posterior_df.mean(axis=0).reshape((1, n_params)) + # map_theta = stats.mode(Posterior_df,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_MAP, y_std_MAP = MetaModel.eval_metamodel(samples=map_theta) + + # Train a GPR meta-model using MAP + self.error_MetaModel = MetaModel.create_model_error( + self.bias_inputs, y_MAP, Name=self.name + ) + + # -------- Posterior perdictive ----------- + self._posterior_predictive() + + # ----------------------------------------------------- + # ------------------ Visualization -------------------- + # ----------------------------------------------------- + # Create Output directory, if it doesn't exist already. + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + os.makedirs(out_dir, exist_ok=True) + + # -------- Posteior parameters -------- + if opt_sigma != "B": + par_names.extend( + [self.Discrepancy.InputDisc.Marginals[i].name for i + in range(len(self.Discrepancy.InputDisc.Marginals))] + ) + # Pot with corner + figPosterior = corner.corner(self.posterior_df.to_numpy(), + labels=par_names, + quantiles=[0.15, 0.5, 0.85], + show_titles=True, + title_fmt=self.corner_title_fmt, + labelpad=0.2, + use_math_text=True, + title_kwargs={"fontsize": 28}, + plot_datapoints=False, + plot_density=False, + fill_contours=True, + smooth=0.5, + smooth1d=0.5) + + # Loop over axes and set x limits + if opt_sigma == "B": + axes = np.array(figPosterior.axes).reshape( + (len(par_names), len(par_names)) + ) + for yi in range(len(par_names)): + ax = axes[yi, yi] + ax.set_xlim(self.engine.ExpDesign.bound_tuples[yi]) + for xi in range(yi): + ax = axes[yi, xi] + ax.set_xlim(self.engine.ExpDesign.bound_tuples[xi]) + plt.close() + + # Turn off gridlines + for ax in figPosterior.axes: + ax.grid(False) + + if self.emulator: + plotname = f'/Posterior_Dist_{Model.name}_emulator' + else: + plotname = f'/Posterior_Dist_{Model.name}' + + figPosterior.set_size_inches((24, 16)) + figPosterior.savefig(f'./{out_dir}{plotname}.pdf', + bbox_inches='tight') + + # -------- Plot MAP -------- + if self.plot_map_pred: + self._plot_max_a_posteriori() + + # -------- Plot log_BME dist -------- + if self.bootstrap: + + # Computing the TOM performance + self.log_BME_tom = stats.chi2.rvs( + self.n_tot_measurement, size=self.log_BME.shape[0] + ) + + fig, ax = plt.subplots() + sns.kdeplot(self.log_BME_tom, ax=ax, color="green", shade=True) + sns.kdeplot( + self.log_BME, ax=ax, color="blue", shade=True, + label='Model BME') + + ax.set_xlabel('log$_{10}$(BME)') + ax.set_ylabel('Probability density') + + legend_elements = [ + Patch(facecolor='green', edgecolor='green', label='TOM BME'), + Patch(facecolor='blue', edgecolor='blue', label='Model BME') + ] + ax.legend(handles=legend_elements) + + if self.emulator: + plotname = f'/BME_hist_{Model.name}_emulator' + else: + plotname = f'/BME_hist_{Model.name}' + + plt.savefig(f'./{out_dir}{plotname}.pdf', bbox_inches='tight') + plt.show() + plt.close() + + # -------- Posteior perdictives -------- + if self.plot_post_pred: + # Plot the posterior predictive + self._plot_post_predictive() + + return self + + # ------------------------------------------------------------------------- + def _perturb_data(self, data, output_names): + """ + Returns an array with n_bootstrap_itrs rowsof perturbed data. + The first row includes the original observation data. + If `self.bayes_loocv` is True, a 2d-array will be returned with + repeated rows and zero diagonal entries. + + Parameters + ---------- + data : pandas DataFrame + Observation data. + output_names : list + List of the output names. + + Returns + ------- + final_data : array + Perturbed data set. + + """ + noise_level = self.bootstrap_noise + obs_data = data[output_names].values + n_measurement, n_outs = obs_data.shape + self.n_tot_measurement = obs_data[~np.isnan(obs_data)].shape[0] + # Number of bootstrap iterations + if self.bayes_loocv: + self.n_bootstrap_itrs = self.n_tot_measurement + + # Pass loocv dataset + if self.bayes_loocv: + obs = obs_data.T[~np.isnan(obs_data.T)] + final_data = np.repeat(np.atleast_2d(obs), self.n_bootstrap_itrs, + axis=0) + np.fill_diagonal(final_data, 0) + return final_data + + else: + final_data = np.zeros( + (self.n_bootstrap_itrs, self.n_tot_measurement) + ) + final_data[0] = obs_data.T[~np.isnan(obs_data.T)] + for itrIdx in range(1, self.n_bootstrap_itrs): + data = np.zeros((n_measurement, n_outs)) + for idx in range(len(output_names)): + std = np.nanstd(obs_data[:, idx]) + if std == 0: + std = 0.001 + noise = std * noise_level + data[:, idx] = np.add( + obs_data[:, idx], + np.random.normal(0, 1, obs_data.shape[0]) * noise, + ) + + final_data[itrIdx] = data.T[~np.isnan(data.T)] + + return final_data + + # ------------------------------------------------------------------------- + def _logpdf(self, x, mean, cov): + """ + computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = spla.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(spla.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + return log_lik + + # ------------------------------------------------------------------------- + def _eval_model(self, samples=None, key='MAP'): + """ + Evaluates Forward Model. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Parameter sets. The default is None. + key : str, optional + Key string to be passed to the run_model_parallel method. + The default is 'MAP'. + + Returns + ------- + model_outputs : dict + Model outputs. + + """ + MetaModel = self.MetaModel + Model = self.engine.Model + + if samples is None: + self.samples = self.engine.ExpDesign.generate_samples( + self.n_samples, 'random') + else: + self.samples = samples + self.n_samples = len(samples) + + model_outputs, _ = Model.run_model_parallel( + self.samples, key_str=key+self.name) + + # Clean up + # Zip the subdirectories + try: + dir_name = f'{Model.name}MAP{self.name}' + key = dir_name + '_' + Model.zip_subdirs(dir_name, key) + except: + pass + + return model_outputs + + # ------------------------------------------------------------------------- + def _kernel_rbf(self, X, hyperparameters): + """ + Isotropic squared exponential kernel. + + Higher l values lead to smoother functions and therefore to coarser + approximations of the training data. Lower l values make functions + more wiggly with wide uncertainty regions between training data points. + + sigma_f controls the marginal variance of b(x) + + Parameters + ---------- + X : ndarray of shape (n_samples_X, n_features) + + hyperparameters : Dict + Lambda characteristic length + sigma_f controls the marginal variance of b(x) + sigma_0 unresolvable error nugget term, interpreted as random + error that cannot be attributed to measurement error. + Returns + ------- + var_cov_matrix : ndarray of shape (n_samples_X,n_samples_X) + Kernel k(X, X). + + """ + from sklearn.gaussian_process.kernels import RBF + min_max_scaler = preprocessing.MinMaxScaler() + X_minmax = min_max_scaler.fit_transform(X) + + nparams = len(hyperparameters) + # characteristic length (0,1] + Lambda = hyperparameters[0] + # sigma_f controls the marginal variance of b(x) + sigma2_f = hyperparameters[1] + + # cov_matrix = sigma2_f*rbf_kernel(X_minmax, gamma = 1/Lambda**2) + + rbf = RBF(length_scale=Lambda) + cov_matrix = sigma2_f * rbf(X_minmax) + if nparams > 2: + # (unresolvable error) nugget term that is interpreted as random + # error that cannot be attributed to measurement error. + sigma2_0 = hyperparameters[2:] + for i, j in np.ndindex(cov_matrix.shape): + cov_matrix[i, j] += np.sum(sigma2_0) if i == j else 0 + + return cov_matrix + + # ------------------------------------------------------------------------- + def normpdf(self, outputs, obs_data, total_sigma2s, sigma2=None, std=None): + """ + Calculates the likelihood of simulation outputs compared with + observation data. + + Parameters + ---------- + outputs : dict + A dictionary containing the simulation outputs as array of shape + (n_samples, n_measurement) for each model output. + obs_data : dict + A dictionary/dataframe containing the observation data. + total_sigma2s : dict + A dictionary with known values of the covariance diagonal entries, + a.k.a sigma^2. + sigma2 : array, optional + An array of the sigma^2 samples, when the covariance diagonal + entries are unknown and are being jointly inferred. The default is + None. + std : dict, optional + A dictionary containing the root mean squared error as array of + shape (n_samples, n_measurement) for each model output. The default + is None. + + Returns + ------- + logLik : array of shape (n_samples) + Likelihoods. + + """ + Model = self.engine.Model + logLik = 0.0 + + # Extract the requested model outputs for likelihood calulation + if self.req_outputs is None: + req_outputs = Model.Output.names + else: + req_outputs = list(self.req_outputs) + + # Loop over the outputs + for idx, out in enumerate(req_outputs): + + # (Meta)Model Output + nsamples, nout = outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Add the std of the PCE is chosen as emulator. + if self.emulator: + if std is not None: + tot_sigma2s += std[out]**2 + + # Covariance Matrix + covMatrix = np.diag(tot_sigma2s) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + + # If sigma2 is not given, use given total_sigma2s + if sigma2 is None: + logLik += stats.multivariate_normal.logpdf( + outputs[out][:, indices], data[indices], covMatrix) + continue + + # Loop over each run/sample and calculate logLikelihood + logliks = np.zeros(nsamples) + for s_idx in range(nsamples): + + # Simulation run + tot_outputs = outputs[out] + + # Covariance Matrix + covMatrix = np.diag(tot_sigma2s) + + if sigma2 is not None: + # Check the type error term + if hasattr(self, 'bias_inputs') and \ + not hasattr(self, 'error_model'): + # Infer a Bias model usig Gaussian Process Regression + bias_inputs = np.hstack( + (self.bias_inputs[out], + tot_outputs[s_idx].reshape(-1, 1))) + + params = sigma2[s_idx, idx*3:(idx+1)*3] + covMatrix = self._kernel_rbf(bias_inputs, params) + else: + # Infer equal sigma2s + try: + sigma_2 = sigma2[s_idx, idx] + except TypeError: + sigma_2 = 0.0 + + covMatrix += sigma_2 * np.eye(nout) + # covMatrix = np.diag(sigma2 * total_sigma2s) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + + # Compute loglikelihood + logliks[s_idx] = self._logpdf( + tot_outputs[s_idx, indices], data[indices], covMatrix + ) + + logLik += logliks + return logLik + + # ------------------------------------------------------------------------- + def _corr_factor_BME_old(self, Data, total_sigma2s, posterior): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + OrigModelOutput = self.engine.ExpDesign.Y + Model = self.engine.Model + + # Posterior with guassian-likelihood + postDist = stats.gaussian_kde(posterior.T) + + # Remove NaN + Data = Data[~np.isnan(Data)] + total_sigma2s = total_sigma2s[~np.isnan(total_sigma2s)] + + # Covariance Matrix + covMatrix = np.diag(total_sigma2s[:self.n_tot_measurement]) + + # Extract the requested model outputs for likelihood calulation + if self.req_outputs is None: + OutputType = Model.Output.names + else: + OutputType = list(self.req_outputs) + + # SampleSize = OrigModelOutput[OutputType[0]].shape[0] + + + # Flatten the OutputType for OrigModel + TotalOutputs = np.concatenate([OrigModelOutput[x] for x in OutputType], 1) + + NrofBayesSamples = self.n_samples + # Evaluate MetaModel on the experimental design + Samples = self.engine.ExpDesign.X + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=Samples) + + # Reset the NrofSamples to NrofBayesSamples + self.n_samples = NrofBayesSamples + + # Flatten the OutputType for MetaModel + TotalPCEOutputs = np.concatenate([OutputRS[x] for x in OutputRS], 1) + TotalPCEstdOutputRS= np.concatenate([stdOutputRS[x] for x in stdOutputRS], 1) + + logweight = 0 + for i, sample in enumerate(Samples): + # Compute likelilhood output vs RS + covMatrix = np.diag(TotalPCEstdOutputRS[i]**2) + logLik = self._logpdf(TotalOutputs[i], TotalPCEOutputs[i], covMatrix) + # Compute posterior likelihood of the collocation points + logpostLik = np.log(postDist.pdf(sample[:, None]))[0] + if logpostLik != -np.inf: + logweight += logLik + logpostLik + return logweight + + # ------------------------------------------------------------------------- + def __corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = self.engine.ExpDesign.X + model_outputs = self.engine.ExpDesign.Y + Model = self.engine.Model + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = Model.Output.names + + # Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + covMatrix = np.eye(len(y_m)) * 1/(2*np.pi) + + # Select the data points to compare + try: + indices = self.selected_indices[out] + except: + indices = list(range(nout)) + covMatrix = np.diag(covMatrix[indices, indices]) + covMatrix_data = np.diag(covMatrix_data[indices, indices]) + + # Compute likelilhood output vs data + logLik_data[i] += self._logpdf( + y_m_hat[indices], data[indices], + covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += self._logpdf( + y_m_hat[indices], y_m[indices], + covMatrix + ) + + # Weight + logLik_data -= logBME + weights = np.mean(np.exp(logLik_model+logLik_data)) + + return np.log(weights) + + # ------------------------------------------------------------------------- + def _rejection_sampling(self): + """ + Performs rejection sampling to update the prior distribution on the + input parameters. + + Returns + ------- + posterior : pandas.dataframe + Posterior samples of the input parameters. + + """ + + MetaModel = self.MetaModel + try: + sigma2_prior = self.Discrepancy.sigma2_prior + except: + sigma2_prior = None + + # Check if the discrepancy is defined as a distribution: + samples = self.samples + + if sigma2_prior is not None: + samples = np.hstack((samples, sigma2_prior)) + + # Take the first column of Likelihoods (Observation data without noise) + if self.just_analysis or self.bayes_loocv: + index = self.n_tot_measurement-1 + likelihoods = np.exp(self.log_likes[:, index], dtype=np.longdouble)#np.float128) + else: + likelihoods = np.exp(self.log_likes[:, 0], dtype=np.longdouble)#np.float128) + + n_samples = len(likelihoods) + norm_ikelihoods = likelihoods / np.max(likelihoods) + + # Normalize based on min if all Likelihoods are zero + if all(likelihoods == 0.0): + likelihoods = self.log_likes[:, 0] + norm_ikelihoods = likelihoods / np.min(likelihoods) + + # Random numbers between 0 and 1 + unif = np.random.rand(1, n_samples)[0] + + # Reject the poorly performed prior + accepted_samples = samples[norm_ikelihoods >= unif] + + # Output the Posterior + par_names = self.engine.ExpDesign.par_names + if sigma2_prior is not None: + for name in self.Discrepancy.name: + par_names.append(name) + + return pd.DataFrame(accepted_samples, columns=sigma2_prior) + + # ------------------------------------------------------------------------- + def _posterior_predictive(self): + """ + Stores the prior- and posterior predictive samples, i.e. model + evaluations using the samples, into hdf5 files. + + priorPredictive.hdf5 : Prior predictive samples. + postPredictive_wo_noise.hdf5 : Posterior predictive samples without + the additive noise. + postPredictive.hdf5 : Posterior predictive samples with the additive + noise. + + Returns + ------- + None. + + """ + + MetaModel = self.MetaModel + Model = self.engine.Model + + # Make a directory to save the prior/posterior predictive + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + os.makedirs(out_dir, exist_ok=True) + + # Read observation data and perturb it if requested + if self.measured_data is None: + self.measured_data = Model.read_observation(case=self.name) + + if not isinstance(self.measured_data, pd.DataFrame): + self.measured_data = pd.DataFrame(self.measured_data) + + # X_values + x_values = self.engine.ExpDesign.x_values + + try: + sigma2_prior = self.Discrepancy.sigma2_prior + except: + sigma2_prior = None + + # Extract posterior samples + posterior_df = self.posterior_df + + # Take care of the sigma2 + if sigma2_prior is not None: + try: + sigma2s = posterior_df[self.Discrepancy.name].values + posterior_df = posterior_df.drop( + labels=self.Discrepancy.name, axis=1 + ) + except: + sigma2s = self.sigma2s + + # Posterior predictive + if self.emulator: + if self.inference_method == 'rejection': + prior_pred = self.__mean_pce_prior_pred + if self.name.lower() != 'calib': + post_pred = self.__mean_pce_prior_pred + post_pred_std = self._std_pce_prior_pred + else: + post_pred, post_pred_std = MetaModel.eval_metamodel( + samples=posterior_df.values + ) + + else: + if self.inference_method == 'rejection': + prior_pred = self.__model_prior_pred + if self.name.lower() != 'calib': + post_pred = self.__mean_pce_prior_pred, + post_pred_std = self._std_pce_prior_pred + else: + post_pred = self._eval_model( + samples=posterior_df.values, key='PostPred' + ) + # Correct the predictions with Model discrepancy + if hasattr(self, 'error_model') and self.error_model: + y_hat, y_std = self.error_MetaModel.eval_model_error( + self.bias_inputs, post_pred + ) + post_pred, post_pred_std = y_hat, y_std + + # Add discrepancy from likelihood Sample to the current posterior runs + total_sigma2 = self.Discrepancy.total_sigma2 + post_pred_withnoise = copy.deepcopy(post_pred) + for varIdx, var in enumerate(Model.Output.names): + for i in range(len(post_pred[var])): + pred = post_pred[var][i] + + # Known sigma2s + clean_sigma2 = total_sigma2[var][~np.isnan(total_sigma2[var])] + tot_sigma2 = clean_sigma2[:len(pred)] + cov = np.diag(tot_sigma2) + + # Check the type error term + if sigma2_prior is not None: + # Inferred sigma2s + if hasattr(self, 'bias_inputs') and \ + not hasattr(self, 'error_model'): + # TODO: Infer a Bias model usig GPR + bias_inputs = np.hstack(( + self.bias_inputs[var], pred.reshape(-1, 1))) + params = sigma2s[i, varIdx*3:(varIdx+1)*3] + cov = self._kernel_rbf(bias_inputs, params) + else: + # Infer equal sigma2s + try: + sigma2 = sigma2s[i, varIdx] + except TypeError: + sigma2 = 0.0 + + # Convert biasSigma2s to a covMatrix + cov += sigma2 * np.eye(len(pred)) + + if self.emulator: + if hasattr(MetaModel, 'rmse') and \ + MetaModel.rmse is not None: + stdPCE = MetaModel.rmse[var] + else: + stdPCE = post_pred_std[var][i] + # Expected value of variance (Assump: i.i.d stds) + cov += np.diag(stdPCE**2) + + # Sample a multivariate normal distribution with mean of + # prediction and variance of cov + post_pred_withnoise[var][i] = np.random.multivariate_normal( + pred, cov, 1 + ) + + # ----- Prior Predictive ----- + if self.inference_method.lower() == 'rejection': + # Create hdf5 metadata + hdf5file = f'{out_dir}/priorPredictive.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=prior_pred[var]) + + # ----- Posterior Predictive only model evaluations ----- + # Create hdf5 metadata + hdf5file = out_dir+'/postPredictive_wo_noise.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=post_pred[var]) + + # ----- Posterior Predictive with noise ----- + # Create hdf5 metadata + hdf5file = out_dir+'/postPredictive.hdf5' + hdf5_exist = os.path.exists(hdf5file) + if hdf5_exist: + os.remove(hdf5file) + file = h5py.File(hdf5file, 'a') + + # Store x_values + if type(x_values) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(Model.Output.names): + grp_x_values.create_dataset(var, data=x_values[var]) + else: + file.create_dataset("x_values", data=x_values) + + # Store posterior predictive + grpY = file.create_group("EDY/") + for varIdx, var in enumerate(Model.Output.names): + grpY.create_dataset(var, data=post_pred_withnoise[var]) + + return + + # ------------------------------------------------------------------------- + def _plot_max_a_posteriori(self): + """ + Plots the response of the model output against that of the metamodel at + the maximum a posteriori sample (mean or mode of posterior.) + + Returns + ------- + None. + + """ + + MetaModel = self.MetaModel + Model = self.engine.Model + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + opt_sigma = self.Discrepancy.opt_sigma + + # -------- Find MAP and run MetaModel and origModel -------- + # Compute the MAP + if self.max_a_posteriori.lower() == 'mean': + if opt_sigma == "B": + Posterior_df = self.posterior_df.values + else: + Posterior_df = self.posterior_df.values[:, :-Model.n_outputs] + map_theta = Posterior_df.mean(axis=0).reshape( + (1, MetaModel.n_params)) + else: + map_theta = stats.mode(Posterior_df.values, axis=0)[0] + # Prin report + print("\nPoint estimator:\n", map_theta[0]) + + # Run the models for MAP + # MetaModel + map_metamodel_mean, map_metamodel_std = MetaModel.eval_metamodel( + samples=map_theta) + self.map_metamodel_mean = map_metamodel_mean + self.map_metamodel_std = map_metamodel_std + + # origModel + map_orig_model = self._eval_model(samples=map_theta) + self.map_orig_model = map_orig_model + + # Extract slicing index + x_values = map_orig_model['x_values'] + + # List of markers and colors + Color = ['k', 'b', 'g', 'r'] + Marker = 'x' + + # Create a PdfPages object + pdf = PdfPages(f'./{out_dir}MAP_PCE_vs_Model_{self.name}.pdf') + fig = plt.figure() + for i, key in enumerate(Model.Output.names): + + y_val = map_orig_model[key] + y_pce_val = map_metamodel_mean[key] + y_pce_val_std = map_metamodel_std[key] + + plt.plot(x_values, y_val, color=Color[i], marker=Marker, + lw=2.0, label='$Y_{MAP}^{M}$') + + plt.plot( + x_values, y_pce_val[i], color=Color[i], lw=2.0, + marker=Marker, linestyle='--', label='$Y_{MAP}^{PCE}$' + ) + # plot the confidence interval + plt.fill_between( + x_values, y_pce_val[i] - 1.96*y_pce_val_std[i], + y_pce_val[i] + 1.96*y_pce_val_std[i], + color=Color[i], alpha=0.15 + ) + + # Calculate the adjusted R_squared and RMSE + R2 = r2_score(y_pce_val.reshape(-1, 1), y_val.reshape(-1, 1)) + rmse = np.sqrt(mean_squared_error(y_pce_val, y_val)) + + plt.ylabel(key) + plt.xlabel("Time [s]") + plt.title(f'Model vs MetaModel {key}') + + ax = fig.axes[0] + leg = ax.legend(loc='best', frameon=True) + fig.canvas.draw() + p = leg.get_window_extent().inverse_transformed(ax.transAxes) + ax.text( + p.p0[1]-0.05, p.p1[1]-0.25, + f'RMSE = {rmse:.3f}\n$R^2$ = {R2:.3f}', + transform=ax.transAxes, color='black', + bbox=dict(facecolor='none', edgecolor='black', + boxstyle='round,pad=1')) + + plt.show() + + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + pdf.close() + + # ------------------------------------------------------------------------- + def _plot_post_predictive(self): + """ + Plots the posterior predictives against the observation data. + + Returns + ------- + None. + + """ + + Model = self.engine.Model + out_dir = f'Outputs_Bayes_{Model.name}_{self.name}' + # Plot the posterior predictive + for out_idx, out_name in enumerate(Model.Output.names): + fig, ax = plt.subplots() + with sns.axes_style("ticks"): + x_key = list(self.measured_data)[0] + + # --- Read prior and posterior predictive --- + if self.inference_method == 'rejection' and \ + self.name.lower() != 'valid': + # --- Prior --- + # Load posterior predictive + f = h5py.File( + f'{out_dir}/priorPredictive.hdf5', 'r+') + + try: + x_coords = np.array(f[f"x_values/{out_name}"]) + except: + x_coords = np.array(f["x_values"]) + + X_values = np.repeat(x_coords, 10000) + + prior_pred_df = {} + prior_pred_df[x_key] = X_values + prior_pred_df[out_name] = np.array( + f[f"EDY/{out_name}"])[:10000].flatten('F') + prior_pred_df = pd.DataFrame(prior_pred_df) + + tags_post = ['prior'] * len(prior_pred_df) + prior_pred_df.insert( + len(prior_pred_df.columns), "Tags", tags_post, + True) + f.close() + + # --- Posterior --- + f = h5py.File(f"{out_dir}/postPredictive.hdf5", 'r+') + + X_values = np.repeat( + x_coords, np.array(f[f"EDY/{out_name}"]).shape[0]) + + post_pred_df = {} + post_pred_df[x_key] = X_values + post_pred_df[out_name] = np.array( + f[f"EDY/{out_name}"]).flatten('F') + + post_pred_df = pd.DataFrame(post_pred_df) + + tags_post = ['posterior'] * len(post_pred_df) + post_pred_df.insert( + len(post_pred_df.columns), "Tags", tags_post, True) + f.close() + # Concatenate two dataframes based on x_values + frames = [prior_pred_df, post_pred_df] + all_pred_df = pd.concat(frames) + + # --- Plot posterior predictive --- + sns.violinplot( + x_key, y=out_name, data=all_pred_df, hue="Tags", + legend=False, ax=ax, split=True, inner=None, + color=".8") + + # --- Plot Data --- + # Find the x,y coordinates for each point + x_coords = np.arange(x_coords.shape[0]) + first_header = list(self.measured_data)[0] + obs_data = self.measured_data.round({first_header: 6}) + sns.pointplot( + x=first_header, y=out_name, color='g', markers='x', + linestyles='', capsize=16, data=obs_data, ax=ax) + + ax.errorbar( + x_coords, obs_data[out_name].values, + yerr=1.96*self.measurement_error[out_name], + ecolor='g', fmt=' ', zorder=-1) + + # Add labels to the legend + handles, labels = ax.get_legend_handles_labels() + labels.append('Data') + + data_marker = mlines.Line2D( + [], [], color='lime', marker='+', linestyle='None', + markersize=10) + handles.append(data_marker) + + # Add legend + ax.legend(handles=handles, labels=labels, loc='best', + fontsize='large', frameon=True) + + else: + # Load posterior predictive + f = h5py.File(f"{out_dir}/postPredictive.hdf5", 'r+') + + try: + x_coords = np.array(f[f"x_values/{out_name}"]) + except: + x_coords = np.array(f["x_values"]) + + mu = np.mean(np.array(f[f"EDY/{out_name}"]), axis=0) + std = np.std(np.array(f[f"EDY/{out_name}"]), axis=0) + + # --- Plot posterior predictive --- + plt.plot( + x_coords, mu, marker='o', color='b', + label='Mean Post. Predictive') + plt.fill_between( + x_coords, mu-1.96*std, mu+1.96*std, color='b', + alpha=0.15) + + # --- Plot Data --- + ax.plot( + x_coords, self.measured_data[out_name].values, + 'ko', label='data', markeredgecolor='w') + + # --- Plot ExpDesign --- + orig_ED_Y = self.engine.ExpDesign.Y[out_name] + for output in orig_ED_Y: + plt.plot( + x_coords, output, color='grey', alpha=0.15 + ) + + # Add labels for axes + plt.xlabel('Time [s]') + plt.ylabel(out_name) + + # Add labels to the legend + handles, labels = ax.get_legend_handles_labels() + + patch = Patch(color='b', alpha=0.15) + handles.insert(1, patch) + labels.insert(1, '95 $\\%$ CI') + + # Add legend + ax.legend(handles=handles, labels=labels, loc='best', + frameon=True) + + # Save figure in pdf format + if self.emulator: + plotname = f'/Post_Prior_Perd_{Model.name}_emulator' + else: + plotname = f'/Post_Prior_Perd_{Model.name}' + + fig.savefig(f'./{out_dir}{plotname}_{out_name}.pdf', + bbox_inches='tight') diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_model_comparison.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_model_comparison.py new file mode 100644 index 000000000..b946281c5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/bayes_model_comparison.py @@ -0,0 +1,658 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sat Aug 24 16:04:06 2019 + +@author: farid +""" +import numpy as np +import os +from scipy import stats +import seaborn as sns +import matplotlib.patches as patches +import matplotlib.colors as mcolors +import matplotlib.pylab as plt +from .bayes_inference import BayesInference + +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class BayesModelComparison: + """ + A class to perform Bayesian Analysis. + + + Attributes + ---------- + justifiability : bool, optional + Whether to perform the justifiability analysis. The default is + `True`. + perturbed_data : array of shape (n_bootstrap_itrs, n_obs), optional + User defined perturbed data. The default is `None`. + n_bootstarp : int + Number of bootstrap iteration. The default is `1000`. + data_noise_level : float + A noise level to perturb the data set. The default is `0.01`. + just_n_meas : int + Number of measurements considered for visualization of the + justifiability results. + + """ + + def __init__(self, justifiability=True, perturbed_data=None, + n_bootstarp=1000, data_noise_level=0.01, just_n_meas=2): + + self.justifiability = justifiability + self.perturbed_data = perturbed_data + self.n_bootstarp = n_bootstarp + self.data_noise_level = data_noise_level + self.just_n_meas = just_n_meas + + # -------------------------------------------------------------------------- + def create_model_comparison(self, model_dict, opts_dict): + """ + Starts the two-stage model comparison. + Stage I: Compare models using Bayes factors. + Stage II: Compare models via justifiability analysis. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + opts_dict : dict + A dictionary given the `BayesInference` options. + + Example: + + >>> opts_bootstrap = { + "bootstrap": True, + "n_samples": 10000, + "Discrepancy": DiscrepancyOpts, + "emulator": True, + "plot_post_pred": True + } + + Returns + ------- + output : dict + A dictionary containing the objects and the model weights for the + comparison using Bayes factors and justifiability analysis. + + """ + + # Bayes factor + bayes_dict_bf, model_weights_dict_bf = self.compare_models( + model_dict, opts_dict + ) + + output = { + 'Bayes objects BF': bayes_dict_bf, + 'Model weights BF': model_weights_dict_bf + } + + # Justifiability analysis + if self.justifiability: + bayes_dict_ja, model_weights_dict_ja = self.compare_models( + model_dict, opts_dict, justifiability=True + ) + + output['Bayes objects JA'] = bayes_dict_ja + output['Model weights JA'] = model_weights_dict_ja + + return output + + # -------------------------------------------------------------------------- + def compare_models(self, model_dict, opts_dict, justifiability=False): + """ + Passes the options to instantiates the BayesInference class for each + model and passes the options from `opts_dict`. Then, it starts the + computations. + It also creates a folder and saves the diagrams, e.g., Bayes factor + plot, confusion matrix, etc. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + opts_dict : dict + A dictionary given the `BayesInference` options. + justifiability : bool, optional + Whether to perform the justifiability analysis. The default is + `False`. + + Returns + ------- + bayes_dict : dict + A dictionary with `BayesInference` objects. + model_weights_dict : dict + A dictionary containing the model weights. + + """ + + if not isinstance(model_dict, dict): + raise Exception("To run model comparsion, you need to pass a " + "dictionary of models.") + + # Extract model names + self.model_names = [*model_dict] + + # Compute total number of the measurement points + Engine = list(model_dict.items())[0][1] + Engine.Model.read_observation() + self.n_meas = Engine.Model.n_obs + + # ----- Generate data ----- + # Find n_bootstrap + if self.perturbed_data is None: + n_bootstarp = self.n_bootstarp + else: + n_bootstarp = self.perturbed_data.shape[0] + + # Create dataset + justData = self.generate_dataset( + model_dict, justifiability, n_bootstarp=n_bootstarp) + + # Run create Interface for each model + bayes_dict = {} + for model in model_dict.keys(): + print("-"*20) + print("Bayesian inference of {}.\n".format(model)) + + BayesOpts = BayesInference(model_dict[model]) + + # Set BayesInference options + for key, value in opts_dict.items(): + if key in BayesOpts.__dict__.keys(): + if key == "Discrepancy" and isinstance(value, dict): + setattr(BayesOpts, key, value[model]) + else: + setattr(BayesOpts, key, value) + + # Pass justifiability data as perturbed data + BayesOpts.perturbed_data = justData + BayesOpts.just_analysis = justifiability + + bayes_dict[model] = BayesOpts.create_inference() + print("-"*20) + + # Compute model weights + BME_Dict = dict() + for modelName, bayesObj in bayes_dict.items(): + BME_Dict[modelName] = np.exp(bayesObj.log_BME, dtype=np.longdouble)#float128) + + # BME correction in BayesInference class + model_weights = self.cal_model_weight( + BME_Dict, justifiability, n_bootstarp=n_bootstarp) + + # Plot model weights + if justifiability: + model_names = self.model_names + model_names.insert(0, 'Observation') + + # Split the model weights and save in a dict + list_ModelWeights = np.split( + model_weights, model_weights.shape[1]/self.n_meas, axis=1) + model_weights_dict = {key: weights for key, weights in + zip(model_names, list_ModelWeights)} + + #self.plot_just_analysis(model_weights_dict) + else: + # Create box plot for model weights + self.plot_model_weights(model_weights, 'model_weights') + + # Create kde plot for bayes factors + self.plot_bayes_factor(BME_Dict, 'kde_plot') + + # Store model weights in a dict + model_weights_dict = {key: weights for key, weights in + zip(self.model_names, model_weights)} + + return bayes_dict, model_weights_dict + + # ------------------------------------------------------------------------- + def generate_dataset(self, model_dict, justifiability=False, + n_bootstarp=1): + """ + Generates the perturbed data set for the Bayes factor calculations and + the data set for the justifiability analysis. + + Parameters + ---------- + model_dict : dict + A dictionary including the metamodels. + bool, optional + Whether to perform the justifiability analysis. The default is + `False`. + n_bootstarp : int, optional + Number of bootstrap iterations. The default is `1`. + + Returns + ------- + all_just_data: array + Created data set. + + """ + # Compute some variables + all_just_data = [] + Engine = list(model_dict.items())[0][1] + out_names = Engine.Model.Output.names + + # Perturb observations for Bayes Factor + if self.perturbed_data is None: + self.perturbed_data = self.__perturb_data( + Engine.Model.observations, out_names, n_bootstarp, + noise_level=self.data_noise_level) + + # Only for Bayes Factor + if not justifiability: + return self.perturbed_data + + # Evaluate metamodel + runs = {} + for key, metaModel in model_dict.items(): + y_hat, _ = metaModel.eval_metamodel(nsamples=n_bootstarp) + runs[key] = y_hat + + # Generate data + for i in range(n_bootstarp): + y_data = self.perturbed_data[i].reshape(1, -1) + justData = np.tril(np.repeat(y_data, y_data.shape[1], axis=0)) + # Use surrogate runs for data-generating process + for key, metaModel in model_dict.items(): + model_data = np.array( + [runs[key][out][i] for out in out_names]).reshape(y_data.shape) + justData = np.vstack(( + justData, + np.tril(np.repeat(model_data, model_data.shape[1], axis=0)) + )) + # Save in a list + all_just_data.append(justData) + + # Squeeze the array + all_just_data = np.array(all_just_data).transpose(1, 0, 2).reshape( + -1, np.array(all_just_data).shape[2] + ) + + return all_just_data + + # ------------------------------------------------------------------------- + def __perturb_data(self, data, output_names, n_bootstrap, noise_level): + """ + Returns an array with n_bootstrap_itrs rowsof perturbed data. + The first row includes the original observation data. + If `self.bayes_loocv` is True, a 2d-array will be returned with + repeated rows and zero diagonal entries. + + Parameters + ---------- + data : pandas DataFrame + Observation data. + output_names : list + List of the output names. + + Returns + ------- + final_data : array + Perturbed data set. + + """ + obs_data = data[output_names].values + n_measurement, n_outs = obs_data.shape + n_tot_measurement = obs_data[~np.isnan(obs_data)].shape[0] + final_data = np.zeros( + (n_bootstrap, n_tot_measurement) + ) + final_data[0] = obs_data.T[~np.isnan(obs_data.T)] + for itrIdx in range(1, n_bootstrap): + data = np.zeros((n_measurement, n_outs)) + for idx in range(len(output_names)): + std = np.nanstd(obs_data[:, idx]) + if std == 0: + std = 0.001 + noise = std * noise_level + data[:, idx] = np.add( + obs_data[:, idx], + np.random.normal(0, 1, obs_data.shape[0]) * noise, + ) + + final_data[itrIdx] = data.T[~np.isnan(data.T)] + + return final_data + + # ------------------------------------------------------------------------- + def cal_model_weight(self, BME_Dict, justifiability=False, n_bootstarp=1): + """ + Normalize the BME (Asumption: Model Prior weights are equal for models) + + Parameters + ---------- + BME_Dict : dict + A dictionary containing the BME values. + + Returns + ------- + model_weights : array + Model weights. + + """ + # Stack the BME values for all models + all_BME = np.vstack(list(BME_Dict.values())) + + if justifiability: + # Compute expected log_BME for justifiabiliy analysis + all_BME = all_BME.reshape( + all_BME.shape[0], -1, n_bootstarp).mean(axis=2) + + # Model weights + model_weights = np.divide(all_BME, np.nansum(all_BME, axis=0)) + + return model_weights + + # ------------------------------------------------------------------------- + def plot_just_analysis(self, model_weights_dict): + """ + Visualizes the confusion matrix and the model wights for the + justifiability analysis. + + Parameters + ---------- + model_weights_dict : dict + Model weights. + + Returns + ------- + None. + + """ + + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + Color = [*mcolors.TABLEAU_COLORS] + names = [*model_weights_dict] + + model_names = [model.replace('_', '$-$') for model in self.model_names] + for name in names: + fig, ax = plt.subplots() + for i, model in enumerate(model_names[1:]): + plt.plot(list(range(1, self.n_meas+1)), + model_weights_dict[name][i], + color=Color[i], marker='o', + ms=10, linewidth=2, label=model + ) + + plt.title(f"Data generated by: {name.replace('_', '$-$')}") + plt.ylabel("Weights") + plt.xlabel("No. of measurement points") + ax.set_xticks(list(range(1, self.n_meas+1))) + plt.legend(loc="best") + fig.savefig( + f'{directory}modelWeights_{name}.svg', bbox_inches='tight' + ) + plt.close() + + # Confusion matrix for some measurement points + epsilon = 1 if self.just_n_meas != 1 else 0 + for index in range(0, self.n_meas+epsilon, self.just_n_meas): + weights = np.array( + [model_weights_dict[key][:, index] for key in model_weights_dict] + ) + g = sns.heatmap( + weights.T, annot=True, cmap='Blues', xticklabels=model_names, + yticklabels=model_names[1:], annot_kws={"size": 24} + ) + + # x axis on top + g.xaxis.tick_top() + g.xaxis.set_label_position('top') + g.set_xlabel(r"\textbf{Data generated by:}", labelpad=15) + g.set_ylabel(r"\textbf{Model weight for:}", labelpad=15) + g.figure.savefig( + f"{directory}confusionMatrix_ND_{index+1}.pdf", + bbox_inches='tight' + ) + plt.close() + + # ------------------------------------------------------------------------- + def plot_model_weights(self, model_weights, plot_name): + """ + Visualizes the model weights resulting from BMS via the observation + data. + + Parameters + ---------- + model_weights : array + Model weights. + plot_name : str + Plot name. + + Returns + ------- + None. + + """ + font_size = 40 + # mkdir for plots + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + + # Create figure + fig, ax = plt.subplots() + + # Filter data using np.isnan + mask = ~np.isnan(model_weights.T) + filtered_data = [d[m] for d, m in zip(model_weights, mask.T)] + + # Create the boxplot + bp = ax.boxplot(filtered_data, patch_artist=True, showfliers=False) + + # change outline color, fill color and linewidth of the boxes + for box in bp['boxes']: + # change outline color + box.set(color='#7570b3', linewidth=4) + # change fill color + box.set(facecolor='#1b9e77') + + # change color and linewidth of the whiskers + for whisker in bp['whiskers']: + whisker.set(color='#7570b3', linewidth=2) + + # change color and linewidth of the caps + for cap in bp['caps']: + cap.set(color='#7570b3', linewidth=2) + + # change color and linewidth of the medians + for median in bp['medians']: + median.set(color='#b2df8a', linewidth=2) + + # change the style of fliers and their fill + # for flier in bp['fliers']: + # flier.set(marker='o', color='#e7298a', alpha=0.75) + + # Custom x-axis labels + model_names = [model.replace('_', '$-$') for model in self.model_names] + ax.set_xticklabels(model_names) + + ax.set_ylabel('Weight', fontsize=font_size) + + # Title + plt.title('Posterior Model Weights') + + # Set y lim + ax.set_ylim((-0.05, 1.05)) + + # Set size of the ticks + for t in ax.get_xticklabels(): + t.set_fontsize(font_size) + for t in ax.get_yticklabels(): + t.set_fontsize(font_size) + + # Save the figure + fig.savefig( + f'./{directory}{plot_name}.pdf', bbox_inches='tight' + ) + + plt.close() + + # ------------------------------------------------------------------------- + def plot_bayes_factor(self, BME_Dict, plot_name=''): + """ + Plots the Bayes factor distibutions in a :math:`N_m \\times N_m` + matrix, where :math:`N_m` is the number of the models. + + Parameters + ---------- + BME_Dict : dict + A dictionary containing the BME values of the models. + plot_name : str, optional + Plot name. The default is ''. + + Returns + ------- + None. + + """ + + font_size = 40 + + # mkdir for plots + directory = 'Outputs_Comparison/' + os.makedirs(directory, exist_ok=True) + + Colors = ["blue", "green", "gray", "brown"] + + model_names = list(BME_Dict.keys()) + nModels = len(model_names) + + # Plots + fig, axes = plt.subplots( + nrows=nModels, ncols=nModels, sharex=True, sharey=True + ) + + for i, key_i in enumerate(model_names): + + for j, key_j in enumerate(model_names): + ax = axes[i, j] + # Set size of the ticks + for t in ax.get_xticklabels(): + t.set_fontsize(font_size) + for t in ax.get_yticklabels(): + t.set_fontsize(font_size) + + if j != i: + + # Null hypothesis: key_j is the better model + BayesFactor = np.log10( + np.divide(BME_Dict[key_i], BME_Dict[key_j]) + ) + + # sns.kdeplot(BayesFactor, ax=ax, color=Colors[i], shade=True) + # sns.histplot(BayesFactor, ax=ax, stat="probability", + # kde=True, element='step', + # color=Colors[j]) + + # taken from seaborn's source code (utils.py and + # distributions.py) + def seaborn_kde_support(data, bw, gridsize, cut, clip): + if clip is None: + clip = (-np.inf, np.inf) + support_min = max(data.min() - bw * cut, clip[0]) + support_max = min(data.max() + bw * cut, clip[1]) + return np.linspace(support_min, support_max, gridsize) + + kde_estim = stats.gaussian_kde( + BayesFactor, bw_method='scott' + ) + + # manual linearization of data + # linearized = np.linspace( + # quotient.min(), quotient.max(), num=500) + + # or better: mimic seaborn's internal stuff + bw = kde_estim.scotts_factor() * np.std(BayesFactor) + linearized = seaborn_kde_support( + BayesFactor, bw, 100, 3, None) + + # computes values of the estimated function on the + # estimated linearized inputs + Z = kde_estim.evaluate(linearized) + + # https://stackoverflow.com/questions/29661574/normalize- + # numpy-array-columns-in-python + def normalize(x): + return (x - x.min(0)) / x.ptp(0) + + # normalize so it is between 0;1 + Z2 = normalize(Z) + ax.plot(linearized, Z2, "-", color=Colors[i], linewidth=4) + ax.fill_between( + linearized, 0, Z2, color=Colors[i], alpha=0.25 + ) + + # Draw BF significant levels according to Jeffreys 1961 + # Strong evidence for both models + ax.axvline( + x=np.log10(3), ymin=0, linewidth=4, color='dimgrey' + ) + # Strong evidence for one model + ax.axvline( + x=np.log10(10), ymin=0, linewidth=4, color='orange' + ) + # Decisive evidence for one model + ax.axvline( + x=np.log10(100), ymin=0, linewidth=4, color='r' + ) + + # legend + BF_label = key_i.replace('_', '$-$') + \ + '/' + key_j.replace('_', '$-$') + legend_elements = [ + patches.Patch(facecolor=Colors[i], edgecolor=Colors[i], + label=f'BF({BF_label})') + ] + ax.legend( + loc='upper left', handles=legend_elements, + fontsize=font_size-(nModels+1)*5 + ) + + elif j == i: + # build a rectangle in axes coords + left, width = 0, 1 + bottom, height = 0, 1 + + # axes coordinates are 0,0 is bottom left and 1,1 is upper + # right + p = patches.Rectangle( + (left, bottom), width, height, color='white', + fill=True, transform=ax.transAxes, clip_on=False + ) + ax.grid(False) + ax.add_patch(p) + # ax.text(0.5*(left+right), 0.5*(bottom+top), key_i, + fsize = font_size+20 if nModels < 4 else font_size + ax.text(0.5, 0.5, key_i.replace('_', '$-$'), + horizontalalignment='center', + verticalalignment='center', + fontsize=fsize, color=Colors[i], + transform=ax.transAxes) + + # Defining custom 'ylim' values. + custom_ylim = (0, 1.05) + + # Setting the values for all axes. + plt.setp(axes, ylim=custom_ylim) + + # set labels + for i in range(nModels): + axes[-1, i].set_xlabel('log$_{10}$(BF)', fontsize=font_size) + axes[i, 0].set_ylabel('Probability', fontsize=font_size) + + # Adjust subplots + plt.subplots_adjust(wspace=0.2, hspace=0.1) + + plt.savefig( + f'./{directory}Bayes_Factor{plot_name}.pdf', bbox_inches='tight' + ) + + plt.close() diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/discrepancy.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/discrepancy.py new file mode 100644 index 000000000..ac1b400c1 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/discrepancy.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import scipy.stats as stats +from bayesvalidrox.surrogate_models.exp_designs import ExpDesigns + + +class Discrepancy: + """ + Discrepancy class for Bayesian inference method. + We define the reference or reality to be equal to what we can model and a + descripancy term \\( \\epsilon \\). We consider the followin format: + + $$\\textbf{y}_{\\text{reality}} = \\mathcal{M}(\\theta) + \\epsilon,$$ + + where \\( \\epsilon \\in R^{N_{out}} \\) represents the the effects of + measurement error and model inaccuracy. For simplicity, it can be defined + as an additive Gaussian disrepancy with zeromean and given covariance + matrix \\( \\Sigma \\): + + $$\\epsilon \\sim \\mathcal{N}(\\epsilon|0, \\Sigma). $$ + + In the context of model inversion or calibration, an observation point + \\( \\textbf{y}_i \\in \\mathcal{y} \\) is a realization of a Gaussian + distribution with mean value of \\(\\mathcal{M}(\\theta) \\) and covariance + matrix of \\( \\Sigma \\). + + $$ p(\\textbf{y}|\\theta) = \\mathcal{N}(\\textbf{y}|\\mathcal{M} + (\\theta))$$ + + The following options are available: + + * Option A: With known redidual covariance matrix \\(\\Sigma\\) for + independent measurements. + + * Option B: With unknown redidual covariance matrix \\(\\Sigma\\), + paramethrized as \\(\\Sigma(\\theta_{\\epsilon})=\\sigma^2 \\textbf{I}_ + {N_{out}}\\) with unknown residual variances \\(\\sigma^2\\). + This term will be jointly infer with the uncertain input parameters. For + the inversion, you need to define a prior marginal via `Input` class. Note + that \\(\\sigma^2\\) is only a single scalar multiplier for the diagonal + entries of the covariance matrix \\(\\Sigma\\). + + Attributes + ---------- + InputDisc : obj + Input object. When the \\(\\sigma^2\\) is expected to be inferred + jointly with the parameters (`Option B`).If multiple output groups are + defined by `Model.Output.names`, each model output needs to have. + a prior marginal using the `Input` class. The default is `''`. + disc_type : str + Type of the noise definition. `'Gaussian'` is only supported so far. + parameters : dict or pandas.DataFrame + Known residual variance \\(\\sigma^2\\), i.e. diagonal entry of the + covariance matrix of the multivariate normal likelihood in case of + `Option A`. + + """ + + def __init__(self, InputDisc='', disc_type='Gaussian', parameters=None): + self.InputDisc = InputDisc + self.disc_type = disc_type + self.parameters = parameters + + # ------------------------------------------------------------------------- + def get_sample(self, n_samples): + """ + Generate samples for the \\(\\sigma^2\\), i.e. the diagonal entries of + the variance-covariance matrix in the multivariate normal distribution. + + Parameters + ---------- + n_samples : int + Number of samples (parameter sets). + + Returns + ------- + sigma2_prior: array of shape (n_samples, n_params) + \\(\\sigma^2\\) samples. + + """ + self.n_samples = n_samples # TODO: not used again in here - needed from the outside? + + # Create and store BoundTuples + self.ExpDesign = ExpDesigns(self.InputDisc) + self.ExpDesign.sampling_method = 'random' + self.ExpDesign.generate_ED( + n_samples, max_pce_deg=1 + ) + # TODO: need to recheck the following line + # This used to simply be the return from the call above + self.sigma2_prior = self.ExpDesign.X + + # Naive approach: Fit a gaussian kernel to the provided data + self.ExpDesign.JDist = stats.gaussian_kde(self.ExpDesign.raw_data) + + # Save the names of sigmas + if len(self.InputDisc.Marginals) != 0: + self.name = [] + for Marginalidx in range(len(self.InputDisc.Marginals)): + self.name.append(self.InputDisc.Marginals[Marginalidx].name) + + return self.sigma2_prior diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/mcmc.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/mcmc.py new file mode 100644 index 000000000..fe22a152f --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayes_inference/mcmc.py @@ -0,0 +1,909 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import numpy as np +import emcee +import pandas as pd +import matplotlib.pyplot as plt +from matplotlib.backends.backend_pdf import PdfPages +import multiprocessing +import scipy.stats as st +from scipy.linalg import cholesky as chol +import warnings +import shutil +os.environ["OMP_NUM_THREADS"] = "1" + + +class MCMC: + """ + A class for bayesian inference via a Markov-Chain Monte-Carlo (MCMC) + Sampler to approximate the posterior distribution of the Bayes theorem: + $$p(\\theta|\\mathcal{y}) = \\frac{p(\\mathcal{y}|\\theta) p(\\theta)} + {p(\\mathcal{y})}.$$ + + This class make inference with emcee package [1] using an Affine Invariant + Ensemble sampler (AIES) [2]. + + [1] Foreman-Mackey, D., Hogg, D.W., Lang, D. and Goodman, J., 2013.emcee: + the MCMC hammer. Publications of the Astronomical Society of the + Pacific, 125(925), p.306. https://emcee.readthedocs.io/en/stable/ + + [2] Goodman, J. and Weare, J., 2010. Ensemble samplers with affine + invariance. Communications in applied mathematics and computational + science, 5(1), pp.65-80. + + + Attributes + ---------- + BayesOpts : obj + Bayes object. + """ + + def __init__(self, BayesOpts): + + self.BayesOpts = BayesOpts + + def run_sampler(self, observation, total_sigma2): + + BayesObj = self.BayesOpts + MetaModel = BayesObj.engine.MetaModel + Model = BayesObj.engine.Model + Discrepancy = self.BayesOpts.Discrepancy + n_cpus = Model.n_cpus + priorDist = BayesObj.engine.ExpDesign.JDist + ndim = MetaModel.n_params + self.counter = 0 + output_dir = f'Outputs_Bayes_{Model.name}_{self.BayesOpts.name}' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + self.observation = observation + self.total_sigma2 = total_sigma2 + + # Unpack mcmc parameters given to BayesObj.mcmc_params + self.initsamples = None + self.nwalkers = 100 + self.nburn = 200 + self.nsteps = 100000 + self.moves = None + self.mp = False + self.verbose = False + + # Extract initial samples + if 'init_samples' in BayesObj.mcmc_params: + self.initsamples = BayesObj.mcmc_params['init_samples'] + if isinstance(self.initsamples, pd.DataFrame): + self.initsamples = self.initsamples.values + + # Extract number of steps per walker + if 'n_steps' in BayesObj.mcmc_params: + self.nsteps = int(BayesObj.mcmc_params['n_steps']) + # Extract number of walkers (chains) + if 'n_walkers' in BayesObj.mcmc_params: + self.nwalkers = int(BayesObj.mcmc_params['n_walkers']) + # Extract moves + if 'moves' in BayesObj.mcmc_params: + self.moves = BayesObj.mcmc_params['moves'] + # Extract multiprocessing + if 'multiprocessing' in BayesObj.mcmc_params: + self.mp = BayesObj.mcmc_params['multiprocessing'] + # Extract verbose + if 'verbose' in BayesObj.mcmc_params: + self.verbose = BayesObj.mcmc_params['verbose'] + + # Set initial samples + np.random.seed(0) + if self.initsamples is None: + try: + initsamples = priorDist.sample(self.nwalkers).T + except: + # when aPCE selected - gaussian kernel distribution + inputSamples = MetaModel.ExpDesign.raw_data.T + random_indices = np.random.choice( + len(inputSamples), size=self.nwalkers, replace=False + ) + initsamples = inputSamples[random_indices] + + else: + if self.initsamples.ndim == 1: + # When MAL is given. + theta = self.initsamples + initsamples = [theta + 1e-1*np.multiply( + np.random.randn(ndim), theta) for i in + range(self.nwalkers)] + else: + # Pick samples based on a uniform dist between min and max of + # each dim + initsamples = np.zeros((self.nwalkers, ndim)) + bound_tuples = [] + for idx_dim in range(ndim): + lower = np.min(self.initsamples[:, idx_dim]) + upper = np.max(self.initsamples[:, idx_dim]) + bound_tuples.append((lower, upper)) + dist = st.uniform(loc=lower, scale=upper-lower) + initsamples[:, idx_dim] = dist.rvs(size=self.nwalkers) + + # Update lower and upper + MetaModel.ExpDesign.bound_tuples = bound_tuples + + # Check if sigma^2 needs to be inferred + if Discrepancy.opt_sigma != 'B': + sigma2_samples = Discrepancy.get_sample(self.nwalkers) + + # Update initsamples + initsamples = np.hstack((initsamples, sigma2_samples)) + + # Update ndim + ndim = initsamples.shape[1] + + # Discrepancy bound + disc_bound_tuple = Discrepancy.ExpDesign.bound_tuples + + # Update bound_tuples + BayesObj.engine.ExpDesign.bound_tuples += disc_bound_tuple + + print("\n>>>> Bayesian inference with MCMC for " + f"{self.BayesOpts.name} started. <<<<<<") + + # Set up the backend + filename = f"{output_dir}/emcee_sampler.h5" + backend = emcee.backends.HDFBackend(filename) + # Clear the backend in case the file already exists + backend.reset(self.nwalkers, ndim) + + # Define emcee sampler + # Here we'll set up the computation. emcee combines multiple "walkers", + # each of which is its own MCMC chain. The number of trace results will + # be nwalkers * nsteps. + if self.mp: + # Run in parallel + if n_cpus is None: + n_cpus = multiprocessing.cpu_count() + + with multiprocessing.Pool(n_cpus) as pool: + sampler = emcee.EnsembleSampler( + self.nwalkers, ndim, self.log_posterior, moves=self.moves, + pool=pool, backend=backend + ) + + # Check if a burn-in phase is needed! + if self.initsamples is None: + # Burn-in + print("\n Burn-in period is starting:") + pos = sampler.run_mcmc( + initsamples, self.nburn, progress=True + ) + + # Reset sampler + sampler.reset() + pos = pos.coords + else: + pos = initsamples + + # Production run + print("\n Production run is starting:") + pos, prob, state = sampler.run_mcmc( + pos, self.nsteps, progress=True + ) + + else: + # Run in series and monitor the convergence + sampler = emcee.EnsembleSampler( + self.nwalkers, ndim, self.log_posterior, moves=self.moves, + backend=backend, vectorize=True + ) + + # Check if a burn-in phase is needed! + if self.initsamples is None: + # Burn-in + print("\n Burn-in period is starting:") + pos = sampler.run_mcmc( + initsamples, self.nburn, progress=True + ) + + # Reset sampler + sampler.reset() + pos = pos.coords + else: + pos = initsamples + + # Production run + print("\n Production run is starting:") + + # Track how the average autocorrelation time estimate changes + autocorrIdx = 0 + autocorr = np.empty(self.nsteps) + tauold = np.inf + autocorreverynsteps = 50 + + # sample step by step using the generator sampler.sample + for sample in sampler.sample(pos, + iterations=self.nsteps, + tune=True, + progress=True): + + # only check convergence every autocorreverynsteps steps + if sampler.iteration % autocorreverynsteps: + continue + + # Train model discrepancy/error + if hasattr(BayesObj, 'errorModel') and BayesObj.errorModel \ + and not sampler.iteration % 3 * autocorreverynsteps: + try: + self.error_MetaModel = self.train_error_model(sampler) + except: + pass + + # Print the current mean acceptance fraction + if self.verbose: + print("\nStep: {}".format(sampler.iteration)) + acc_fr = np.mean(sampler.acceptance_fraction) + print(f"Mean acceptance fraction: {acc_fr:.3f}") + + # compute the autocorrelation time so far + # using tol=0 means that we'll always get an estimate even if + # it isn't trustworthy + tau = sampler.get_autocorr_time(tol=0) + # average over walkers + autocorr[autocorrIdx] = np.nanmean(tau) + autocorrIdx += 1 + + # output current autocorrelation estimate + if self.verbose: + print(f"Mean autocorr. time estimate: {np.nanmean(tau):.3f}") + list_gr = np.round(self.gelman_rubin(sampler.chain), 3) + print("Gelman-Rubin Test*: ", list_gr) + + # check convergence + converged = np.all(tau*autocorreverynsteps < sampler.iteration) + converged &= np.all(np.abs(tauold - tau) / tau < 0.01) + converged &= np.all(self.gelman_rubin(sampler.chain) < 1.1) + + if converged: + break + tauold = tau + + # Posterior diagnostics + try: + tau = sampler.get_autocorr_time(tol=0) + except emcee.autocorr.AutocorrError: + tau = 5 + + if all(np.isnan(tau)): + tau = 5 + + burnin = int(2*np.nanmax(tau)) + thin = int(0.5*np.nanmin(tau)) if int(0.5*np.nanmin(tau)) != 0 else 1 + finalsamples = sampler.get_chain(discard=burnin, flat=True, thin=thin) + acc_fr = np.nanmean(sampler.acceptance_fraction) + list_gr = np.round(self.gelman_rubin(sampler.chain[:, burnin:]), 3) + + # Print summary + print('\n') + print('-'*15 + 'Posterior diagnostics' + '-'*15) + print(f"Mean auto-correlation time: {np.nanmean(tau):.3f}") + print(f"Thin: {thin}") + print(f"Burn-in: {burnin}") + print(f"Flat chain shape: {finalsamples.shape}") + print(f"Mean acceptance fraction*: {acc_fr:.3f}") + print("Gelman-Rubin Test**: ", list_gr) + + print("\n* This value must lay between 0.234 and 0.5.") + print("** These values must be smaller than 1.1.") + print('-'*50) + + print(f"\n>>>> Bayesian inference with MCMC for {self.BayesOpts.name} " + "successfully completed. <<<<<<\n") + + # Extract parameter names and their prior ranges + par_names = self.BayesOpts.engine.ExpDesign.par_names + + if Discrepancy.opt_sigma != 'B': + for i in range(len(Discrepancy.InputDisc.Marginals)): + par_names.append(Discrepancy.InputDisc.Marginals[i].name) + + params_range = self.BayesOpts.engine.ExpDesign.bound_tuples + + # Plot traces + if self.verbose and self.nsteps < 10000: + pdf = PdfPages(output_dir+'/traceplots.pdf') + fig = plt.figure() + for parIdx in range(ndim): + # Set up the axes with gridspec + fig = plt.figure() + grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2) + main_ax = fig.add_subplot(grid[:-1, :3]) + y_hist = fig.add_subplot(grid[:-1, -1], xticklabels=[], + sharey=main_ax) + + for i in range(self.nwalkers): + samples = sampler.chain[i, :, parIdx] + main_ax.plot(samples, '-') + + # histogram on the attached axes + y_hist.hist(samples[burnin:], 40, histtype='stepfilled', + orientation='horizontal', color='gray') + + main_ax.set_ylim(params_range[parIdx]) + main_ax.set_title('traceplot for ' + par_names[parIdx]) + main_ax.set_xlabel('step number') + + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + pdf.close() + + # plot development of autocorrelation estimate + if not self.mp: + fig1 = plt.figure() + steps = autocorreverynsteps*np.arange(1, autocorrIdx+1) + taus = autocorr[:autocorrIdx] + plt.plot(steps, steps / autocorreverynsteps, "--k") + plt.plot(steps, taus) + plt.xlim(0, steps.max()) + plt.ylim(0, np.nanmax(taus)+0.1*(np.nanmax(taus)-np.nanmin(taus))) + plt.xlabel("number of steps") + plt.ylabel(r"mean $\hat{\tau}$") + fig1.savefig(f"{output_dir}/autocorrelation_time.pdf", + bbox_inches='tight') + + # logml_dict = self.marginal_llk_emcee(sampler, self.nburn, logp=None, + # maxiter=5000) + # print('\nThe Bridge Sampling Estimation is " + # f"{logml_dict['logml']:.5f}.') + + # # Posterior-based expectation of posterior probablity + # postExpPostLikelihoods = np.mean(sampler.get_log_prob(flat=True) + # [self.nburn*self.nwalkers:]) + + # # Posterior-based expectation of prior densities + # postExpPrior = np.mean(self.log_prior(emcee_trace.T)) + + # # Posterior-based expectation of likelihoods + # postExpLikelihoods_emcee = postExpPostLikelihoods - postExpPrior + + # # Calculate Kullback-Leibler Divergence + # KLD_emcee = postExpLikelihoods_emcee - logml_dict['logml'] + # print("Kullback-Leibler divergence: %.5f"%KLD_emcee) + + # # Information Entropy based on Entropy paper Eq. 38 + # infEntropy_emcee = logml_dict['logml'] - postExpPrior - + # postExpLikelihoods_emcee + # print("Information Entropy: %.5f" %infEntropy_emcee) + + Posterior_df = pd.DataFrame(finalsamples, columns=par_names) + + return Posterior_df + + # ------------------------------------------------------------------------- + def log_prior(self, theta): + """ + Calculates the log prior likelihood \\( p(\\theta)\\) for the given + parameter set(s) \\( \\theta \\). + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter sets, i.e. proposals of MCMC chains. + + Returns + ------- + logprior: float or array of shape n_samples + Log prior likelihood. If theta has only one row, a single value is + returned otherwise an array. + + """ + + MetaModel = self.BayesOpts.MetaModel + Discrepancy = self.BayesOpts.Discrepancy + + # Find the number of sigma2 parameters + if Discrepancy.opt_sigma != 'B': + disc_bound_tuples = Discrepancy.ExpDesign.bound_tuples + disc_marginals = Discrepancy.ExpDesign.InputObj.Marginals + disc_prior_space = Discrepancy.ExpDesign.prior_space + n_sigma2 = len(disc_bound_tuples) + else: + n_sigma2 = -len(theta) + prior_dist = self.BayesOpts.engine.ExpDesign.prior_space + params_range = self.BayesOpts.engine.ExpDesign.bound_tuples + theta = theta if theta.ndim != 1 else theta.reshape((1, -1)) + nsamples = theta.shape[0] + logprior = -np.inf*np.ones(nsamples) + + for i in range(nsamples): + # Check if the sample is within the parameters' range + if self._check_ranges(theta[i], params_range): + # Check if all dists are uniform, if yes priors are equal. + if all(MetaModel.input_obj.Marginals[i].dist_type == 'uniform' + for i in range(MetaModel.n_params)): + logprior[i] = 0.0 + else: + logprior[i] = np.log( + prior_dist.pdf(theta[i, :-n_sigma2].T) + ) + + # Check if bias term needs to be inferred + if Discrepancy.opt_sigma != 'B': + if self._check_ranges(theta[i, -n_sigma2:], + disc_bound_tuples): + if all('unif' in disc_marginals[i].dist_type for i in + range(Discrepancy.ExpDesign.ndim)): + logprior[i] = 0.0 + else: + logprior[i] += np.log( + disc_prior_space.pdf(theta[i, -n_sigma2:]) + ) + + if nsamples == 1: + return logprior[0] + else: + return logprior + + # ------------------------------------------------------------------------- + def log_likelihood(self, theta): + """ + Computes likelihood \\( p(\\mathcal{Y}|\\theta)\\) of the performance + of the (meta-)model in reproducing the observation data. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + log_like : array of shape (n_samples) + Log likelihood. + + """ + + BayesOpts = self.BayesOpts + MetaModel = BayesOpts.MetaModel + Discrepancy = self.BayesOpts.Discrepancy + + # Find the number of sigma2 parameters + if Discrepancy.opt_sigma != 'B': + disc_bound_tuples = Discrepancy.ExpDesign.bound_tuples + n_sigma2 = len(disc_bound_tuples) + else: + n_sigma2 = -len(theta) + # Check if bias term needs to be inferred + if Discrepancy.opt_sigma != 'B': + sigma2 = theta[:, -n_sigma2:] + theta = theta[:, :-n_sigma2] + else: + sigma2 = None + theta = theta if theta.ndim != 1 else theta.reshape((1, -1)) + + # Evaluate Model/MetaModel at theta + mean_pred, BayesOpts._std_pce_prior_pred = self.eval_model(theta) + + # Surrogate model's error using RMSE of test data + surrError = MetaModel.rmse if hasattr(MetaModel, 'rmse') else None + + # Likelihood + log_like = BayesOpts.normpdf( + mean_pred, self.observation, self.total_sigma2, sigma2, + std=surrError + ) + return log_like + + # ------------------------------------------------------------------------- + def log_posterior(self, theta): + """ + Computes the posterior likelihood \\(p(\\theta| \\mathcal{Y})\\) for + the given parameterset. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + log_like : array of shape (n_samples) + Log posterior likelihood. + + """ + + nsamples = 1 if theta.ndim == 1 else theta.shape[0] + + if nsamples == 1: + if self.log_prior(theta) == -np.inf: + return -np.inf + else: + # Compute log prior + log_prior = self.log_prior(theta) + # Compute log Likelihood + log_likelihood = self.log_likelihood(theta) + + return log_prior + log_likelihood + else: + # Compute log prior + log_prior = self.log_prior(theta) + + # Initialize log_likelihood + log_likelihood = -np.inf*np.ones(nsamples) + + # find the indices for -inf sets + non_inf_idx = np.where(log_prior != -np.inf)[0] + + # Compute loLikelihoods + if non_inf_idx.size != 0: + log_likelihood[non_inf_idx] = self.log_likelihood( + theta[non_inf_idx] + ) + + return log_prior + log_likelihood + + # ------------------------------------------------------------------------- + def eval_model(self, theta): + """ + Evaluates the (meta-) model at the given theta. + + Parameters + ---------- + theta : array of shape (n_samples, n_params) + Parameter set, i.e. proposals of the MCMC chains. + + Returns + ------- + mean_pred : dict + Mean model prediction. + std_pred : dict + Std of model prediction. + + """ + + BayesObj = self.BayesOpts + MetaModel = BayesObj.MetaModel + Model = BayesObj.engine.Model + + if BayesObj.emulator: + # Evaluate the MetaModel + mean_pred, std_pred = MetaModel.eval_metamodel(samples=theta) + else: + # Evaluate the origModel + mean_pred, std_pred = dict(), dict() + + model_outs, _ = Model.run_model_parallel( + theta, prevRun_No=self.counter, + key_str='_MCMC', mp=False, verbose=False) + + # Save outputs in respective dicts + for varIdx, var in enumerate(Model.Output.names): + mean_pred[var] = model_outs[var] + std_pred[var] = np.zeros((mean_pred[var].shape)) + + # Remove the folder + if Model.link_type.lower() != 'function': + shutil.rmtree(f"{Model.name}_MCMC_{self.counter+1}") + + # Add one to the counter + self.counter += 1 + + if hasattr(self, 'error_MetaModel') and BayesObj.error_model: + meanPred, stdPred = self.error_MetaModel.eval_model_error( + BayesObj.BiasInputs, mean_pred + ) + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + def train_error_model(self, sampler): + """ + Trains an error model using a Gaussian Process Regression. + + Parameters + ---------- + sampler : obj + emcee sampler. + + Returns + ------- + error_MetaModel : obj + A error model. + + """ + BayesObj = self.BayesOpts + MetaModel = BayesObj.MetaModel + + # Prepare the poster samples + try: + tau = sampler.get_autocorr_time(tol=0) + except emcee.autocorr.AutocorrError: + tau = 5 + + if all(np.isnan(tau)): + tau = 5 + + burnin = int(2*np.nanmax(tau)) + thin = int(0.5*np.nanmin(tau)) if int(0.5*np.nanmin(tau)) != 0 else 1 + finalsamples = sampler.get_chain(discard=burnin, flat=True, thin=thin) + posterior = finalsamples[:, :MetaModel.n_params] + + # Select posterior mean as MAP + map_theta = posterior.mean(axis=0).reshape((1, MetaModel.n_params)) + # MAP_theta = st.mode(Posterior_df,axis=0)[0] + + # Evaluate the (meta-)model at the MAP + y_map, y_std_map = MetaModel.eval_metamodel(samples=map_theta) + + # Train a GPR meta-model using MAP + error_MetaModel = MetaModel.create_model_error( + BayesObj.BiasInputs, y_map, name='Calib') + + return error_MetaModel + + # ------------------------------------------------------------------------- + def gelman_rubin(self, chain, return_var=False): + """ + The potential scale reduction factor (PSRF) defined by the variance + within one chain, W, with the variance between chains B. + Both variances are combined in a weighted sum to obtain an estimate of + the variance of a parameter \\( \\theta \\).The square root of the + ratio of this estimates variance to the within chain variance is called + the potential scale reduction. + For a well converged chain it should approach 1. Values greater than + 1.1 typically indicate that the chains have not yet fully converged. + + Source: http://joergdietrich.github.io/emcee-convergence.html + + https://github.com/jwalton3141/jwalton3141.github.io/blob/master/assets/posts/ESS/rwmh.py + + Parameters + ---------- + chain : array (n_walkers, n_steps, n_params) + The emcee ensamples. + + Returns + ------- + R_hat : float + The Gelman-Robin values. + + """ + m_chains, n_iters = chain.shape[:2] + + # Calculate between-chain variance + θb = np.mean(chain, axis=1) + θbb = np.mean(θb, axis=0) + B_over_n = ((θbb - θb)**2).sum(axis=0) + B_over_n /= (m_chains - 1) + + # Calculate within-chain variances + ssq = np.var(chain, axis=1, ddof=1) + W = np.mean(ssq, axis=0) + + # (over) estimate of variance + var_θ = W * (n_iters - 1) / n_iters + B_over_n + + if return_var: + return var_θ + else: + # The square root of the ratio of this estimates variance to the + # within chain variance + R_hat = np.sqrt(var_θ / W) + return R_hat + + # ------------------------------------------------------------------------- + def marginal_llk_emcee(self, sampler, nburn=None, logp=None, maxiter=1000): + """ + The Bridge Sampling Estimator of the Marginal Likelihood based on + https://gist.github.com/junpenglao/4d2669d69ddfe1d788318264cdcf0583 + + Parameters + ---------- + sampler : TYPE + MultiTrace, result of MCMC run. + nburn : int, optional + Number of burn-in step. The default is None. + logp : TYPE, optional + Model Log-probability function. The default is None. + maxiter : int, optional + Maximum number of iterations. The default is 1000. + + Returns + ------- + marg_llk : dict + Estimated Marginal log-Likelihood. + + """ + r0, tol1, tol2 = 0.5, 1e-10, 1e-4 + + if logp is None: + logp = sampler.log_prob_fn + + # Split the samples into two parts + # Use the first 50% for fiting the proposal distribution + # and the second 50% in the iterative scheme. + if nburn is None: + mtrace = sampler.chain + else: + mtrace = sampler.chain[:, nburn:, :] + + nchain, len_trace, nrofVars = mtrace.shape + + N1_ = len_trace // 2 + N1 = N1_*nchain + N2 = len_trace*nchain - N1 + + samples_4_fit = np.zeros((nrofVars, N1)) + samples_4_iter = np.zeros((nrofVars, N2)) + effective_n = np.zeros((nrofVars)) + + # matrix with already transformed samples + for var in range(nrofVars): + + # for fitting the proposal + x = mtrace[:, :N1_, var] + + samples_4_fit[var, :] = x.flatten() + # for the iterative scheme + x2 = mtrace[:, N1_:, var] + samples_4_iter[var, :] = x2.flatten() + + # effective sample size of samples_4_iter, scalar + effective_n[var] = self._my_ESS(x2) + + # median effective sample size (scalar) + neff = np.median(effective_n) + + # get mean & covariance matrix and generate samples from proposal + m = np.mean(samples_4_fit, axis=1) + V = np.cov(samples_4_fit) + L = chol(V, lower=True) + + # Draw N2 samples from the proposal distribution + gen_samples = m[:, None] + np.dot( + L, st.norm.rvs(0, 1, size=samples_4_iter.shape) + ) + + # Evaluate proposal distribution for posterior & generated samples + q12 = st.multivariate_normal.logpdf(samples_4_iter.T, m, V) + q22 = st.multivariate_normal.logpdf(gen_samples.T, m, V) + + # Evaluate unnormalized posterior for posterior & generated samples + q11 = logp(samples_4_iter.T) + q21 = logp(gen_samples.T) + + # Run iterative scheme: + tmp = self._iterative_scheme( + N1, N2, q11, q12, q21, q22, r0, neff, tol1, maxiter, 'r' + ) + if ~np.isfinite(tmp['logml']): + warnings.warn( + "Logml could not be estimated within maxiter, rerunning with " + "adjusted starting value. Estimate might be more variable than" + " usual.") + # use geometric mean as starting value + r0_2 = np.sqrt(tmp['r_vals'][-2]*tmp['r_vals'][-1]) + tmp = self._iterative_scheme( + q11, q12, q21, q22, r0_2, neff, tol2, maxiter, 'logml' + ) + + marg_llk = dict( + logml=tmp['logml'], niter=tmp['niter'], method="normal", + q11=q11, q12=q12, q21=q21, q22=q22 + ) + return marg_llk + + # ------------------------------------------------------------------------- + def _iterative_scheme(self, N1, N2, q11, q12, q21, q22, r0, neff, tol, + maxiter, criterion): + """ + Iterative scheme as proposed in Meng and Wong (1996) to estimate the + marginal likelihood + + """ + l1 = q11 - q12 + l2 = q21 - q22 + # To increase numerical stability, + # subtracting the median of l1 from l1 & l2 later + lstar = np.median(l1) + s1 = neff/(neff + N2) + s2 = N2/(neff + N2) + r = r0 + r_vals = [r] + logml = np.log(r) + lstar + criterion_val = 1 + tol + + i = 0 + while (i <= maxiter) & (criterion_val > tol): + rold = r + logmlold = logml + numi = np.exp(l2 - lstar)/(s1 * np.exp(l2 - lstar) + s2 * r) + deni = 1/(s1 * np.exp(l1 - lstar) + s2 * r) + if np.sum(~np.isfinite(numi))+np.sum(~np.isfinite(deni)) > 0: + warnings.warn( + """Infinite value in iterative scheme, returning NaN. + Try rerunning with more samples.""") + r = (N1/N2) * np.sum(numi)/np.sum(deni) + r_vals.append(r) + logml = np.log(r) + lstar + i += 1 + if criterion == 'r': + criterion_val = np.abs((r - rold)/r) + elif criterion == 'logml': + criterion_val = np.abs((logml - logmlold)/logml) + + if i >= maxiter: + return dict(logml=np.NaN, niter=i, r_vals=np.asarray(r_vals)) + else: + return dict(logml=logml, niter=i) + + # ------------------------------------------------------------------------- + def _my_ESS(self, x): + """ + Compute the effective sample size of estimand of interest. + Vectorised implementation. + https://github.com/jwalton3141/jwalton3141.github.io/blob/master/assets/posts/ESS/rwmh.py + + + Parameters + ---------- + x : array of shape (n_walkers, n_steps) + MCMC Samples. + + Returns + ------- + int + Effective sample size. + + """ + m_chains, n_iters = x.shape + + def variogram(t): + variogram = ((x[:, t:] - x[:, :(n_iters - t)])**2).sum() + variogram /= (m_chains * (n_iters - t)) + return variogram + + post_var = self.gelman_rubin(x, return_var=True) + + t = 1 + rho = np.ones(n_iters) + negative_autocorr = False + + # Iterate until the sum of consecutive estimates of autocorrelation is + # negative + while not negative_autocorr and (t < n_iters): + rho[t] = 1 - variogram(t) / (2 * post_var) + + if not t % 2: + negative_autocorr = sum(rho[t-1:t+1]) < 0 + + t += 1 + + return int(m_chains*n_iters / (1 + 2*rho[1:t].sum())) + + # ------------------------------------------------------------------------- + def _check_ranges(self, theta, ranges): + """ + This function checks if theta lies in the given ranges. + + Parameters + ---------- + theta : array + Proposed parameter set. + ranges : nested list + List of the praremeter ranges. + + Returns + ------- + c : bool + If it lies in the given range, it return True else False. + + """ + c = True + # traverse in the list1 + for i, bounds in enumerate(ranges): + x = theta[i] + # condition check + if x < bounds[0] or x > bounds[1]: + c = False + return c + return c diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/bayesvalidrox.mplstyle b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayesvalidrox.mplstyle new file mode 100644 index 000000000..1f31c01f2 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/bayesvalidrox.mplstyle @@ -0,0 +1,16 @@ +figure.titlesize : 30 +axes.titlesize : 30 +axes.labelsize : 30 +axes.linewidth : 3 +axes.grid : True +lines.linewidth : 3 +lines.markersize : 10 +xtick.labelsize : 30 +ytick.labelsize : 30 +legend.fontsize : 30 +font.family : serif +font.serif : Arial +font.size : 30 +text.usetex : True +grid.linestyle : - +figure.figsize : 24, 16 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__init__.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__init__.py new file mode 100644 index 000000000..81c982542 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .post_processing import PostProcessing + +__all__ = [ + "PostProcessing" + ] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8590a242166b2e8d40de7ee2eece71980bd1571 GIT binary patch literal 261 zcmZ8bu};G<5Vf5GRYl8y)IVUz!u<fM7!d7*A|aM6CpWel3nz|z4z!=dFJ)!o7g*rZ ziSnd-r+4q2?!tUN6O76AjZNG?NAVYm#XT1-nT#;fi$<1G3Zr(iR3>{C`Q%Honag2O z1WH8=l_hfRE{@Ajc{W^iJjd?T7%mXC_lO@No^kL<-z79{f(l;9MuPYnYF}$j@DQrL zv27w)yR_-I@aV&Pp;HZ8eX#VVy)!ZF;ol`dbgfH>x7}fw-ZjDW-mb=X>740Oscic5 E3kw-WVE_OC literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d21ad3c9193151d5353eea7e29d38f3b43e4b39 GIT binary patch literal 295 zcmZ3^%ge<81T4a;sU<-AF^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%zJUDVl7OQ8<kaHg%)Im>W}vX2Ci5-+0-$(&0jk6;_W1b3oSgXhl?<Oj z*8B={wu%WYPAw{qDay{z$jL}dERJ!>PcF?(%_}L6anCIAC{2oS%gHYfNG!>SNlL6t zEiOyU$xJEAuZTgjASOOOGcU6wK3=b&@)w6qZhlH>PO4oIC(s&@Q;Ri$#0O?ZM#c|p d42(J#7_^ZQP>fad12YphTLU`?7O?|W0{}&mQW5|F literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58a0eb24635d0b97a14d13708e616de6a0659976 GIT binary patch literal 326 zcmZ9G&q@O^5XO_;ibbs6e1|=xP{fOf2=(GYS&#)Ofsk&pH8lT7Hl_9IbNB$hg4e#q zUOo8=UUarz)Pea8Gv7DE@X_c1K|H^0g@O9sH@_o;<_a>N00a_PBZFrcBatoeEED-X zDh3}I!~%CmrHgGDTrFc%b`kpJyCUz7J<OT^D|GveajhA9MPUz&JAA%O&uJB9h&0Hh zn^2KVTK|w3Wo6)6J@HmKOB%`B6ePKsmgKs+tsYLtXLO#F7Nj<ODJl0}Q&oE^0mL-4 zQI_i<W72J0O&(eA3dzzr-^jRv%Obcn{r4<oOj*@3HujrtcwwAKT3+VxaU1{+^X%&z DlmueV literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0924d8afac04d4fe82ebe791bc55a8ae48d7c117 GIT binary patch literal 28679 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2922ed407a89b026bf4d9e031464e011a7ad4a9b GIT binary patch literal 58838 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 C=CgqS literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/__pycache__/post_processing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..312575d7655db85df423489051f494f3dce62692 GIT binary patch literal 28771 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/post_processing.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/post_processing.py new file mode 100644 index 000000000..6520a40f9 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/post_processing/post_processing.py @@ -0,0 +1,1338 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import math +import os +from itertools import combinations, cycle +import pandas as pd +import scipy.stats as stats +from sklearn.linear_model import LinearRegression +from sklearn.metrics import mean_squared_error, r2_score +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +from matplotlib.offsetbox import AnchoredText +from matplotlib.patches import Patch +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class PostProcessing: + """ + This class provides many helper functions to post-process the trained + meta-model. + + Attributes + ---------- + MetaModel : obj + MetaModel object to do postprocessing on. + name : str + Type of the anaylsis. The default is `'calib'`. If a validation is + expected to be performed change this to `'valid'`. + """ + + def __init__(self, engine, name='calib'): + self.engine = engine + self.MetaModel = engine.MetaModel + self.ExpDesign = engine.ExpDesign + self.ModelObj = engine.Model + self.name = name + + # ------------------------------------------------------------------------- + def plot_moments(self, xlabel='Time [s]', plot_type=None): + """ + Plots the moments in a pdf format in the directory + `Outputs_PostProcessing`. + + Parameters + ---------- + xlabel : str, optional + String to be displayed as x-label. The default is `'Time [s]'`. + plot_type : str, optional + Options: bar or line. The default is `None`. + + Returns + ------- + pce_means: dict + Mean of the model outputs. + pce_means: dict + Standard deviation of the model outputs. + + """ + + bar_plot = True if plot_type == 'bar' else False + meta_model_type = self.MetaModel.meta_model_type + Model = self.ModelObj + + # Read Monte-Carlo reference + self.mc_reference = Model.read_observation('mc_ref') + + # Set the x values + x_values_orig = self.engine.ExpDesign.x_values + + # Compute the moments with the PCEModel object + self.pce_means, self.pce_stds = self.compute_pce_moments() + + # Get the variables + out_names = Model.Output.names + + # Open a pdf for the plots + newpath = (f'Outputs_PostProcessing_{self.name}/') + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Plot the best fit line, set the linewidth (lw), color and + # transparency (alpha) of the line + for key in out_names: + fig, ax = plt.subplots(nrows=1, ncols=2) + + # Extract mean and std + mean_data = self.pce_means[key] + std_data = self.pce_stds[key] + + # Extract a list of x values + if type(x_values_orig) is dict: + x = x_values_orig[key] + else: + x = x_values_orig + + # Plot: bar plot or line plot + if bar_plot: + ax[0].bar(list(map(str, x)), mean_data, color='b', + width=0.25) + ax[1].bar(list(map(str, x)), std_data, color='b', + width=0.25) + ax[0].legend(labels=[meta_model_type]) + ax[1].legend(labels=[meta_model_type]) + else: + ax[0].plot(x, mean_data, lw=3, color='k', marker='x', + label=meta_model_type) + ax[1].plot(x, std_data, lw=3, color='k', marker='x', + label=meta_model_type) + + if self.mc_reference is not None: + if bar_plot: + ax[0].bar(list(map(str, x)), self.mc_reference['mean'], + color='r', width=0.25) + ax[1].bar(list(map(str, x)), self.mc_reference['std'], + color='r', width=0.25) + ax[0].legend(labels=[meta_model_type]) + ax[1].legend(labels=[meta_model_type]) + else: + ax[0].plot(x, self.mc_reference['mean'], lw=3, marker='x', + color='r', label='Ref.') + ax[1].plot(x, self.mc_reference['std'], lw=3, marker='x', + color='r', label='Ref.') + + # Label the axes and provide a title + ax[0].set_xlabel(xlabel) + ax[1].set_xlabel(xlabel) + ax[0].set_ylabel(key) + ax[1].set_ylabel(key) + + # Provide a title + ax[0].set_title('Mean of ' + key) + ax[1].set_title('Std of ' + key) + + if not bar_plot: + ax[0].legend(loc='best') + ax[1].legend(loc='best') + + plt.tight_layout() + + # save the current figure + fig.savefig( + f'./{newpath}Mean_Std_PCE_{key}.pdf', + bbox_inches='tight' + ) + + return self.pce_means, self.pce_stds + + # ------------------------------------------------------------------------- + def valid_metamodel(self, n_samples=1, samples=None, model_out_dict=None, + x_axis='Time [s]'): + """ + Evaluates and plots the meta model and the PCEModel outputs for the + given number of samples or the given samples. + + Parameters + ---------- + n_samples : int, optional + Number of samples to be evaluated. The default is 1. + samples : array of shape (n_samples, n_params), optional + Samples to be evaluated. The default is None. + model_out_dict: dict + The model runs using the samples provided. + x_axis : str, optional + Label of x axis. The default is `'Time [s]'`. + + Returns + ------- + None. + + """ + MetaModel = self.MetaModel + Model = self.ModelObj + + if samples is None: + self.n_samples = n_samples + samples = self._get_sample() + else: + self.n_samples = samples.shape[0] + + # Extract x_values + x_values = self.engine.ExpDesign.x_values + + if model_out_dict is not None: + self.model_out_dict = model_out_dict + else: + self.model_out_dict = self._eval_model(samples, key_str='valid') + self.pce_out_mean, self.pce_out_std = MetaModel.eval_metamodel(samples) + + try: + key = Model.Output.names[1] + except IndexError: + key = Model.Output.names[0] + + n_obs = self.model_out_dict[key].shape[1] + + if n_obs == 1: + self._plot_validation() + else: + self._plot_validation_multi(x_values=x_values, x_axis=x_axis) + + # ------------------------------------------------------------------------- + def check_accuracy(self, n_samples=None, samples=None, outputs=None): + """ + Checks accuracy of the metamodel by computing the root mean square + error and validation error for all outputs. + + Parameters + ---------- + n_samples : int, optional + Number of samples. The default is None. + samples : array of shape (n_samples, n_params), optional + Parameter sets to be checked. The default is None. + outputs : dict, optional + Output dictionary with model outputs for all given output types in + `Model.Output.names`. The default is None. + + Raises + ------ + Exception + When neither n_samples nor samples are provided. + + Returns + ------- + rmse: dict + Root mean squared error for each output. + valid_error : dict + Validation error for each output. + + """ + MetaModel = self.MetaModel + Model = self.ModelObj + + # Set the number of samples + if n_samples: + self.n_samples = n_samples + elif samples is not None: + self.n_samples = samples.shape[0] + else: + raise Exception("Please provide either samples or pass the number" + " of samples!") + + # Generate random samples if necessary + Samples = self._get_sample() if samples is None else samples + + # Run the original model with the generated samples + if outputs is None: + outputs = self._eval_model(Samples, key_str='validSet') + + # Run the PCE model with the generated samples + pce_outputs, _ = MetaModel.eval_metamodel(samples=Samples) + + self.rmse = {} + self.valid_error = {} + # Loop over the keys and compute RMSE error. + for key in Model.Output.names: + # Root mena square + self.rmse[key] = mean_squared_error(outputs[key], pce_outputs[key], + squared=False, + multioutput='raw_values') + # Validation error + self.valid_error[key] = (self.rmse[key]**2) / \ + np.var(outputs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(self.rmse[key], + self.valid_error[key])))) + # Save error dicts in PCEModel object + self.MetaModel.rmse = self.rmse + self.MetaModel.valid_error = self.valid_error + + return + + # ------------------------------------------------------------------------- + def plot_seq_design_diagnostics(self, ref_BME_KLD=None): + """ + Plots the Bayesian Model Evidence (BME) and Kullback-Leibler divergence + (KLD) for the sequential design. + + Parameters + ---------- + ref_BME_KLD : array, optional + Reference BME and KLD . The default is `None`. + + Returns + ------- + None. + + """ + engine = self.engine + PCEModel = self.MetaModel + n_init_samples = engine.ExpDesign.n_init_samples + n_total_samples = engine.ExpDesign.X.shape[0] + + newpath = f'Outputs_PostProcessing_{self.name}/seq_design_diagnostics/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + plotList = ['Modified LOO error', 'Validation error', 'KLD', 'BME', + 'RMSEMean', 'RMSEStd', 'Hellinger distance'] + seqList = [engine.SeqModifiedLOO, engine.seqValidError, + engine.SeqKLD, engine.SeqBME, engine.seqRMSEMean, + engine.seqRMSEStd, engine.SeqDistHellinger] + + markers = ('x', 'o', 'd', '*', '+') + colors = ('k', 'darkgreen', 'b', 'navy', 'darkred') + + # Plot the evolution of the diagnostic criteria of the + # Sequential Experimental Design. + for plotidx, plot in enumerate(plotList): + fig, ax = plt.subplots() + seq_dict = seqList[plotidx] + name_util = list(seq_dict.keys()) + + if len(name_util) == 0: + continue + + # Box plot when Replications have been detected. + if any(int(name.split("rep_", 1)[1]) > 1 for name in name_util): + # Extract the values from dict + sorted_seq_opt = {} + # Number of replications + n_reps = engine.ExpDesign.n_replication + + # Get the list of utility function names + # Handle if only one UtilityFunction is provided + if not isinstance(engine.ExpDesign.util_func, list): + util_funcs = [engine.ExpDesign.util_func] + else: + util_funcs = engine.ExpDesign.util_func + + for util in util_funcs: + sortedSeq = {} + # min number of runs available from reps + n_runs = min([seq_dict[f'{util}_rep_{i+1}'].shape[0] + for i in range(n_reps)]) + + for runIdx in range(n_runs): + values = [] + for key in seq_dict.keys(): + if util in key: + values.append(seq_dict[key][runIdx].mean()) + sortedSeq['SeqItr_'+str(runIdx)] = np.array(values) + sorted_seq_opt[util] = sortedSeq + + # BoxPlot + def draw_plot(data, labels, edge_color, fill_color, idx): + pos = labels - (idx-1) + bp = plt.boxplot(data, positions=pos, labels=labels, + patch_artist=True, sym='', widths=0.75) + elements = ['boxes', 'whiskers', 'fliers', 'means', + 'medians', 'caps'] + for element in elements: + plt.setp(bp[element], color=edge_color[idx]) + + for patch in bp['boxes']: + patch.set(facecolor=fill_color[idx]) + + if engine.ExpDesign.n_new_samples != 1: + step1 = engine.ExpDesign.n_new_samples + step2 = 1 + else: + step1 = 5 + step2 = 5 + edge_color = ['red', 'blue', 'green'] + fill_color = ['tan', 'cyan', 'lightgreen'] + plot_label = plot + # Plot for different Utility Functions + for idx, util in enumerate(util_funcs): + all_errors = np.empty((n_reps, 0)) + + for key in list(sorted_seq_opt[util].keys()): + errors = sorted_seq_opt.get(util, {}).get(key)[:, None] + all_errors = np.hstack((all_errors, errors)) + + # Special cases for BME and KLD + if plot == 'KLD' or plot == 'BME': + # BME convergence if refBME is provided + if ref_BME_KLD is not None: + if plot == 'BME': + refValue = ref_BME_KLD[0] + plot_label = r'BME/BME$^{Ref.}$' + if plot == 'KLD': + refValue = ref_BME_KLD[1] + plot_label = '$D_{KL}[p(\\theta|y_*),p(\\theta)]'\ + ' / D_{KL}^{Ref.}[p(\\theta|y_*), '\ + 'p(\\theta)]$' + + # Difference between BME/KLD and the ref. values + all_errors = np.divide(all_errors, + np.full((all_errors.shape), + refValue)) + + # Plot baseline for zero, i.e. no difference + plt.axhline(y=1.0, xmin=0, xmax=1, c='green', + ls='--', lw=2) + + # Plot each UtilFuncs + labels = np.arange(n_init_samples, n_total_samples+1, step1) + draw_plot(all_errors[:, ::step2], labels, edge_color, + fill_color, idx) + + plt.xticks(labels, labels) + # Set the major and minor locators + ax.xaxis.set_major_locator(ticker.AutoLocator()) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.xaxis.grid(True, which='major', linestyle='-') + ax.xaxis.grid(True, which='minor', linestyle='--') + + # Legend + legend_elements = [] + for idx, util in enumerate(util_funcs): + legend_elements.append(Patch(facecolor=fill_color[idx], + edgecolor=edge_color[idx], + label=util)) + plt.legend(handles=legend_elements[::-1], loc='best') + + if plot != 'BME' and plot != 'KLD': + plt.yscale('log') + plt.autoscale(True) + plt.xlabel('\\# of training samples') + plt.ylabel(plot_label) + plt.title(plot) + + # save the current figure + plot_name = plot.replace(' ', '_') + fig.savefig( + f'./{newpath}/seq_{plot_name}.pdf', + bbox_inches='tight' + ) + # Destroy the current plot + plt.clf() + # Save arrays into files + f = open(f'./{newpath}/seq_{plot_name}.txt', 'w') + f.write(str(sorted_seq_opt)) + f.close() + else: + for idx, name in enumerate(name_util): + seq_values = seq_dict[name] + if engine.ExpDesign.n_new_samples != 1: + step = engine.ExpDesign.n_new_samples + else: + step = 1 + x_idx = np.arange(n_init_samples, n_total_samples+1, step) + if n_total_samples not in x_idx: + x_idx = np.hstack((x_idx, n_total_samples)) + + if plot == 'KLD' or plot == 'BME': + # BME convergence if refBME is provided + if ref_BME_KLD is not None: + if plot == 'BME': + refValue = ref_BME_KLD[0] + plot_label = r'BME/BME$^{Ref.}$' + if plot == 'KLD': + refValue = ref_BME_KLD[1] + plot_label = '$D_{KL}[p(\\theta|y_*),p(\\theta)]'\ + ' / D_{KL}^{Ref.}[p(\\theta|y_*), '\ + 'p(\\theta)]$' + + # Difference between BME/KLD and the ref. values + values = np.divide(seq_values, + np.full((seq_values.shape), + refValue)) + + # Plot baseline for zero, i.e. no difference + plt.axhline(y=1.0, xmin=0, xmax=1, c='green', + ls='--', lw=2) + + # Set the limits + plt.ylim([1e-1, 1e1]) + + # Create the plots + plt.semilogy(x_idx, values, marker=markers[idx], + color=colors[idx], ls='--', lw=2, + label=name.split("_rep", 1)[0]) + else: + plot_label = plot + + # Create the plots + plt.plot(x_idx, seq_values, marker=markers[idx], + color=colors[idx], ls='--', lw=2, + label=name.split("_rep", 1)[0]) + + else: + plot_label = plot + seq_values = np.nan_to_num(seq_values) + + # Plot the error evolution for each output + plt.semilogy(x_idx, seq_values.mean(axis=1), + marker=markers[idx], ls='--', lw=2, + color=colors[idx], + label=name.split("_rep", 1)[0]) + + # Set the major and minor locators + ax.xaxis.set_major_locator(ticker.AutoLocator()) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.xaxis.grid(True, which='major', linestyle='-') + ax.xaxis.grid(True, which='minor', linestyle='--') + + ax.tick_params(axis='both', which='major', direction='in', + width=3, length=10) + ax.tick_params(axis='both', which='minor', direction='in', + width=2, length=8) + plt.xlabel('Number of runs') + plt.ylabel(plot_label) + plt.title(plot) + plt.legend(frameon=True) + + # save the current figure + plot_name = plot.replace(' ', '_') + fig.savefig( + f'./{newpath}/seq_{plot_name}.pdf', + bbox_inches='tight' + ) + # Destroy the current plot + plt.clf() + + # ---------------- Saving arrays into files --------------- + np.save(f'./{newpath}/seq_{plot_name}.npy', seq_values) + + return + + # ------------------------------------------------------------------------- + def sobol_indices(self, xlabel='Time [s]', plot_type=None): + """ + Provides Sobol indices as a sensitivity measure to infer the importance + of the input parameters. See Eq. 27 in [1] for more details. For the + case with Principal component analysis refer to [2]. + + [1] Global sensitivity analysis: A flexible and efficient framework + with an example from stochastic hydrogeology S. Oladyshkin, F.P. + de Barros, W. Nowak https://doi.org/10.1016/j.advwatres.2011.11.001 + + [2] Nagel, J.B., Rieckermann, J. and Sudret, B., 2020. Principal + component analysis and sparse polynomial chaos expansions for global + sensitivity analysis and model calibration: Application to urban + drainage simulation. Reliability Engineering & System Safety, 195, + p.106737. + + Parameters + ---------- + xlabel : str, optional + Label of the x-axis. The default is `'Time [s]'`. + plot_type : str, optional + Plot type. The default is `None`. This corresponds to line plot. + Bar chart can be selected by `bar`. + + Returns + ------- + sobol_cell: dict + Sobol indices. + total_sobol: dict + Total Sobol indices. + + """ + # Extract the necessary variables + PCEModel = self.MetaModel + basis_dict = PCEModel.basis_dict + coeffs_dict = PCEModel.coeffs_dict + n_params = PCEModel.n_params + max_order = np.max(PCEModel.pce_deg) + sobol_cell_b = {} + total_sobol_b = {} + cov_Z_p_q = np.zeros((n_params)) + + for b_i in range(PCEModel.n_bootstrap_itrs): + + sobol_cell_, total_sobol_ = {}, {} + + for output in self.ModelObj.Output.names: + + n_meas_points = len(coeffs_dict[f'b_{b_i+1}'][output]) + + # Initialize the (cell) array containing the (total) Sobol indices. + sobol_array = dict.fromkeys(range(1, max_order+1), []) + sobol_cell_array = dict.fromkeys(range(1, max_order+1), []) + + for i_order in range(1, max_order+1): + n_comb = math.comb(n_params, i_order) + + sobol_cell_array[i_order] = np.zeros((n_comb, n_meas_points)) + + total_sobol_array = np.zeros((n_params, n_meas_points)) + + # Initialize the cell to store the names of the variables + TotalVariance = np.zeros((n_meas_points)) + # Loop over all measurement points and calculate sobol indices + for pIdx in range(n_meas_points): + + # Extract the basis indices (alpha) and coefficients + Basis = basis_dict[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + + try: + clf_poly = PCEModel.clf_poly[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + PCECoeffs = clf_poly.coef_ + except: + PCECoeffs = coeffs_dict[f'b_{b_i+1}'][output][f'y_{pIdx+1}'] + + # Compute total variance + TotalVariance[pIdx] = np.sum(np.square(PCECoeffs[1:])) + + nzidx = np.where(PCECoeffs != 0)[0] + # Set all the Sobol indices equal to zero in the presence of a + # null output. + if len(nzidx) == 0: + # This is buggy. + for i_order in range(1, max_order+1): + sobol_cell_array[i_order][:, pIdx] = 0 + + # Otherwise compute them by summing well-chosen coefficients + else: + nz_basis = Basis[nzidx] + for i_order in range(1, max_order+1): + idx = np.where(np.sum(nz_basis > 0, axis=1) == i_order) + subbasis = nz_basis[idx] + Z = np.array(list(combinations(range(n_params), i_order))) + + for q in range(Z.shape[0]): + Zq = Z[q] + subsubbasis = subbasis[:, Zq] + subidx = np.prod(subsubbasis, axis=1) > 0 + sum_ind = nzidx[idx[0][subidx]] + if TotalVariance[pIdx] == 0.0: + sobol_cell_array[i_order][q, pIdx] = 0.0 + else: + sobol = np.sum(np.square(PCECoeffs[sum_ind])) + sobol /= TotalVariance[pIdx] + sobol_cell_array[i_order][q, pIdx] = sobol + + # Compute the TOTAL Sobol indices. + for ParIdx in range(n_params): + idx = nz_basis[:, ParIdx] > 0 + sum_ind = nzidx[idx] + + if TotalVariance[pIdx] == 0.0: + total_sobol_array[ParIdx, pIdx] = 0.0 + else: + sobol = np.sum(np.square(PCECoeffs[sum_ind])) + sobol /= TotalVariance[pIdx] + total_sobol_array[ParIdx, pIdx] = sobol + + # ----- if PCA selected: Compute covariance ----- + if PCEModel.dim_red_method.lower() == 'pca': + # Extract the basis indices (alpha) and coefficients for + # next component + if pIdx < n_meas_points-1: + nextBasis = basis_dict[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + if PCEModel.bootstrap_method != 'fast' or b_i == 0: + clf_poly = PCEModel.clf_poly[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + nextPCECoeffs = clf_poly.coef_ + else: + nextPCECoeffs = coeffs_dict[f'b_{b_i+1}'][output][f'y_{pIdx+2}'] + + # Choose the common non-zero basis + mask = (Basis[:, None] == nextBasis).all(-1).any(-1) + n_mask = (nextBasis[:, None] == Basis).all(-1).any(-1) + + # Compute the covariance in Eq 17. + for ParIdx in range(n_params): + idx = (mask) & (Basis[:, ParIdx] > 0) + n_idx = (n_mask) & (nextBasis[:, ParIdx] > 0) + try: + cov_Z_p_q[ParIdx] += np.sum(np.dot( + PCECoeffs[idx], nextPCECoeffs[n_idx]) + ) + except: + pass + + # Compute the sobol indices according to Ref. 2 + if PCEModel.dim_red_method.lower() == 'pca': + n_c_points = self.engine.ExpDesign.Y[output].shape[1] + PCA = PCEModel.pca[f'b_{b_i+1}'][output] + compPCA = PCA.components_ + nComp = compPCA.shape[0] + var_Z_p = PCA.explained_variance_ + + # Extract the sobol index of the components + for i_order in range(1, max_order+1): + n_comb = math.comb(n_params, i_order) + sobol_array[i_order] = np.zeros((n_comb, n_c_points)) + Z = np.array(list(combinations(range(n_params), i_order))) + + # Loop over parameters + for q in range(Z.shape[0]): + S_Z_i = sobol_cell_array[i_order][q] + + for tIdx in range(n_c_points): + var_Y_t = np.var( + self.engine.ExpDesign.Y[output][:, tIdx]) + if var_Y_t == 0.0: + term1, term2 = 0.0, 0.0 + else: + # Eq. 17 + term1 = 0.0 + for i in range(nComp): + a = S_Z_i[i] * var_Z_p[i] + a *= compPCA[i, tIdx]**2 + term1 += a + + # TODO: Term 2 + # term2 = 0.0 + # for i in range(nComp-1): + # term2 += cov_Z_p_q[q] * compPCA[i, tIdx] + # term2 *= compPCA[i+1, tIdx] + # term2 *= 2 + + sobol_array[i_order][q, tIdx] = term1 #+ term2 + + # Devide over total output variance Eq. 18 + sobol_array[i_order][q, tIdx] /= var_Y_t + + # Compute the TOTAL Sobol indices. + total_sobol = np.zeros((n_params, n_c_points)) + for ParIdx in range(n_params): + S_Z_i = total_sobol_array[ParIdx] + + for tIdx in range(n_c_points): + var_Y_t = np.var(self.engine.ExpDesign.Y[output][:, tIdx]) + if var_Y_t == 0.0: + term1, term2 = 0.0, 0.0 + else: + term1 = 0 + for i in range(nComp): + term1 += S_Z_i[i] * var_Z_p[i] * \ + (compPCA[i, tIdx]**2) + + # Term 2 + term2 = 0 + for i in range(nComp-1): + term2 += cov_Z_p_q[ParIdx] * compPCA[i, tIdx] \ + * compPCA[i+1, tIdx] + term2 *= 2 + + total_sobol[ParIdx, tIdx] = term1 #+ term2 + + # Devide over total output variance Eq. 18 + total_sobol[ParIdx, tIdx] /= var_Y_t + + sobol_cell_[output] = sobol_array + total_sobol_[output] = total_sobol + else: + sobol_cell_[output] = sobol_cell_array + total_sobol_[output] = total_sobol_array + + # Save for each bootsrtap iteration + sobol_cell_b[b_i] = sobol_cell_ + total_sobol_b[b_i] = total_sobol_ + + # Average total sobol indices + total_sobol_all = {} + for i in sorted(total_sobol_b): + for k, v in total_sobol_b[i].items(): + if k not in total_sobol_all: + total_sobol_all[k] = [None] * len(total_sobol_b) + total_sobol_all[k][i] = v + + self.total_sobol = {} + for output in self.ModelObj.Output.names: + self.total_sobol[output] = np.mean(total_sobol_all[output], axis=0) + + # ---------------- Plot ----------------------- + par_names = self.engine.ExpDesign.par_names + x_values_orig = self.engine.ExpDesign.x_values + + newpath = (f'Outputs_PostProcessing_{self.name}/') + if not os.path.exists(newpath): + os.makedirs(newpath) + + fig = plt.figure() + + for outIdx, output in enumerate(self.ModelObj.Output.names): + + # Extract total Sobol indices + total_sobol = self.total_sobol[output] + + # Compute quantiles + q_5 = np.quantile(total_sobol_all[output], q=0.05, axis=0) + q_97_5 = np.quantile(total_sobol_all[output], q=0.975, axis=0) + + # Extract a list of x values + if type(x_values_orig) is dict: + x = x_values_orig[output] + else: + x = x_values_orig + + if plot_type == 'bar': + ax = fig.add_axes([0, 0, 1, 1]) + dict1 = {xlabel: x} + dict2 = {param: sobolIndices for param, sobolIndices + in zip(par_names, total_sobol)} + + df = pd.DataFrame({**dict1, **dict2}) + df.plot(x=xlabel, y=par_names, kind="bar", ax=ax, rot=0, + colormap='Dark2', yerr=q_97_5-q_5) + ax.set_ylabel('Total Sobol indices, $S^T$') + + else: + for i, sobolIndices in enumerate(total_sobol): + plt.plot(x, sobolIndices, label=par_names[i], + marker='x', lw=2.5) + plt.fill_between(x, q_5[i], q_97_5[i], alpha=0.15) + + plt.ylabel('Total Sobol indices, $S^T$') + plt.xlabel(xlabel) + + plt.title(f'Sensitivity analysis of {output}') + if plot_type != 'bar': + plt.legend(loc='best', frameon=True) + + # Save indices + np.savetxt(f'./{newpath}totalsobol_' + + output.replace('/', '_') + '.csv', + total_sobol.T, delimiter=',', + header=','.join(par_names), comments='') + + # save the current figure + fig.savefig( + f'./{newpath}Sobol_indices_{output}.pdf', + bbox_inches='tight' + ) + + # Destroy the current plot + plt.clf() + + return self.total_sobol + + # ------------------------------------------------------------------------- + def check_reg_quality(self, n_samples=1000, samples=None): + """ + Checks the quality of the metamodel for single output models based on: + https://towardsdatascience.com/how-do-you-check-the-quality-of-your-regression-model-in-python-fa61759ff685 + + + Parameters + ---------- + n_samples : int, optional + Number of parameter sets to use for the check. The default is 1000. + samples : array of shape (n_samples, n_params), optional + Parameter sets to use for the check. The default is None. + + Returns + ------- + None. + + """ + MetaModel = self.MetaModel + + if samples is None: + self.n_samples = n_samples + samples = self._get_sample() + else: + self.n_samples = samples.shape[0] + + # Evaluate the original and the surrogate model + y_val = self._eval_model(samples, key_str='valid') + y_pce_val, _ = MetaModel.eval_metamodel(samples=samples) + + # Open a pdf for the plots + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Fit the data(train the model) + for key in y_pce_val.keys(): + + y_pce_val_ = y_pce_val[key] + y_val_ = y_val[key] + residuals = y_val_ - y_pce_val_ + + # ------ Residuals vs. predicting variables ------ + # Check the assumptions of linearity and independence + fig1 = plt.figure() + for i, par in enumerate(self.engine.ExpDesign.par_names): + plt.title(f"{key}: Residuals vs. {par}") + plt.scatter( + x=samples[:, i], y=residuals, color='blue', edgecolor='k') + plt.grid(True) + xmin, xmax = min(samples[:, i]), max(samples[:, i]) + plt.hlines(y=0, xmin=xmin*0.9, xmax=xmax*1.1, color='red', + lw=3, linestyle='--') + plt.xlabel(par) + plt.ylabel('Residuals') + plt.show() + + # save the current figure + fig1.savefig(f'./{newpath}/Residuals_vs_Par_{i+1}.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Fitted vs. residuals ------ + # Check the assumptions of linearity and independence + fig2 = plt.figure() + plt.title(f"{key}: Residuals vs. fitted values") + plt.scatter(x=y_pce_val_, y=residuals, color='blue', edgecolor='k') + plt.grid(True) + xmin, xmax = min(y_val_), max(y_val_) + plt.hlines(y=0, xmin=xmin*0.9, xmax=xmax*1.1, color='red', lw=3, + linestyle='--') + plt.xlabel(key) + plt.ylabel('Residuals') + plt.show() + + # save the current figure + fig2.savefig(f'./{newpath}/Fitted_vs_Residuals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Histogram of normalized residuals ------ + fig3 = plt.figure() + resid_pearson = residuals / (max(residuals)-min(residuals)) + plt.hist(resid_pearson, bins=20, edgecolor='k') + plt.ylabel('Count') + plt.xlabel('Normalized residuals') + plt.title(f"{key}: Histogram of normalized residuals") + + # Normality (Shapiro-Wilk) test of the residuals + ax = plt.gca() + _, p = stats.shapiro(residuals) + if p < 0.01: + annText = "The residuals seem to come from a Gaussian Process." + else: + annText = "The normality assumption may not hold." + at = AnchoredText(annText, prop=dict(size=30), frameon=True, + loc='upper left') + at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") + ax.add_artist(at) + + plt.show() + + # save the current figure + fig3.savefig(f'./{newpath}/Hist_NormResiduals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------ Q-Q plot of the normalized residuals ------ + plt.figure() + stats.probplot(residuals[:, 0], plot=plt) + plt.xticks() + plt.yticks() + plt.xlabel("Theoretical quantiles") + plt.ylabel("Sample quantiles") + plt.title(f"{key}: Q-Q plot of normalized residuals") + plt.grid(True) + plt.show() + + # save the current figure + plt.savefig(f'./{newpath}/QQPlot_NormResiduals.pdf', + bbox_inches='tight') + # Destroy the current plot + plt.clf() + + # ------------------------------------------------------------------------- + def eval_pce_model_3d(self): + + self.n_samples = 1000 + + PCEModel = self.MetaModel + Model = self.ModelObj + n_samples = self.n_samples + + # Create 3D-Grid + # TODO: Make it general + x = np.linspace(-5, 10, n_samples) + y = np.linspace(0, 15, n_samples) + + X, Y = np.meshgrid(x, y) + PCE_Z = np.zeros((self.n_samples, self.n_samples)) + Model_Z = np.zeros((self.n_samples, self.n_samples)) + + for idxMesh in range(self.n_samples): + sample_mesh = np.vstack((X[:, idxMesh], Y[:, idxMesh])).T + + univ_p_val = PCEModel.univ_basis_vals(sample_mesh) + + for Outkey, ValuesDict in PCEModel.coeffs_dict.items(): + + pce_out_mean = np.zeros((len(sample_mesh), len(ValuesDict))) + pce_out_std = np.zeros((len(sample_mesh), len(ValuesDict))) + model_outs = np.zeros((len(sample_mesh), len(ValuesDict))) + + for Inkey, InIdxValues in ValuesDict.items(): + idx = int(Inkey.split('_')[1]) - 1 + basis_deg_ind = PCEModel.basis_dict[Outkey][Inkey] + clf_poly = PCEModel.clf_poly[Outkey][Inkey] + + PSI_Val = PCEModel.create_psi(basis_deg_ind, univ_p_val) + + # Perdiction with error bar + y_mean, y_std = clf_poly.predict(PSI_Val, return_std=True) + + pce_out_mean[:, idx] = y_mean + pce_out_std[:, idx] = y_std + + # Model evaluation + model_out_dict, _ = Model.run_model_parallel(sample_mesh, + key_str='Valid3D') + model_outs[:, idx] = model_out_dict[Outkey].T + + PCE_Z[:, idxMesh] = y_mean + Model_Z[:, idxMesh] = model_outs[:, 0] + + # ---------------- 3D plot for PCEModel ----------------------- + fig_PCE = plt.figure() + ax = plt.axes(projection='3d') + ax.plot_surface(X, Y, PCE_Z, rstride=1, cstride=1, + cmap='viridis', edgecolor='none') + ax.set_title('PCEModel') + ax.set_xlabel('$x_1$') + ax.set_ylabel('$x_2$') + ax.set_zlabel('$f(x_1,x_2)$') + + plt.grid() + plt.show() + + # Saving the figure + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # save the figure to file + fig_PCE.savefig(f'./{newpath}/3DPlot_PCEModel.pdf', + bbox_inches='tight') + plt.close(fig_PCE) + + # ---------------- 3D plot for Model ----------------------- + fig_Model = plt.figure() + ax = plt.axes(projection='3d') + ax.plot_surface(X, Y, PCE_Z, rstride=1, cstride=1, + cmap='viridis', edgecolor='none') + ax.set_title('Model') + ax.set_xlabel('$x_1$') + ax.set_ylabel('$x_2$') + ax.set_zlabel('$f(x_1,x_2)$') + + plt.grid() + plt.show() + + # Save the figure + fig_Model.savefig(f'./{newpath}/3DPlot_Model.pdf', + bbox_inches='tight') + plt.close(fig_Model) + + return + + # ------------------------------------------------------------------------- + def compute_pce_moments(self): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moments (mean) of outpust. + pce_means: dict + The first moments (mean) of outpust. + + """ + + MetaModel = self.MetaModel + outputs = self.ModelObj.Output.names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(MetaModel.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = MetaModel.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = MetaModel.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = MetaModel.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if MetaModel.dim_red_method.lower() == 'pca': + PCA = MetaModel.pca[f'b_{b_i+1}'][output] + means[output] = PCA.inverse_transform(pce_mean) + stds[output] = np.sqrt(np.dot(pce_var, + PCA.components_**2)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + # Print a report table + print("\n>>>>> Moments of {} <<<<<".format(output)) + print("\nIndex | Mean | Std. deviation") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(pce_means[output], + pce_stds[output])))) + print('-'*40) + + return pce_means, pce_stds + + # ------------------------------------------------------------------------- + def _get_sample(self, n_samples=None): + """ + Generates random samples taken from the input parameter space. + + Returns + ------- + samples : array of shape (n_samples, n_params) + Generated samples. + + """ + if n_samples is None: + n_samples = self.n_samples + self.samples = self.ExpDesign.generate_samples( + n_samples, + sampling_method='random') + return self.samples + + # ------------------------------------------------------------------------- + def _eval_model(self, samples=None, key_str='Valid'): + """ + Evaluates Forward Model for the given number of self.samples or given + samples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate the model at. The default is None. + key_str : str, optional + Key string pass to the model. The default is 'Valid'. + + Returns + ------- + model_outs : dict + Dictionary of results. + + """ + Model = self.ModelObj + + if samples is None: + samples = self._get_sample() + self.samples = samples + else: + self.n_samples = len(samples) + + model_outs, _ = Model.run_model_parallel(samples, key_str=key_str) + + return model_outs + + # ------------------------------------------------------------------------- + def _plot_validation(self): + """ + Plots outputs for visual comparison of metamodel outputs with that of + the (full) original model. + + Returns + ------- + None. + + """ + PCEModel = self.MetaModel + + # get the samples + x_val = self.samples + y_pce_val = self.pce_out_mean + y_val = self.model_out_dict + + # Open a pdf for the plots + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + fig = plt.figure() + # Fit the data(train the model) + for key in y_pce_val.keys(): + + y_pce_val_ = y_pce_val[key] + y_val_ = y_val[key] + + regression_model = LinearRegression() + regression_model.fit(y_pce_val_, y_val_) + + # Predict + x_new = np.linspace(np.min(y_pce_val_), np.max(y_val_), 100) + y_predicted = regression_model.predict(x_new[:, np.newaxis]) + + plt.scatter(y_pce_val_, y_val_, color='gold', linewidth=2) + plt.plot(x_new, y_predicted, color='k') + + # Calculate the adjusted R_squared and RMSE + # the total number of explanatory variables in the model + # (not including the constant term) + length_list = [] + for key, value in PCEModel.coeffs_dict['b_1'][key].items(): + length_list.append(len(value)) + n_predictors = min(length_list) + n_samples = x_val.shape[0] + + R2 = r2_score(y_pce_val_, y_val_) + AdjR2 = 1 - (1 - R2) * (n_samples - 1) / \ + (n_samples - n_predictors - 1) + rmse = mean_squared_error(y_pce_val_, y_val_, squared=False) + + plt.annotate(f'RMSE = {rmse:.3f}\n Adjusted $R^2$ = {AdjR2:.3f}', + xy=(0.05, 0.85), xycoords='axes fraction') + + plt.ylabel("Original Model") + plt.xlabel("PCE Model") + plt.grid() + plt.show() + + # save the current figure + plot_name = key.replace(' ', '_') + fig.savefig(f'./{newpath}/Model_vs_PCEModel_{plot_name}.pdf', + bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + # ------------------------------------------------------------------------- + def _plot_validation_multi(self, x_values=[], x_axis="x [m]"): + """ + Plots outputs for visual comparison of metamodel outputs with that of + the (full) multioutput original model + + Parameters + ---------- + x_values : list or array, optional + List of x values. The default is []. + x_axis : str, optional + Label of the x axis. The default is "x [m]". + + Returns + ------- + None. + + """ + Model = self.ModelObj + + newpath = f'Outputs_PostProcessing_{self.name}/' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # List of markers and colors + color = cycle((['b', 'g', 'r', 'y', 'k'])) + marker = cycle(('x', 'd', '+', 'o', '*')) + + fig = plt.figure() + # Plot the model vs PCE model + for keyIdx, key in enumerate(Model.Output.names): + + y_pce_val = self.pce_out_mean[key] + y_pce_val_std = self.pce_out_std[key] + y_val = self.model_out_dict[key] + try: + x = self.model_out_dict['x_values'][key] + except (TypeError, IndexError): + x = x_values + + for idx in range(y_val.shape[0]): + Color = next(color) + Marker = next(marker) + + plt.plot(x, y_val[idx], color=Color, marker=Marker, + label='$Y_{%s}^M$'%(idx+1)) + + plt.plot(x, y_pce_val[idx], color=Color, marker=Marker, + linestyle='--', + label='$Y_{%s}^{PCE}$'%(idx+1)) + plt.fill_between(x, y_pce_val[idx]-1.96*y_pce_val_std[idx], + y_pce_val[idx]+1.96*y_pce_val_std[idx], + color=Color, alpha=0.15) + + # Calculate the RMSE + rmse = mean_squared_error(y_pce_val, y_val, squared=False) + R2 = r2_score(y_pce_val[idx].reshape(-1, 1), + y_val[idx].reshape(-1, 1)) + + plt.annotate(f'RMSE = {rmse:.3f}\n $R^2$ = {R2:.3f}', + xy=(0.85, 0.1), xycoords='axes fraction') + + plt.ylabel(key) + plt.xlabel(x_axis) + plt.legend(loc='best') + plt.grid() + + # save the current figure + plot_name = key.replace(' ', '_') + fig.savefig(f'./{newpath}/Model_vs_PCEModel_{plot_name}.pdf', + bbox_inches='tight') + + # Destroy the current plot + plt.clf() + + # Zip the subdirectories + Model.zip_subdirs(f'{Model.name}valid', f'{Model.name}valid_') diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__init__.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__init__.py new file mode 100644 index 000000000..4bd81739f --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .pylink import PyLinkForwardModel + +__all__ = [ + "PyLinkForwardModel" + ] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b7c1b3926506fb279b856f55ca6120df31b8888 GIT binary patch literal 247 zcmYk0F>V4e5Jhb-0ThKMNZf#88|DHCrHFtcL7*rNjb*UKTFkDI?G5aaa;0rk<q9+~ z3k_eIKl*yo{BgbBGb6S7LlbEKHQ`Z$!W&H(kZGnlvYf9uXIkv|TIl49rLBKXFy-~@ zvih*ae(L;DdHw0MLEju$q)FXAR7mWW>yDHPQOaNDpNQY=yn?)lu!Zknd;q_98D>fa zcz4?}H$@CEvvFQ-V2bXzR562%s!aG%Xtj4IxEFwwwy;sk(V?ol<J{>I&7^rSw8>tC HNV=CRubV&? literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ce3317406e07859bf08a42b738674e05d5c4339 GIT binary patch literal 281 zcmZ3^%ge<81T4a;sl`D0F^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%p@2%C%)D&3{G#&2q7>i!l+>IeW}uXxCi5+}g327A9GHKLJw84$Cnr9B zCBtWs4ZnPytztrpQ;UjYin8-FaxxMVi(_2!lS^|`^Gb?i+%ro&N|R#Ta`MXq5=$~- zk`gOZi^~#oGE<83D`Ft##>B^G=4F<|$LkeT{^GF7%}*)KNwq8D1ey+VT(KsQ_`uA_ g$oPScfl>VegBmgdim^(5U}oZGYhVY#B6gr^0M-CYtpET3 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bbb522855ad250ad55bca46123c0f5023076291 GIT binary patch literal 312 zcmYk0%}N6?6or$S`h(bw3*TWDDHL%dB0@zFtQ2HGN+6_7M#J1>hGbGZZhZw`!dGzX zTg=v#ui!@Sv>Pwn?{YYo!;!<`0l|6w_*8)Rs~7(#L2-#2juDC|3dGVmr9>r<be^d6 zo@9e>ie^T;qgi`vTzOsjXX(|nQW|_8aF?asZruWU8{O>*ApwMVCw>S04SwDxXFLzu z2kv!Qjk$_8uD4{?IPE2v7ulG~u|mrxdd+SoGj^3v^M{ksDPKebiY=`yHJ5b_+$?LZ z5zH36FiwKkAwm;Y<0sL7`RMpUwmPgZS@~+sw;j0<#+gQlQQda?=eAN2^hJtA!vJxZ GCcl4{ja-8O literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6ae7c14b35b60388e38fcbd3af64d04771a947c GIT binary patch literal 18654 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..196cda321394e0169190078c23aeee5b564efdfb GIT binary patch literal 35776 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 SVDoUH{A(8Tt1aRgKK@@2*W9!K literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/__pycache__/pylink.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..746c82eb52be2e437c61bd201433f9d38b8ab177 GIT binary patch literal 18646 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/pylink.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/pylink.py new file mode 100644 index 000000000..8b826c5ce --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/pylink/pylink.py @@ -0,0 +1,797 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from dataclasses import dataclass + +import os +import shutil +import h5py +import numpy as np +import time +import zipfile +import pandas as pd +import multiprocessing +from functools import partial +import tqdm + +import umbridge # TODO: add this to the imports!? +#from multiprocessing import get_context +from multiprocess import get_context + + + +def within_range(out, minout, maxout): + """ + Checks if all the values in out lie between minout and maxout + + Parameters + ---------- + out : array or list + Data to check against range + minout : int + Lower bound of the range + maxout : int + Upper bound of the range + + Returns + ------- + inside : bool + True if all values in out are in the specified range + + """ + try: + out = np.array(out) + except: + raise AttributeError('The given values should be a 1D array, but are not') + if out.ndim != 1: + raise AttributeError('The given values should be a 1D array, but are not') + + if minout > maxout: + raise ValueError('The lower and upper bounds do not form a valid range, they might be switched') + + inside = False + if (out > minout).all() and (out < maxout).all(): + inside = True + return inside + + +class PyLinkForwardModel(object): + """ + A forward model binder + + This calss serves as a code wrapper. This wrapper allows the execution of + a third-party software/solver within the scope of BayesValidRox. + + Attributes + ---------- + link_type : str + The type of the wrapper. The default is `'pylink'`. This runs the + third-party software or an executable using a shell command with given + input files. + Second option is `'function'` which assumed that model can be run using + a function written separately in a Python script. + name : str + Name of the model. + py_file : str + Python file name without `.py` extension to be run for the `'function'` + wrapper. Note that the name of the python file and that of the function + must be simillar. This function must recieve the parameters in an array + of shape `(n_samples, n_params)` and returns a dictionary with the + x_values and output arrays for given output names. + func_args : dict + Additional arguments for the python file. The default is `{}`. + shell_command : str + Shell command to be executed for the `'pylink'` wrapper. + input_file : str or list + The input file to be passed to the `'pylink'` wrapper. + input_template : str or list + A template input file to be passed to the `'pylink'` wrapper. This file + must be a copy of `input_file` with `<Xi>` place holder for the input + parameters defined using `inputs` class, with i being the number of + parameter. The file name ending should include `.tpl` before the actual + extension of the input file, for example, `params.tpl.input`. + aux_file : str or list + The list of auxiliary files needed for the `'pylink'` wrapper. + exe_path : str + Execution path if you wish to run the model for the `'pylink'` wrapper + in another directory. The default is `None`, which corresponds to the + currecnt working directory. + output_file_names : list of str + List of the name of the model output text files for the `'pylink'` + wrapper. + output_names : list of str + List of the model outputs to be used for the analysis. + output_parser : str + Name of the model parser file (without `.py` extension) that recieves + the `output_file_names` and returns a 2d-array with the first row being + the x_values, e.g. x coordinates or time and the rest of raws pass the + simulation output for each model output defined in `output_names`. Note + that again here the name of the file and that of the function must be + the same. + multi_process: bool + Whether the model runs to be executed in parallel for the `'pylink'` + wrapper. The default is `True`. + n_cpus: int + The number of cpus to be used for the parallel model execution for the + `'pylink'` wrapper. The default is `None`, which corresponds to all + available cpus. + meas_file : str + The name of the measurement text-based file. This file must contain + x_values as the first column and one column for each model output. The + default is `None`. Only needed for the Bayesian Inference. + meas_file_valid : str + The name of the measurement text-based file for the validation. The + default is `None`. Only needed for the validation with Bayesian + Inference. + mc_ref_file : str + The name of the text file for the Monte-Carlo reference (mean and + standard deviation) values. It must contain `x_values` as the first + column, `mean` as the second column and `std` as the third. It can be + used to compare the estimated moments using meta-model in the post- + processing step. This is only available for one output. + obs_dict : dict + A dictionary containing the measurement text-based file. It must + contain `x_values` as the first item and one item for each model output + . The default is `{}`. Only needed for the Bayesian Inference. + obs_dict_valid : dict + A dictionary containing the validation measurement text-based file. It + must contain `x_values` as the first item and one item for each model + output. The default is `{}`. + mc_ref_dict : dict + A dictionary containing the Monte-Carlo reference (mean and standard + deviation) values. It must contain `x_values` as the first item and + `mean` as the second item and `std` as the third. The default is `{}`. + This is only available for one output. + """ + + # Nested class + @dataclass + class OutputData(object): + parser: str = "" + names: list = None + file_names: list = None + + def __init__(self, link_type='pylink', name=None, py_file=None, + func_args={}, shell_command='', input_file=None, + input_template=None, aux_file=None, exe_path='', + output_file_names=[], output_names=[], output_parser='', + multi_process=True, n_cpus=None, meas_file=None, + meas_file_valid=None, mc_ref_file=None, obs_dict={}, + obs_dict_valid={}, mc_ref_dict={}): + self.link_type = link_type + self.name = name + self.shell_command = shell_command + self.py_file = py_file + self.func_args = func_args + self.input_file = input_file + self.input_template = input_template + self.aux_file = aux_file + self.exe_path = exe_path + self.multi_process = multi_process + self.n_cpus = n_cpus + self.Output = self.OutputData( + parser=output_parser, + names=output_names, + file_names=output_file_names, + ) + self.n_outputs = len(self.Output.names) + self.meas_file = meas_file + self.meas_file_valid = meas_file_valid + self.mc_ref_file = mc_ref_file + self.observations = obs_dict + self.observations_valid = obs_dict_valid + self.mc_reference = mc_ref_dict + + # ------------------------------------------------------------------------- + def read_observation(self, case='calib'): + """ + Reads/prepare the observation/measurement data for + calibration. + + Parameters + ---------- + case : str + The type of observation to read in. Can be either 'calib', + 'valid' or 'mc_ref' + + Returns + ------- + DataFrame + A dataframe with the calibration data. + + """ + # TOOD: check that what is read in/transformed matches the expected form of data/reference + if case.lower() == 'calib': + if isinstance(self.observations, dict) and bool(self.observations): + self.observations = pd.DataFrame.from_dict(self.observations) + elif self.meas_file is not None: + file_path = os.path.join(os.getcwd(), self.meas_file) + self.observations = pd.read_csv(file_path, delimiter=',') + elif isinstance(self.observations, pd.DataFrame): + self.observations = self.observations + else: + raise Exception("Please provide the observation data as a " + "dictionary via observations attribute or pass" + " the csv-file path to MeasurementFile " + "attribute") + # Compute the number of observation + self.n_obs = self.observations[self.Output.names].notnull().sum().values.sum() + return self.observations + + elif case.lower() == 'valid': + if isinstance(self.observations_valid, dict) and \ + bool(self.observations_valid): + self.observations_valid = pd.DataFrame.from_dict(self.observations_valid) + elif self.meas_file_valid is not None: + file_path = os.path.join(os.getcwd(), self.meas_file_valid) + self.observations_valid = pd.read_csv(file_path, delimiter=',') + elif isinstance(self.observations_valid, pd.DataFrame): + self.observations_valid = self.observations_valid + else: + raise Exception("Please provide the observation data as a " + "dictionary via observations attribute or pass" + " the csv-file path to MeasurementFile " + "attribute") + # Compute the number of observation + self.n_obs_valid = self.observations_valid[self.Output.names].notnull().sum().values.sum() + return self.observations_valid + + elif case.lower() == 'mc_ref': + if self.mc_ref_file is None and \ + isinstance(self.mc_reference, pd.DataFrame): + return self.mc_reference + elif isinstance(self.mc_reference, dict) and bool(self.mc_reference): + self.mc_reference = pd.DataFrame.from_dict(self.mc_reference) + elif self.mc_ref_file is not None: + file_path = os.path.join(os.getcwd(), self.mc_ref_file) + self.mc_reference = pd.read_csv(file_path, delimiter=',') + else: + self.mc_reference = None + return self.mc_reference + + + # ------------------------------------------------------------------------- + def read_output(self): + """ + Reads the the parser output file and returns it as an + executable function. It is required when the models returns the + simulation outputs in csv files. + + Returns + ------- + Output : func + Output parser function. + + """ + output_func_name = self.Output.parser + + output_func = getattr(__import__(output_func_name), output_func_name) + + file_names = [] + for File in self.Output.file_names: + file_names.append(os.path.join(self.exe_path, File)) + try: + output = output_func(self.name, file_names) + except TypeError: + output = output_func(file_names) + return output + + # ------------------------------------------------------------------------- + def update_input_params(self, new_input_file, param_set): + """ + Finds this pattern with <X1> in the new_input_file and replace it with + the new value from the array param_sets. + + Parameters + ---------- + new_input_file : list + List of the input files with the adapted names. + param_set : array of shape (n_params) + Parameter set. + + Returns + ------- + None. + + """ + NofPa = param_set.shape[0] + text_to_search_list = [f'<X{i+1}>' for i in range(NofPa)] + + for filename in new_input_file: + # Read in the file + with open(filename, 'r') as file: + filedata = file.read() + + # Replace the target string + for text_to_search, params in zip(text_to_search_list, param_set): + filedata = filedata.replace(text_to_search, f'{params:0.4e}') + + # Write the file out again + with open(filename, 'w') as file: + file.write(filedata) + + # ------------------------------------------------------------------------- + def run_command(self, command, output_file_names): + """ + Runs the execution command given by the user to run the given model. + It checks if the output files have been generated. If yes, the jobe is + done and it extracts and returns the requested output(s). Otherwise, + it executes the command again. + + Parameters + ---------- + command : str + The shell command to be executed. + output_file_names : list + Name of the output file names. + + Returns + ------- + simulation_outputs : array of shape (n_obs, n_outputs) + Simulation outputs. + + """ + + # Check if simulation is finished + while True: + time.sleep(3) + files = os.listdir(".") + if all(elem in files for elem in output_file_names): + break + else: + # Run command + Process = os.system(f'./../{command}') + if Process != 0: + print('\nMessage 1:') + print(f'\tIf the value of \'{Process}\' is a non-zero value' + ', then compilation problems occur \n' % Process) + os.chdir("..") + + # Read the output + simulation_outputs = self.read_output() + + return simulation_outputs + + # ------------------------------------------------------------------------- + def run_forwardmodel(self, xx): + """ + This function creates subdirectory for the current run and copies the + necessary files to this directory and renames them. Next, it executes + the given command. + + Parameters + ---------- + xx : tuple + A tuple including parameter set, simulation number and key string. + + Returns + ------- + output : array of shape (n_outputs+1, n_obs) + An array passed by the output paraser containing the x_values as + the first row and the simulations results stored in the the rest of + the array. + + """ + c_points, run_no, key_str = xx + + # Handle if only one imput file is provided + if not isinstance(self.input_template, list): + self.input_template = [self.input_template] + if not isinstance(self.input_file, list): + self.input_file = [self.input_file] + + new_input_file = [] + # Loop over the InputTemplates: + for in_temp in self.input_template: + if '/' in in_temp: + in_temp = in_temp.split('/')[-1] + new_input_file.append(in_temp.split('.tpl')[0] + key_str + + f"_{run_no+1}" + in_temp.split('.tpl')[1]) + + # Create directories + newpath = self.name + key_str + f'_{run_no+1}' + if not os.path.exists(newpath): + os.makedirs(newpath) + + # Copy the necessary files to the directories + print(self.input_template) + for in_temp in self.input_template: + # Input file(s) of the model + shutil.copy2(in_temp, newpath) + # Auxiliary file + if self.aux_file is not None: + shutil.copy2(self.aux_file, newpath) # Auxiliary file + + # Rename the Inputfile and/or auxiliary file + os.chdir(newpath) + for input_tem, input_file in zip(self.input_template, new_input_file): + if '/' in input_tem: + input_tem = input_tem.split('/')[-1] + os.rename(input_tem, input_file) + + # Update the parametrs in Input file + self.update_input_params(new_input_file, c_points) + + # Update the user defined command and the execution path + try: + new_command = self.shell_command.replace(self.input_file[0], + new_input_file[0]) + new_command = new_command.replace(self.input_file[1], + new_input_file[1]) + except: + new_command = self.shell_command.replace(self.input_file[0], + new_input_file[0]) + # Set the exe path if not provided + if not bool(self.exe_path): + self.exe_path = os.getcwd() + + # Run the model + print(new_command) + output = self.run_command(new_command, self.Output.file_names) + + return output + + # ------------------------------------------------------------------------- + def run_model_parallel(self, c_points, prevRun_No=0, key_str='', + mp=True, verbose=True): + """ + Runs model simulations. If mp is true (default), then the simulations + are started in parallel. + + Parameters + ---------- + c_points : array of shape (n_samples, n_params) + Collocation points (training set). + prevRun_No : int, optional + Previous run number, in case the sequential design is selected. + The default is `0`. + key_str : str, optional + A descriptive string for validation runs. The default is `''`. + mp : bool, optional + Multiprocessing. The default is `True`. + verbose: bool, optional + Verbosity. The default is `True`. + + Returns + ------- + all_outputs : dict + A dictionary with x values (time step or point id) and all outputs. + Each key contains an array of the shape `(n_samples, n_obs)`. + new_c_points : array + Updated collocation points (training set). If a simulation does not + executed successfully, the parameter set is removed. + + """ + + # Initilization + n_c_points = len(c_points) + all_outputs = {} + + # TODO: if umbridge, just run, no parallel from here + # If the link type is UM-Bridge, then no parallel needs to be started from here + if self.link_type.lower() == 'umbridge': + # Init model + #model = umbridge.HTTPModel('http://localhost:4242', 'forward') + self.model = umbridge.HTTPModel(self.host, 'forward') # TODO: is this always forward? + Function = self.uMBridge_model + + # Extract the function + if self.link_type.lower() == 'function': + # Prepare the function + Function = getattr(__import__(self.py_file), self.py_file) + # --------------------------------------------------------------- + # -------------- Multiprocessing with Pool Class ---------------- + # --------------------------------------------------------------- + # Start a pool with the number of CPUs + if self.n_cpus is None: + n_cpus = multiprocessing.cpu_count() + else: + n_cpus = self.n_cpus + + # Run forward model + if n_c_points == 1 or not mp: + if n_c_points== 1: + if self.link_type.lower() == 'function' or self.link_type.lower() == 'umbridge': + group_results = Function(c_points, **self.func_args) + else: + group_results = self.run_forwardmodel( + (c_points[0], prevRun_No, key_str) + ) + else: + for i in range(c_points.shape[0]): + if i == 0: + if self.link_type.lower() == 'function' or self.link_type.lower() == 'umbridge': + group_results = Function(np.array([c_points[0]]), **self.func_args) + else: + group_results = self.run_forwardmodel( + (c_points[0], prevRun_No, key_str) + ) + for key in group_results: + if key != 'x_values': + group_results[key] = [group_results[key]] + else: + if self.link_type.lower() == 'function' or self.link_type.lower() == 'umbridge': + res = Function(np.array([c_points[i]]), **self.func_args) + else: + res = self.run_forwardmodel( + (c_points[i], prevRun_No, key_str) + ) + for key in res: + if key != 'x_values': + group_results[key].append(res[key]) + + for key in group_results: + if key != 'x_values': + group_results[key]= np.array(group_results[key]) + + elif self.multi_process or mp: + with get_context('spawn').Pool(n_cpus) as p: + #with multiprocessing.Pool(n_cpus) as p: + + if self.link_type.lower() == 'function' or self.link_type.lower() == 'umbridge': + imap_var = p.imap(partial(Function, **self.func_args), + c_points[:, np.newaxis]) + else: + args = zip(c_points, + [prevRun_No+i for i in range(n_c_points)], + [key_str]*n_c_points) + imap_var = p.imap(self.run_forwardmodel, args) + + if verbose: + desc = f'Running forward model {key_str}' + group_results = list(tqdm.tqdm(imap_var, total=n_c_points, + desc=desc)) + else: + group_results = list(imap_var) + + # Check for NaN + for var_i, var in enumerate(self.Output.names): + # If results are given as one dictionary + if isinstance(group_results, dict): + Outputs = np.asarray(group_results[var]) + # If results are given as list of dictionaries + elif isinstance(group_results, list): + Outputs = np.asarray([item[var] for item in group_results], + dtype=np.float64) + NaN_idx = np.unique(np.argwhere(np.isnan(Outputs))[:, 0]) + new_c_points = np.delete(c_points, NaN_idx, axis=0) + all_outputs[var] = np.atleast_2d( + np.delete(Outputs, NaN_idx, axis=0) + ) + + # Print the collocation points whose simulations crashed + if len(NaN_idx) != 0: + print('\n') + print('*'*20) + print("\nThe following parameter sets have been removed:\n", + c_points[NaN_idx]) + print("\n") + print('*'*20) + + # Save time steps or x-values + if isinstance(group_results, dict): + all_outputs["x_values"] = group_results["x_values"] + elif any(isinstance(i, dict) for i in group_results): + all_outputs["x_values"] = group_results[0]["x_values"] + + # Store simulations in a hdf5 file + self._store_simulations( + c_points, all_outputs, NaN_idx, key_str, prevRun_No + ) + + return all_outputs, new_c_points + + def uMBridge_model(self, params): + """ + Function that calls a UMBridge model and transforms its output into the + shape expected for the surrogate. + + Parameters + ---------- + params : 2d np.array, shape (#samples, #params) + The parameter values for which the model is run. + + Returns + ------- + dict + The transformed model outputs. + + """ + # Run the model + #out = np.array(model(np.ndarray.tolist(params), {'level':0})) + out = np.array(self.model(np.ndarray.tolist(params), self.modelparams)) + + # Sort into dict + out_dict = {} + cnt = 0 + for key in self.Output.names: + # If needed resort into single-value outputs + if self.output_type == 'single-valued': + if out.shape[1]>1: # TODO: this doesn't fully seem correct?? + for i in range(out[:,key]): # TODO: this doesn't fully seem correct?? + new_key = key+str(i) + if new_key not in self.Output.names: + self.Output.names.append(new_key) + if i == 0: + self.Ouptut.names.remove(key) + out_dict[new_key] = out[:,cnt,i] # TODO: not sure about this, need to test + else: + out_dict[key] = out[:,cnt] + + + else: + out_dict[key] = out[:,cnt] + cnt += 1 + + + # TODO: how to deal with the x-values? + if self.output_type == 'single-valued': + out_dict['x_values'] = [0] + else: + out_dict['x_values'] = np.arange(0,out[:,0].shape[0],1) + + #return {'T1':out[:,0], 'T2':out[:,1], 'H1':out[:,2], 'H2':out[:,3], + # 'x_values':[0]} + return out_dict + + # ------------------------------------------------------------------------- + def _store_simulations(self, c_points, all_outputs, NaN_idx, key_str, + prevRun_No): + """ + + + Parameters + ---------- + c_points : TYPE + DESCRIPTION. + all_outputs : TYPE + DESCRIPTION. + NaN_idx : TYPE + DESCRIPTION. + key_str : TYPE + DESCRIPTION. + prevRun_No : TYPE + DESCRIPTION. + + Returns + ------- + None. + + """ + + # Create hdf5 metadata + if key_str == '': + hdf5file = f'ExpDesign_{self.name}.hdf5' + else: + hdf5file = f'ValidSet_{self.name}.hdf5' + hdf5_exist = os.path.exists(hdf5file) + file = h5py.File(hdf5file, 'a') + + # ---------- Save time steps or x-values ---------- + if not hdf5_exist: + if type(all_outputs["x_values"]) is dict: + grp_x_values = file.create_group("x_values/") + for varIdx, var in enumerate(self.Output.names): + grp_x_values.create_dataset( + var, data=all_outputs["x_values"][var] + ) + else: + file.create_dataset("x_values", data=all_outputs["x_values"]) + + # ---------- Save outputs ---------- + for varIdx, var in enumerate(self.Output.names): + if not hdf5_exist: + grpY = file.create_group("EDY/"+var) + else: + grpY = file.get("EDY/"+var) + + if prevRun_No == 0 and key_str == '': + grpY.create_dataset(f'init_{key_str}', data=all_outputs[var]) + else: + try: + oldEDY = np.array(file[f'EDY/{var}/adaptive_{key_str}']) + del file[f'EDY/{var}/adaptive_{key_str}'] + data = np.vstack((oldEDY, all_outputs[var])) + except KeyError: + data = all_outputs[var] + grpY.create_dataset('adaptive_'+key_str, data=data) + + if prevRun_No == 0 and key_str == '': + grpY.create_dataset(f"New_init_{key_str}", + data=all_outputs[var]) + else: + try: + name = f'EDY/{var}/New_adaptive_{key_str}' + oldEDY = np.array(file[name]) + del file[f'EDY/{var}/New_adaptive_{key_str}'] + data = np.vstack((oldEDY, all_outputs[var])) + except KeyError: + data = all_outputs[var] + grpY.create_dataset(f'New_adaptive_{key_str}', data=data) + + # ---------- Save CollocationPoints ---------- + new_c_points = np.delete(c_points, NaN_idx, axis=0) + grpX = file.create_group("EDX") if not hdf5_exist else file.get("EDX") + if prevRun_No == 0 and key_str == '': + grpX.create_dataset("init_"+key_str, data=c_points) + if len(NaN_idx) != 0: + grpX.create_dataset("New_init_"+key_str, data=new_c_points) + + else: + try: + name = f'EDX/adaptive_{key_str}' + oldCollocationPoints = np.array(file[name]) + del file[f'EDX/adaptive_{key_str}'] + data = np.vstack((oldCollocationPoints, new_c_points)) + except KeyError: + data = new_c_points + grpX.create_dataset('adaptive_'+key_str, data=data) + + if len(NaN_idx) != 0: + try: + name = f'EDX/New_adaptive_{key_str}' + oldCollocationPoints = np.array(file[name]) + del file[f'EDX/New_adaptive_{key_str}'] + data = np.vstack((oldCollocationPoints, new_c_points)) + except KeyError: + data = new_c_points + grpX.create_dataset('New_adaptive_'+key_str, data=data) + + # Close h5py file + file.close() + + # ------------------------------------------------------------------------- + def zip_subdirs(self, dir_name, key): + """ + Zips all the files containing the key(word). + + Parameters + ---------- + dir_name : str + Directory name. + key : str + Keyword to search for. + + Returns + ------- + None. + + """ + # setup file paths variable + dir_list = [] + file_paths = [] + + # Read all directory, subdirectories and file lists + dir_path = os.getcwd() + + for root, directories, files in os.walk(dir_path): + for directory in directories: + # Create the full filepath by using os module. + if key in directory: + folderPath = os.path.join(dir_path, directory) + dir_list.append(folderPath) + + # Loop over the identified directories to store the file paths + for direct_name in dir_list: + for root, directories, files in os.walk(direct_name): + for filename in files: + # Create the full filepath by using os module. + filePath = os.path.join(root, filename) + file_paths.append('.'+filePath.split(dir_path)[1]) + + # writing files to a zipfile + if len(file_paths) != 0: + zip_file = zipfile.ZipFile(dir_name+'.zip', 'w') + with zip_file: + # writing each file one by one + for file in file_paths: + zip_file.write(file) + + file_paths = [path for path in os.listdir('.') if key in path] + + for path in file_paths: + shutil.rmtree(path) + + print("\n") + print(f'{dir_name}.zip has been created successfully!\n') + + return diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__init__.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__init__.py new file mode 100644 index 000000000..70bfb20f5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .surrogate_models import MetaModel + +__all__ = [ + "MetaModel" + ] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c10c82287a57ba1e3b4dd428962e57cdfbc5c58 GIT binary patch literal 258 zcmZ8bL23d)5S*DcQG-Gt;14|P#r}Xu4ncEKgy2OF&FBp7;_ObCo;C4Ferd0s{DPOH z*HcJAS5s6M)xO_<5{%Z%&>nbS8u1s3#VZdDn2a#ei9)WW6h`gkTAAcSq^+xDGnI9B zZlj)iV_j%+i!`a9sS3gGb+lMC2Hl;yji{YNJd5zamv_2tpeQ5kU_~|%goDpqrZvHv z-&KVzBf%_>@6{Hj&VMa+%wVfemX6xxCirjoUj>MHnMcIY=c(?DxxaFD()>z~Og*KN G&d)E$kVM1) literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe3d14f8dfc5304350b98b23bc52ca5b2315a871 GIT binary patch literal 292 zcmZ3^%ge<81T4a;so6mKF^B^LOi;#W2_R!SLkdF*V-7<uV-zDJLkd$mV-!;gb1;J@ z%S%R}v?k*%PT$m$MBn_B)SMz_popI)^DTkm(xRgL^u&_X_*{@gF<9mndwhIiPELIM zN`}uMD}IGLTg8MHrxq2*6lLdU<YXi!7RR{cCzs}?=9Lu3xM!AllqSWv<>Z$KB$i~v zBqdg+7MCUFWTq75SHz&(5ECDtnU`4-AFo$X`HRB_Xl-dus$CH$&>oOGi#3772WCb_ g#t&=^j2agh)R7TTj8)(RGZQyk13L&7u>(~D0K~CSSO5S3 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1a3fcc2eed66172304cd27ab5fe111ca0198bf5 GIT binary patch literal 323 zcmZ9Hy-EW?5XX1#B7R`N%6GV813_#=M2L;Wi693O7M4wRE-u;KJN6?aw!VkGuV9<E zxYo*7u+h2Lhy(K*hX2g)A2}Qz5sa7jtx{M&`sQzB*j!_VQ-mUl8e-{`Qlhd2on|V3 zAjRO5qFB)Gu!JbfMuGAD-d&M*Cn0&?EMx>>dm-$UZeIv#j1X_c@8RSQU$2u3UIp-h zdssGOu98jbUoxv5cxm*rjJk2G1{sqFc00LeH&t0Zo{i4=ENP?I+{z_z*|vu3dCLL8 zY|U%!r121viD5N<68)4<j?d%<!U``d->mt6w_FJAbQEILZn}d@d?6XQ%F%KdAdd6w F`v>INVKD#z literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/adaptPlot.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2854217e56fecb2456011a91a984951fed9cbcbb GIT binary patch literal 4921 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffab8b4f67e52a3128aa8740301f958a0d72c502 GIT binary patch literal 2815 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 C4-2yZ literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92db2e7e7390700d4b6b25bcdc0db1906dee37bc GIT binary patch literal 5228 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 H>m>gNxx5;C literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/apoly_construction.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82737a42dd7351d06b703b3da838031ba95979da GIT binary patch literal 2886 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 UGiz{V6;d({`I`N<wKeJd7wkkSHUIzs literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92d0cc0e7a0a07123fdfbc2c777d1b9281a43344 GIT binary patch literal 14412 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51c4ea4a7b9eb757b303782de26abffc022df39b GIT binary patch literal 21706 zcmeHvYit}>c4k$-n@x(%SCisHD(b<9L{d-dLCKaVQPj(lEQyjew2Vfvt4KE052~su ziFCK41kR?FD6>s~lW7H<ptaCA6s!q2fD<Ty2k-`yKtB?oOX!7q3lN~qVlXhW3()Wk zHW)0hd(N$@TU~6@ay*m4{7A8Rs_NE#-*eAB_dBQRFRQ957&zj0|4RISZ!^sQ#2e#q z=@(!99b9~$5g37uFe5CSZ4q14K4NDv%pP$>og+?i?TEOd?h$v?GvbMQN4zA=8L5c+ zMttPj6{(C?jZ~3qHnMJH9i(?hs-ymq8kVs!CmF%>5hHj-yXgGb!7!h|zjln&lBX5$ z)F;+{Y=>v?uRp63DnDXI>Pd_$h_S9LMuWg!X1c4tzy#;JS#{kdaa<B*IWC<G-wDSc z#P@bMCi2p`xFANl?W#94A%<=QuLWmRpLWSh5<jD^<K^I3B+e&-<Q@`MYmdVa9!?}g z0fOxEEj)Q+aVg42!n0yXuPHgP`ps9{;Nts?NP2X{Ca@!R!3OPc2zH=O!2#4IIDxta z7u4RZHXY+<L^;gIw7TkT2*+cyw<|a}E>BO1QYga9GB*~NxD(N-uoMpQ5sswe_?W<5 z<)tv6fFv|D9G!}YQ8AVv!7>*g<49&kS)5iFXO_m1P9l*)28&>uZ19hR@)htAG%U#` znIK$gN74>=M$?(31MV<BIg(Deqr;iB!5tlVfw{~)X3uv!RaYz+PKc6P1^pZh$KWy~ zP9;=VC_Xh4yr#NuiPC6X7FBy99_e<e4q1$hN!3t*RENZmqy|YX5E(0uea3OW`h(;B z*RRN;Bwv?q#3v#XJTG4#jEAPNQ{?L>!--SVqt{2V>u<qm3R3*eb@2|5-6mh3j*d!U zVO$I*<mnh64JW1(ap>X5ium%hB*n-1gcyt>gUQ<CV1)2o-_(ri2||;gUBTIQqvKZ& za-R_e8zCd}++~Vwo70Z_zGB<9w4>l@rng%lw6fU7!O4?`zpo%R6QW%VH`snMSOQ#p zpGnZ6VVFsJop8cK{ea=L&4R4>7@mGYV<eeLn(GZRXx8TfdxH!!45Do|L3jrH{5Z}o znG3~ZFlyssEF>b|@sV-pyu?J5o0h||aV|8$$HqmO3&*&q$j30sR9uFE562~%l@OK_ zQh0P4nHpo<7Q^Ec37I~Zu>8jk)fStAi8&or?fj@rSmLo=s)uK)Ejq2bqSL{6M3AvD zP(P^wAJhi5xm{At+3jl&Pg&&kkO`UPcbQ*SF#g*6x4sw3ZpvPL&^;HMkL89RU3(tr zRjT_6)qP9t&#U+3J$s}^NMji&90D>>e*>Lv9Vnb(=3qTxKZd4$LT6QqEge2{n3C+I zIlF9FN9}-cI^0j}EAoQbJ4xrdwBM4m+sr|5JaMi_=~yGKZI!rAXpv(Ux*!G2mUJS! zrEIb9SaR@~rG1NbIFhzWuaSdb)0k7T39i`IHA=C4i&C&1Hjr`7q<zeZqWf1>+;Na5 zAY(XzPw<af)q!H`3!F!A;}jAzAi4>s!Xy4pSpK<D$?ggXJ6IE4EpVke;xSQHo$>?^ zX}a+l$~M)_!(8IWMb$YgN^x0r#DsA4u}kA|_L|DhsLpFaIU%U7YeAe(s%wUvOJt$O z_m#mAscaDII=l62INprb4pop9Aa|Lc`8Q;5E;^q0^8USwe{aFRH_iUcUpw#4vJ37U zyHK$>@Z_ZV%vtnR7kq8YjNAJT`?8^Nek8{(*5n(uD-GKV4cpU0tA!OSt1?&bT}TfU z8v@zD+(>#LJ@7L~do9Z^jOX};$)%c48}khZm4<_bhJ)#$VoU47zTCw>Ka@R`xs<u| zqhn7_EnWQd-KQ5n9r^s`PjBaYE+{=03OyGfX0<<4lNrhm<xb?QyYrrIZA#K<1x=)~ z^Y7pW7CI&e=kg=TT4iAh*7(v1JL?1Xwp-Ya%2G=xovviU(@AQbXo77Prbg*BorRdf z%8BfNh1f9*l}$NuijCWVJstc3D40sj<9sAE9f8G4<}|sBio-2b9CSH7C5b{flnCDv zIg9i~r9<RH6NJY#Edqu8R2)`o6wQ!hf|JEWU)T9~Lgc<#Hd^YiZ02{8pO#Sz>fsU- zq9j78A{S0@5M??RzBw&MW;j8FxfX@hRp3Tv${W#*)mnMb_Ln}Of$#7VAH`hFm8F*+ zG}fJdj_8HGk?;+&q{*QDab2+>Ha#e7N<$A93yz6=Vj48iZkiNJy)2S`G9D5w?)F3& zdNdT5Aof%o<}@sf+NBHwBu~VrBhX0No1#!bv%Dli8L_eo)93vWSUbtU+>Udx>FCsq zR(qLy50*n5o*o=`a`iq<MK7?%dOWVbG(BdyYQwFq#q`>7&RE@7XDmyJMjFm!2n;gn z`Ri4LsK>A2a=ikyQo5vGKJo?12&oeY=<2mWK@5duP)dSh(=nJV@tEoy6%%|=LLn}- z0#WTkJfV6(VYwxS<e+xNN916)CbgwK7|E^ov08!RI2enELCN(IJyO5%7>zHN<oX;7 z;ynEtNnRRl7ZfUw0=dg9_b`nuF9N-wrY!PGU}qt)Gwm)0nzHo^&2!Oo#mhj`{MZjJ zEnLkF<b+32rEPDaZSNAVwC#Vo<+EO;?c_6737jbe&ZK?C#`fG<rEy2vQ}j1xJ^AYP zyr-Rr*7MySRDVHx7K1^xB8V#TbOf&}gTb5Ad_;fZ4hDsIC>WFiP&WzJ8|eU&6F?p_ zBrCFfNtGCi1pnm`Ab08Cvd!-FEHg+vPG|cvLy6z%+>5t5@mD#wEi;sG&CX5BOgYht z#ezccPY*+me{~Fk{s`8H(p{dH@xmT8&5W^v_aiUt_h45G`#m4o@8M3?EmR9tAF(5z zG;@a?@q&c*tF<SNt=tgs{|giY!iL5QUAjrT4T>~}Y6W-tG#3SxB03%AP%K5l6Y;pf zb*<PQYIBohXUe*Ma!=)4Z?8V<w5?b_Xy%C?E<UAiD7ywv3=Ld)dzgEZ+p}{go$TlI z!a>4}iV_M3+{bC#O*)IT*$i8^eva&~SI>5r*t>`3J3Ik$a00Y;A}33fbR$!8#@a<e z3QPSQY!p_{wsUN%lV*EPOiV!k;9{nyB~|5mI1#!O8gSyylo-;s%N%K2cvg!6DU70r z!gpZpd55fgC#NHk-gA8DEI-42&?!bcd$7DzAE!mq7dYA_AcI9Cn=u}@J3Sn1Z@3Wb zfI!YeFTw^0cJ;8#O~>Q}KN^7*2G#};HzW{tOCeq+s}CX?94LunP+tzV&E0)Q#^h|- zNcVH2@pxqQ{u!30McO~7$2h!)u@6P21z3Yd!@LY@yA&lGHQe7?O3}+lcqC|!F9*yr zU~mfz>l-xxcO>x^?!37;=(E5Jw~=E&KxxvHo1zOb*Oi!nMIU}Lz$~yEPrxb=ftp>q ze3|st1Zc!&le@U~_I8eF9^o;4hk4>0)ET;%7qE~q9JF3C9-v!DGkU&~mMvXJu{v6x z8g1$!+yc@adVzy_grh`zf`}lQU#m8CYb!P%nVR5r?#JGtokM%(G#~^p#(FEudj(5J zwhhI_v9WL{OnR{kH6TG8<EJAD*c{^}=tY!Kp^s;{Q7H~RVA17hp=2yIj0IMC<Plh` zzX6+YI-m4#*SOo^NCbHovI(P75yyFS8`d%U#NZgMUQj87a#mqUy&Z3IL$FSk^CX|p z6i_N)fN|mk=>wf<DlQQ%aY{n;2u6Hb10+b<0|^a95Vc`8MV{V%aV*F|`-yhf18NuS zy+F)?W@jjCw8OaLrQHvs1dWB#Ni7hgAS*Z5RfcF-`rpirluzNVpw1w)zpfIFhf>U0 z*ahrunc6r-NPiKHIfhbO1J8oc1XE6HeNWgh2u&qon3i)w=W3y3DnhBHtY*X|XQJw0 zkCALByK!seL$n$r11&bHMW_sYZLjxmW>1|61Cm4}06{TBaXR^6I!fU?T-TTskD3sY zrNeRl>(G&zBdL&~p1r0XIwzE>^jd{L_Qqk~Pde*c*ND{QiypuWe*S+SfBF2}=sQPL z+t}3b&;Rs)|8?&F{KL{)MDH950b)WAgbh#;`Dz)+_gE`-lt5)wKaz}fE14^KX2gN5 zrG{yElHQMDWBCc)hO$i3F0i*)sXBor>W5&nZhrrOB?z#&m30HkOY;yA9j5q_faoyI zD}m^Sewf(JIHJq6wMiG;!FF0Z5Hs#}p6|A)HZdw)fWX<U7YsGPSV#56e3Ka6#DUD* zG&Z$~8yfDe1YiYWbm?tKMpR9;g3PfKfZ$51m#P!0lgt#=SF#pJSRta{tB&)h&kw0? z88&VrsP@$*v2Yda_7PmB1fRZwNeM_zGC{Rfx{8Ei)~YucB<OxHC}UgojR>6XYKku^ z#<MNuiXugh??D9l10eqjD2=D;zpdkP^@^vX;OThb+40=7W6AZ@{`CE4L;2zN6wmd7 z=X&0Az38jYp3VC@;rFt(HQzR<)Sf8Rp2%08C~oKke0g1Q17gq><W%r972Db|^yS9( zh1=OMTvir0_8~gmnkPREPB9c@sEY}w2ykQNQWM=Q1w@b&e;p`VLeNucMzR5j1@t8w zi`lKKbz&L5`#sEI6OuC2mO?~t!CbPoiGVl={E_3gh}wQo+J}>LekIvekXQ%Q(m-OF zNs75jjR`cS=m(}0T!Q<F$7-y*4sA}cDSNELQX(DmZ-+oz@-l0`I*z;+dTdIJZ-as( zdTdG=6Fv5>K#$E*eiP_%g|r1aT-u7H6G;~ml+n^QARx5t(ssP-0HXRNg8Be7AVsAf z2<fg|0U%4g7`YD#MUSN&c#HK`ePbjoF<eSJF&Gg6X*ZCS_yXC0&u(0GvY62D4=`mb zaQwH2hAT^;VK(2eO=;LxXxIi|Ex^EmduIU#uCBZP;WFc>I`p!oBX@K0=F)WWjf2Z} zw)N1L43J+Sne$}W%o~|Ee(7S?w;&Y#$i2uus#t3Ov@_q-uQc@+n))+N18%mI;|EB1 zuHxSvWu{XEx(r#IEZ<{rRVG4gr3?5ZG6OjT_K9uP$!LQ~M{_3=)SiN6Hb)m^BL_UA zfVHXw*I}uKDQ!zRQ?8Vo7;Nd{O%`9ecqegTH>YQb@JM+Qv<6^hq-Gc>3z*{*DiTxP zq*t)(rWw27NL9od1?M+QOEC3{1e)*k1B8_8iF-wBpdKk-sxnn&$(2s+q;C=-9dfMf ziPXAerQkuVJyk8(Q~m_PdHMn9`#R&=+NMD!V|#x?swU}A)gl6~*-EAQWK~H?m5A6U ztCOB&1-1iGdeR<$tSjjgoNGN@qYZ3H&VFnAq1L4%VYb_!T(>f2(zZriHn}2KVy>&R z#76TwIg)i+pILh)RiCU++Odt$b5zZ{K~hK?&{`5i?S~u*lz;j$Nf#l(Yt4~mSSG{9 z!jK=@cF7@B=)CkNYt*eGSxx%ZID3qqx8|K{NH(mIgMYQwS>jTTw9H%7*vMfmX%h7b zau_v9d4Ovgu!ocNztMavVk3exS=RDYAnCA_V~*tO+e+gKzGMJL*V;Nuo2;#&DPb0T zUCIiOTunwFm7bHeE4eb&2)sb8+|sGU8)kf=GFLKt&G2N6wZ_&v*zhz8>@=u;mb|LI zZC>)aWKF5$5PUe!hH08*Vz!L!KDWjwRai#JoXO>KB|vz5#r!5=Oc1RR<bZx{Gp<X| zAn{#Ex7F_o`T@ovh$=KWKyER?jr1-6cO1Pdtq&7yr{T=xCgWP#54~X4#I4DNlDfIp zXe+o6ndwZaXO(1R?l8g4Mrkp(unuZS?~}M`tmgj`mLZBm421!Pq~N-Szn5a{nw!cB zAf2YB7bc!ggI3^6xRtxMs_pQ-7&RN3Sd(dtgLLOKa0BoK@y=9)kMRIE%xJ(PK*KWE zrP~N&aX`N`%+>^pDAqx1HnUbW44}(W_*H^#Ah;ojQ({a2t<Nl)qRrSmTEOe9lJU_= z$Q00e@ZX||IP;c<4L`OK1y=RW1a(xLXvO0n)c@7V|1tZ~5vd;rdkFk1s>T3<4-yn8 zB+Aku2%eoBh(y7e$bfPYF++UV#HUOoiJ~?LuIi?;GUGR(_JD>(r=}5F)EFZk1B@QP zXaYeH)qS?{G(c~fwcvxDDUu)pR%PK=T?5ql$*^Py96yGTE=Ht)rmX4oTO?G!G^oK% zAhvybHI*K1Vqj0ZLtHz8synDTd8jT30_P8cDX4a6l7tGF^cF^EhgGM9zE&C@fpbtA zLGms>_1xyA7?_>Gr39~}D;Vem6nQMJYGv=)t=h#YSu@I^d!6beAgk(v9)oUIorn_# z)pbFz{+qsg(wi97r6G>eQMi$gAVEz)tuRr_?j{W^L360I7aw}*tWYb=X(8>y2>X$s zkk^{(gr<TQrvm{=m7P{uLABjVsJ1IJV1AWvN+_^YHY{;?b^`DND343NDFEK1I>-5F zlvmw46bW9Ty2F|v<LZNKz1pF9(b$2bW&^A2jUfETkXn8QIv99{buj+**_!OY4=+6$ zdAc`WeN?GFTBtsH&yi-+yNX=<Be&vdOM5f@#g1(+I`%*B*#DG$x=ZPJv(WLT;@OO` z(qoyitXOQ?0B}o{cB(8kwZWZl*~Qd1&G)CBFKg=N16g)%{rvj0^Oet^8TjM=bbqm~ zF+G?bd{x)*1KWZtd-H*J!8`X>dJwiq^^KXEi(B(`JC(Yfg}R;hTu@Sb`q<0b`uUD* z%|c!F;#}{1Z`xL@t;<}T+mg1!McVeWnm{Ho|AA7oxlprtnd$ZhzC@B9fQmFVqkBzL zw*Ptc)_nEWV&nSxME2&~Om1^dTpWBj`LIuE+?A=#)MDKA+1+!uvU2Xq;@*cN%Elc^ z<IYU&OGt7HTzo>gO>-a4e+U7jHnrJfq%OxGVPn$|HZ64IYI3_D^epr!fsXVEVy4bs z$qhWX2KNOB8hTaTko79n?YY6imIKeL59F&46gPKf90fo3(%&>+wal>XBP?tkYp%1f zcLWL{KwtSA=A5r^vze>cTJdrNw=k9)Uflff+G1kq_~ScIw<<f1C|i#z8wLs+1~N{l z6Swt8wNC;|wxxj|J0G__Y5Pg-XH9><>8IP2gXaqPyQp+uR5o7DIE!5O;t7S@wRG$6 zZ9nz=Q|&)CD@TV5_`9a;zou*$$v83&$Z!Lf+Y2T3FFBRXZzyg1GVWqqCpa|?E$v>q z`QtYppL=rdC&xY;`h3^t@BY_=%HeZ`!{?Nqb4uF<D59-nao=Ab`*i5(o~O6}_K>po zWMS_~W&25`?KH`HecOws9nYHp3tW=4EphrZ?yi$yHLn5(Eq_D4ap#N1{m&bL50%FL zLSw(;KV0x1&ifA+>soV;eBBoKy{uoKZytQneD-<s*=GYv^Z7#ad8PhBq5eX?{sJ%o zbZ1o{JCIE*e6Tq1;KS#wz4_MOqQ4>I{L;>}^}T9p&JO1GJUFx1ptSZWO*_EvpsAI( z8XS8xxLEUWXmS6;^GnCT)u7O}UuoJ8yk1fCRKD=EJomJK^VYt_t%_%7!Lu{(*$FAh zV{Jwhn>K3Gq<O)C7to!Re&T@U@U|D%w=Fd1L}mT<^x*w7#SL42C_TEhIJP8wI{9ft z={#QOJg#gw4$m&6FTC2o;RSF*+V^z`AZQfU?YoI;5-gBz-mMA?C^dAGhAMN)p0r7K zAe3&|rCO4nZp1Ye$Mn-An@5&7ozV?B33FK7eJQ$U38mX{QU=|uTkA-j&JZ~w2P%|h zPG?T^g(PioS;{cgRhL!828h9)bdP~^TG9@#!w%j7T|pQA<JvMSuelcEI!&F;XfiM? ze*?EQ>Td>KmS7<QCvbG);i*lVGu+RJKYfV@8n`o0fNeSiOEy?GS9d%!H6pWC)SgX) zOy#hbhJkkYf$3TX7D%vz%VG*Gkh)tL@iAM|w`>^9(!?*X2b@8OHEb<~kroL{8@+y= z($){IB~Sq584+XS=y?JzW$(=dCwOoW!4()TOvRCAOIA-3YfZl`OY5k*YFTzy)7cU{ z_?4p*L5y+&*A?y)`%G7I$`01*=vkLq!!5;HW9x1Eb*g{$^*#c$Orp{f1y*x3tJJ*7 zP>YiiNNyv+*(i-82_r!@i#VKV>eW%Wh1Vl)N{McdsaUBMI&h30!cH<K(lJbU9LXT2 zal<1VNEs!DF#?*h<JQ&U+2&Og9{pJZh!puDBn73XhXH5Zq3o{g@WO~v-&LsZTHO2O zh*A%V$}3;PGUN5G*CAcD>OirvDZ6*!O{KAGaq!7mC9prk7Moi!>4V<%nU~G23mreK zeH2(^7q>j=RoV{}+7CQ!SK1Ff6+Vk9?R5D`pDng*UGym}d(x*+B^b|6D1pvGpfi24 zSl5*8%)FJaY=2ePlzy8?^KP$n4x4@+$ps+8!_qr=-HF$*tr!B=>>&&|iR2WL(?}51 zDe+JHBfR}C5VcCT--SfjjRYUF(t8jpqo6&i8SseB5eb$fe;)`K>Wsf-+dgz%Lo&rO zm)UpO;`^h^_6p~YWo9kXME%)_XPdtko!Thr8fBgJ%S;J9Wp8(`UuIrQNCy!UX^5^~ zP+MHD@c%2cL|E56urWhJKf%V5Bgx`Q1Y2&FuZ2Lu;8d;~z7a(IwwUQjJVI7%s!f?m zo*Irc<OUpTiN6MQ9YQ&E5>@*(@*cH%KU@ND9@FpWYZB`Mvs75>^&<7K=4v>-u2B(q zfy_xZc3{S4VdpX`V^15erc{uwA$vUO&mjB|^r4K1C(Nx)Ol3``=H7w(2QvJ<!+A%e zrks#&*9i_19$%s0Sj|5XJQOR4hoXykD7uM<BD|XiZ>0IaYmpss6W>G+3}B^Nd$rs* z@gW!lNTW|1@0Wc8Bn8L4cPuP|OCLW4o;%>QNcPIwvN<5b>pK8wXj}msOjzYXyn}Qp zcMXF9E_F>IYc=sP>C>F8Oz!C?wKUmBTXJ9P;JE7>Iye%Ctg~-(;EaxLh@?4M6--~a z)xD`KzK+LB-jqrhevdkHYpXQuD$SksDxOo+pKMiUKH{M@4GvkR8xg*Bh0c74j3i+D zuY0NKOl+w$^~!=e@1=|7nv+f&Ivq^W$8N=dS(;`{$8S*PT2pnkB1;*>QeNoSYNIY$ zRx1%2X>oKSr3&A?wDQ*dTMPT`de(uCK$`d;&UJc6tl?Z|ECr@0``YP%ZxO8GTDNL0 z8o!ZI&{3@aaHvbbYd54vz7Syf`+4v2)_?iuea%OP*KnU(fJna~_c=S*NXp&kU~?S8 zm!6GP8LXk^3(#nHAy4TxAD&WcJG#0_Xmjp%OPAp!WswjKbRMt12SjB<QVP!HK4%ED zN;IB?4J9#6pEFHG#eKS=@2~JSD_{Dlx7i<}PJ&=DD6xPide^P#Z&uv7|4TdTJqSpf z_aGoc-h;1NTC;q*3h)_MI&uFNyuMd@o4%F4RgSn|Es6Gd4Z3QD_6ZIR7Q-vmT7TCZ zCKA-(jcyo%{fWbhxLk)8raUQcssfxOoWu>mXEBRWq$cT^q^L}p6GJ87NECe$T;S^k zeMS(PDtJPjAK;0dJ^^#tWEJ!=Ip7-EjvOgJxI(y7H3@3`vl{fRnm@Qgu<wtgY7?7{ z^bmVpnc23^^1LcpZS9AY)o_eP2Xd@5-Gb4c$x(L!BNm>Mb>MtZne?H%MbZl|Yr?Mf z6N-fq7nvF`gO{{fuo@sy-6lt}MjHuhJ1wJP#tm3wVV~0;u3jUJ)dj;GVHR2oocsyp zW<&s2t4peJjhxXy4<m1_Q>v+Sbb$vNlTDU-`k_x7^u}9GV90K;)+n_e@<Mq;4q`Sx zmDpk2Lv1~48S<@lvfhE|dA)9eFU`yQZSw*Xd@a-y<smtQiZT;Cd;hwHBg;4z#4>d= zu*59mU5MFil(Z&ymN+dy&CK{;%dwC%b!dR=){;{GO=kTP$x&+H$NjpG{|jTkj!VK2 zn#c))Rr*yCc<1G7zZ-%n$qI}Y=3a~jncFcM^gCi6|IY8ac^rFmSmI&iholft0u~|` z2*;}<#6UjVY_&qe>meb4)QKTl5+R<3Ep9Yz%+eT!_8~$0vW6{A;1vNFQ6dpbvUCHl zh(<w_2~<BcjUs|q=-xx%3e8ouHb_6`5!Bzk&|u1TjE5p!l90$q2#9$LuM$X(BAG^l zCgbjA6UZbMV(AV(nnAJ;iD?v0!mY{<N*`kIUA(bf`Od0U#??&veT?A}gT#F77K22C zC&psw56L4i6@$@OwcnBNNdE~!WSpuv2&*3&(1)1dY+x1L3HI9Gh3O^#4TyBmnzsDA z+J-?Xt8K_!Ty*AZ`jnc!LQS7x<So|JW(MZ!({|lzykO4`%(cz8rEOp>s||o5d2_Bp zY2K#PY)iAnng$Z!eXv8R={D}SEOdamn8o<zX5sZ{76y_YfI75x<oHGQ!I6a{@U4fI zt@P&P%a*o<{b0vEv~UQ&;IQ#U%kJkbyO;Jo?fiVx=a-+=Jlp+@&%bj~X}MHrxpePL z`dIol6xYhZmmZG)Xw#F9rP`&7KW=#3`=s|Ln?CFKyzy^$e6~Z`c3RnTMrk>t6}<uC z?jklme#!PQ`6#Ju-UBZ%Z`!Z494NFLzzVfNl+C&Ehuf8wzCuf1`Z&}COIQpnZGPOU zY}u!@>?7uFYB{wn?Xy@;vx$85X857)G_d<c;NbJXK>(-&hYNwjivP`m|INJr&2MTu zg%<h&q9xYToa2#iao}Oq^VYt6Yag|q?)asLY1)))&kfA|-u&;O>GLJLeQn<Qid(u~ zY&rCN%b}-(pPhN;_(xy<%DctGM?SCl{Ma-0*)Gt<x1L9{H&DfcuX9vn2ItScTGPC$ zTT%hBH!Pu4M*&86z(3K;{~0deGh!@Q6p6kGZ*kx}06i33em#?LtsO-7sz~`jFY{4H zSyzeG)Qvg|*c8F38B^0-D#20KDX?ojwY))qH6jO;3^Pu@u3VwLRIZVxGP&}@8kL|+ zdeLIpZJXuks#WqW4T?UKcfm}26QE_|qed1u+FT$33@H1mQ9o3;+o6eMB6M-xCo;IZ zN|S{TG2p)-$sxIm1cjd_`EWz1eP6&ShsUFQiNHj;C!?ZokzktO`U?o2-MWh4Di`Jd z9p%`cKz#U)KqXUCm${lfJ~xu<R2sS!|F$&xMYL}+om+hMnc3&Q_PnpXSl2MWH@j=@ zU^bLHxj6Ljys}}pQnx34DShcxU42HH+n3#wYg`OG+@Q4V0OyqSrI(OmU$%W=b9Qv@ zt@*bgV4eT|SmsjJb}xEA3N9+uHJPpHJL&53O(X8433Kj*>S`Y?GZ|4gs8jYJth&Y* zTk!QZ(==~oBX|M~s~yO!;CXM8g2XUSck(1}r-j|zMjA_~$+-A68M<MymPifrbRy!U zC^O8v(65u!$ZaXZ+&H?eiZ}QnJCYt^n0Em3a1Uw-umY+VnkGQGP+O&mia=IwR7Fkm zqx8p^&|9)-BcrJ79qB&CJBH*ql0hVY3Pi?+P=?f)@w*T-+q?=h>ITPuK@LPK8u^k% zpb<V>(WW$XfR%8&QvXJpeOVtUvq2tK>i6q5NH^FZe=BCj2T(=n&w&gRx`GT3N&gw1 zL2nIVypu>yAvujCfCSYE38yBpGfEk}ngdd5TO_~`l6Q=G`LB1OW3<0z+itWiBAH;B z0rmu2JO(Q+x9oH|xn*W8QhSOR5KHJ)o8Jk(J(O(W(4P2OqS+I%cHIHhNj^oR`8HO{ zH{gA9Db_a%pEQt=_0?u0C_=uTr+rbcFGwOdFhZ3P0lo<rku@b2rx|$-N^P<{?E^2* zFnm`9Ts$P4N@}GX3Qx`SLEi8+I?Y8gis21LGT<$+Oo1CIexgpZv<ESB#7wl8M*j@2 zNOzyXt41WaTmF^ju=Z(_x1=SwMX4eW0EM@dShmR2=8a#G>C9VyMP_&2`YSR=^K1W# z%-+29S7ciA)?bmSzDxd!On=_`TlO4b;d3YDB>UmwjW03$7v{rLwlO;kgS<M;uiy10 hdGw3Y2v^-TEU*bB+di;i7OPW|1wQ)48WBhr|9?DEcsT$7 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/bayes_linear.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..063355b16a397fb5fd89d38daa0d3ca5a8506766 GIT binary patch literal 14506 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 B<oN&q literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/engine.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..973173b304ddea1307ffa400cc1815eb81399423 GIT binary patch literal 84465 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 B$2|Z5 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbfe4d97e8e83ebc276e45ba6e84f514784f1d0b GIT binary patch literal 5560 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 Z-$TZ+G!?TsR$7>|U8i)t^vVlo{{y+urp*8V literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaf7d2d285e24e4d2e31c3dab3b1b071be7c5ecf GIT binary patch literal 8154 zcmd5>UrZe5cAwe5>|(GnIA)CngJT<SF5Y;t!44r#z<*+5;DT|S#3kK)?99U8*_q{= zSp)8(a-~FFOMX~XM_H>}iK||vptusZ@&i@x!&UooUn;TDKA@2-MXmhcH!3$$bsy@U z^UeMnz_H^>RcE}%Gv9oF&UgO&zH<(LS5xEX;BwU;lkOehxPQl&;^injJnM#sZ#a>= z$%(w^Q23h;_}{5G<F1=7o)fD?*O&ZFx9I+oyXg@<K)ulBg|;fuG0Fvf$s<mV^ZWgM zM3+QCQw3vE66AP7k>ZkS5JQG0SrtAW86e}rpM^gU`Tf_Vm_#KtD(T(+a7Y*p34?@6 ziXyiQL=}ZTXiADyGTN<C-9oPrqa-fPX!Mp4)2NVyvD6^4YRn1KNunBZOpdap{IJv@ zF%&Z1E(}vG8WK8S#(vcZ2^Taq7D5JZBo$SnWL#EcW3FAeChNC^UX>_wx~ww>28l{0 z82kPc{TFUr>mBSk6+RPe7Y5|p5>05D0-UL`0sFlws}rIYZx^r!(9X^?Cp$X3PQxxc z>^mC@2?PJ~dk~J=zGH_%QkSR@Cu))?!oMy2wJ@wHbE+1X;Wau*G~F-FCWxwoEOlU5 zN@&y&-n681@<upx=4AL3tbSpV$W+i`Y)kFJD2YiRAQb7xWr6ueYyxW+E?vJO+)PqA zItfE&WaExR6&QnC>IlO=dXvVaM!SW}gvz2Ys7;c1oQR;S!O&<l<iB)skjP565W~-* zc=7WG@{Arzs`5$QNE*fjp+-oQ{1>GJJfUGAn^)#Us>LPPp(;lUqSr(;1a+eHU7ynp zDXt4A2Cj4j{r#$L$S|YC>|n6e8>b>kMUJxVUQ%z%R8yG&D#B=ShW<}RL5ZL_(4r2y z_X7{3MfTc-nVFf;Zd|{uOm@8OAC8e&Oj2ivB2wh9E9^ges<Z2z@(h0e1u7A=3NW(E zR2DuWst`Vda_sOwMSmL#@}@Tdy1h-5D7a1O^1u_mKik7|++R7q;ZnTF-(o&Wt3}6` z+`LnC0(FTl(LLdqcdHknho{g(0Dr_DRoKHQP0DdoFq?H%bGx^*xtd`vUtzAsv?Iog z{x7TMo$RR^o?POd7mqedYruL%RN)+4%9-N6g>T=LzC)X9dt1yQx*yhj3*){kjZL}5 z+9k)lC*=Wr*-QQjCh!YzUC`nQ(7etNhDy;SWgsF%H7N%EFN0O-%q*e`(RBa>Mfe07 zC3><~za`BH;53ukga)3@rb9hgKBj|};{wA3QN{q{V6P`j7kgDBaWX4(1DF}?9Y+k3 zSvj7J3+1^4QJSEV6k=VlIbzHuBp9X}Xf~yh!==>)>`>^B4Cv5Vk##^nErIA+VAsx| zK&9!VOu^O=55G{zL{b8Ae8D)eW)!Xi5Q|a_+`<q5*@iR~mSGHBlZ+%)ZM$Ucy?wB@ zC`Zd1#5qn2Ad)z&2ol%9ckBX3ctOY~i3GSG8CN8M5_Li<3e~JqqzOp{Jdc(v0c_F* zzk2vRI|Jk!&SpiWeknMU?!b4Ek2&nNG|H_yhMr=_Rfp+N6Q&zrOVd|*lUH?Y7XCDL zp?mCOz*T*W-qI$ONka6oi&`{^sGyI1C>vLj<71Z<ZDyDllVjs#PSU|GWq_pFF&%76 zn*d*q#1UfjF$q3JU<(nNRHRU1&U6s<P7~8FwlWjcLp_QHR;Qm25w#0=cy<WL0{6K7 z!2NUCk?iz?(dE|cm0bO?eEqSFJ;$EGSI#CBFElWr`~y7ve4)$(Xn-p_dSJBS22!}7 zwIE2lqg~`aKRWNQiM|9%qEmFGz&Y<!aoimUBkojl+uS+D!*@@Nt#<ENiU())4pHb1 zDxv7ij7(TOY`y;!HU9L!pFe-j+E-l^gA)qVa;BSEjOo&+sj=#$HLOjaj*P1&FYCw? zSU;`BW-s=E4|kZQGnH%?exb)Z&|SynK?4nM+`p0~%lw1raya{GuHksT;duJe=Aowa zrOeU0S05iZlnq<o7eBxM`4-35oM9xxKW-M5CYHxnT332k=<21_w%;hZ=F|D+(;0V$ zWa~2GVs)l^v%WDsK<i+wr?9{0ObDiT61)b21e=Ec*Je-AMyL<T9w3&jGttn!@cxrF zc@anLLxQZ@_(E%8mbVNK|0kB$^diekZF6;IXU>A19Y#A_by;>skz>o$-oU2-5Sz8o z!_e|_OZgDTeFo&UEG3AR5-eH@c`&s!wYzNq5*A>3chRSTgRlA55&kPWd;PpabfmaD zpzOO&kw<Y^7h)`m8G++o19N4kCE};($U$e>SLs1)a9KXe6WRo?rU#-rIJk7QZt&EF zSG31#&|Mz^@?RkMef#fMWm~ho58lj9XB%_-j^y_pN%!vJnQbWVwhX^{urXV=sAq31 z_bz?5_?H<z)4J%&xHjt>(pPpGIJylp@PCGf*OT(k2G?J_*u+zgof?3%4uKZ5V?XPv znQp|Q3$&wtXe(@kqSY64LGi3%+MvhbX`3ou%@01sfe9d}kDm{jJ*b!-aD<lDrJ3bv z0L<9h$U}Mc>N>wVm}~3KwY-~ed3U4v-QC@TIWh#uE{Li0pu_YNB{4}N<B~y4&$yOU zMZI8%rc+j9W_46kA?cG;_yxVDo5g3QuM~4JIWSOUFhJjejhT+#J{?U#5WWCIEu1NP zx1Hnk6!d6;pZ**O2xIFluBtBc(f8iw4R7<7i}xLetrm&L?F(#iB~r`PAIOl*!L%ps z`N6k8BY*E}+3>ae^r#<eIgoc(rtQ}qOI;gvM~Z`|zV`_mK4Ht{@*UXXb|HI8>y|lS zPrydQ*Vpdf$TX!rPZ|#`)vh?;?p*af^sSv;JG<WbyYr9EZ?yIOv2LUBYOe8WzVYg2 z!=WuF?>`KC^B-R5+wyRGY8Uz~S1QE?AP_v_S+ep0fP)>b5Jc=T#=J9SgPM7#Q88CJ zVK7iDg=>3~kaA8Tvam~ZlwnJBB5-XF4Iy2@HC^R?7`vn(aT48MIf`y%VBk@>eqw%b zNV_va%#@vX+xCFT8@p1N^teSwtb#{$>Ehb(t-x`aH@mc6FmHkPl)G|fwibZGi{{$4 zvd5BD4{&N*r6l(XE(?9jGh1un3@E>HyPf-;GvI3X9u(UlrUVUCj>njh{5{0$Ed96y zL3R?n*~;+HDGN0aW0Dw<bwGlnCp5qT!O&RF@ezq?<1!RZAh(*uTt`+VkxdnY!UF5k z+xJSz9VT{!QZgr;P$N3Q@|7NBGa*b2YmoHm!VE-o5}UQm8<Z`e4bubUT(t5yNE9QG z2g01YC5x|{Au@Jel)51UAh_Z#pt7M)5=cDD+i3?mF}8jYuH0Es$a;l<vA(gJhzp{m zK~Sp|cOe!83*kOK57DF8QpF&&95t9uMN&;SV~Ir&W>p;0QaPc_nI2KTEsIjnWAd}6 zx4<I};Sz5HF+JASO#YURo`(7;0(XrqEu-D=c>;cVCs@=1_u~o9AIKhD4(5FAd0+cN z-=?oRJ&^YW7W$sl?7jEt*LpU*c>DhCEM1yi;g|kmCH!E1<BgNKnozzbv~U>$i44si zy+6Cyvv4^bW;aQn`PIOan*Es$$mn|Sznh(2d@oniny+cy;+*dH8A<bx15Ha!%Vg!q z%E%hOa{b|n-zaN0)_d7K{fD}L)YmUR`tw}iVm@%u>UsmtO1!66F8+3Gtz(U>*R6?< z&gB9<`9RNqIQc{G!GSQ1ccwMdyZC1M_TAbiut;FJ3lbB&M^>g+M^}#j_B<QS|1P>7 zUW+~I&IQir1Lt=RPS<W$*TGzPk7TaFeeB+Q8?MHkU|*_C{Q(4P2m5k$sWSfD0p5_5 z?h4aR8{`*y?Eu@OP|?C{r*HwpI#LzTZU>;LQql_t0K~dqLEln>>IATHLJs&cumPyC z0H6Q}v;Y4A#L9rT*KUT(0BS3dMXfrTD2x|N_Hn4f0>HhbI`o<lgY{OZ4Fft>l(qFT zWC|sL7a3sr^H9)J#t+&7`e(pFF?ulh>p?fg5(_<xuhlGov!p=JVT%($R!3{7K#PMm zw1^NoE*q54Ir={I!{n<_E%@;`SG%tQ9w3%|Ft_nWFjw<dzUHlk%TM+;WIoA`EPj^T z+mheg0^yST93yGx<AAVSw|sTYnLm0a7wF96zq2LxV}6^i{h_*UVbJolQdk44<3Y^A zsva;=r~q?Q&|qC-5NOT2wuK#-nXwD1s&1?oGcR-6J!sxz^D?*nD+DtW^Iq^MZ}~_U z9feA87<|Z?@>=u$4fpGcV}HKN?vqfJc7d;XE01;v1*^V={d`vn_fnp6KNc9gZwtb> z^4Bsq7*JMn_mUYWS<To@20=L6LJIg>M9~Z>mS}Zdqi}dD8k}{q3Wa4Td_pM?E3QR5 z{ONjdIb_)NuvH^gQd~Z3uT%Jo6&|gH_~KP!g>s;=dttd)EXF^VSQTcgs*7en07YbM zub2Z%%~p+^D2l)sWc6-~6;k0w1uzkIt3v;5TzQRBG^#5Ci1U(=rYPlIgPRKEDa)X| zeJc*L{_a#3g&mlR;BS@md?m~<9f=4c)M@a*3Yfy;2!j(Aiv)cY80BZeWePC&R7%?P zl_E~Fs<<E1R}z3#VqwEAgwydnWVnXJDvR!A*v7^Hs>?d<hdzG`KmA{UKnB~+H631R z%ef9N^rvU7VoPxO)0LUE>D9T7z&p8p-T8gp3;h_|oVy#j7un*x?m^z7Y5s?5$Z7Ar zm%aLZb=yXD+h*X{^3+OrWn}gA^3?KFJ`hfS^tibb;ufCW;dR%eiS?Pyt`8u1Y3bwt zlS7*BhrAeWteW2aW%`#tdbpN$h<XU#YjrE)!w=U!S)cl2-S6YM=7D_k!1e(@R5xt6 z8W?g0`JtfC^hP407L7z8`A^0Zb4(Ft6MGJoHD2+^P7f<K#bD7=6^d%rs);gT{;8@5 zs{T;tKTn6?6QD7te+2}RW1ipg9OPYF9FkKUU%$caxBhK%Z*SQDZFw&7eC-yugAO~I bd8inaNFU$G@89A|r0WO|$^Hun+x`CllJEy5 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/eval_rec_rule.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27878248cbdaa2abf0af9d51d061aa6e2db86f43 GIT binary patch literal 5648 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 Qn=09pu6MokM(NCd0M{nQGXMYp literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc01f0f01b8bc70d438a3317b87d304883456f15 GIT binary patch literal 17477 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т#dTfa#8J56>f8$ut6T)8sKb87ka10Av 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 WxdKn&n8;-&>4E+sNkEpU=>G#}NHw+q literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..786fb6880e590007f4cc628dab413d62f1590cce GIT binary patch literal 19555 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7e0226dc1e28c09b9cd09a610599007b2267e3c GIT binary patch literal 17597 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 C=1mCz literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exp_designs_.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..076580dd7fa9e11559ef202903d44e00e25b8a26 GIT binary patch literal 20552 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af7431ce432969f095d1c07f429b8129cb5a2def GIT binary patch literal 8154 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93c4663b2cd6bd9acef73471231ba305bddf9dad GIT binary patch literal 12405 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/exploration.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98964152a4ea29f85f061ea6ec7daa3df7487230 GIT binary patch literal 8190 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 O{Slolq(+zPr9T4XZ>fI( literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16a383b994853cdb226f7b7fb291cdbef789e1f7 GIT binary patch literal 7185 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ce136ba4d826073719d19ffbbc87cff8dc02562 GIT binary patch literal 7952 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/glexindex.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3f24cf9cb753b59f9e226f828a7c3598ac65a9a GIT binary patch literal 7232 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/input_space.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2310be6610a4c4824d6749297cdffe80c533a47 GIT binary patch literal 16785 zcmd6OYit`=mSz>-lqivUk(5M9C0h^EmgOi)WXrEuwjxXEShiy)mK~>=l8Tb3P^4T% z`Jo}x?o0;54TN2$;YE~Q&4g%pvrI=jquy=wYJvRlVERY@7+|V2H84?t01pQKk$=jj z8weT;?4EOrELKsL<0Os2l&D*;bI(2J+}F9^J@wzJswyZrChz`D`1xZL^{;qSJS>Ha zuaCpUM-)eKbd<VAle6iXiJZ;zmTOj;GErwK&h$RTnLjmA)aUT89@lIfeTfQMzQo({ zslrooD$;y?1a3c~!h|z$rLUQ}3eNmKea*sEa<=z@Kj-4?aBt%r?^D<8TovbpI|pY4 z&eclASZrZ2acO~_3bXIh6ji~%ad|c(FjG-h5SW>8EX=csu)ri{!%PH;83C!8={QfG z&4&~0e4GnMnQ1;gkB<lsE+QoO$mC)o5|0VY0w2E_;ldoVC`4j2B;VVl<hPml<Xm_v z(OW@s4JFh}VS(Hp)DCh>axh0R3%N&G)n_UbW-1;_u#s4?hy|8sLA)@}%(MJVB*sRC z9wyQo?qy=|yhr1qmz7D}SqL+1jAIN>HC6%xdb2m#NR*w7h8do{#c*tb?Iq067NK)! zj1XaSlmR1X#au?t@oCL!I?96jig{rwJZ08ZG}bfTe?3j=IY}p}koG!hf;*@*_24MD zE4B-0Z*Zq^N>bTkdn}TZ^QVx0u05e4*CpyRdOT=V9K^8aC+8G*nO2I01t}FvjEl@G zwNta<sdqv**=U3dMX-4YL9=2J!qI8PN?7nt;4h#gP+Nce>6xR~Ul+o>aGifAJ{z57 zS>gI{d}?t%97_n-&qflXi<8$U**jr@u;k;nuZM55^9#|iaD8!pl8<mR;ZQ<YgbIu# z787wk!bZ#Jg+-o^&p?|Ek!C4eCt`(2tL<I5qc}n!Xe1E|E!7bLN#pM=KJ=rs(3h#Z zRNmi`wk%iW+j`R$*%8>bQ4Njoz?rZ2;|cDaRSz9)n~pZg(JnjM#p3U4$WAFXKAc$O zW8+g=4Z%|@{FD0pKahR|bu@>x<Vev8t-dHKNzZ9@`6+PtT;pP_*Ey|Tv&ehLVXR?} zeur@79UQhDTai3w=gj(hkV}(=v%Et%3+{xwNKa9m)hN|_v|i$2>McHHGU#KPa};wM zb8@zVOifAC95xnmaQ4DeW2p{f-uLK4Loo+M%~ck!fzvLf&AEy+oUO5VN%7@n6YY6p z+0OE^mj$i@tX5TIQ)Yo1Df2GUnZKKKDNEAAw<lVP<v{D8=Co3cQbBF0vOBp-y=*iU z3nnc>y*?*cp0pl*Cv6?j+But^1IS?KEcz$Qyn$Qg6Kl+6ln>g8PIg{Mv>CM0TAeW$ zw5PXIR)aM?#e90JC#|JA-Oa`+n}JWw_vT|y+LHDe({AO5YKxqgL!A8*h5x}S)&m_` zn-b38=*dLXIbkMpGaOSVG#Gaon1jg}$Ry%0ZK@OQ^db)vEYD1_(W%8KOD5N&8aJE| zM_GXp;`3qVTye@Xyw;vFv+T`qp@0QG66e(!7g^vj6pfZRFsfw08Jz$D=1z5%+y|F9 zGBY;?GFt}KNgVUPM#jDp&%#8m$ub^~g-g^tx>1)$zQi$Z>4h_FEEZ2NlZ%n4aTXTP zQn7exHfLBqtP02Dur|KbH4YhBkX@VbnOk9?(fkip)uoqD#}l)t2@!wCY_IwNMc%#4 zg=m<C8km}m$Ke!@Mejfo?)~!r!SN-QymV^V;O|ToR0tC-KqS?4YU!%!xybZ1h!#r_ zTMEHC9!D(291X`5r&dio4rycxRjkoC=t4}TR1XO-iDLD?43izNRH$<tdLoJw9T(z% zD5ltgVr6-ry`xx#S#}|;cuIsJQmcxYofH%+&&FoLig`W~gM_`URFoW^po7P;MzN9E zQc#?lZ50b%!fYQ|3M+I(ae{=Q$@pT7Qyhy6>Xm?6VT-_n#|ebT5qPOZH}~%JAv%CW z=m*Q*rMCT4t@mC_+O}2iTd~RheNuf;t`CwK*g?5Ga%J1Y%FfNoPN}k6uI$bYY*zM( zm3?`CAU(W1mL7Wqvp8J9Z0)IEzO&NzK`Ncvs%6CXD^l%*TstAUCg5EYBR2-ODZA54 zlJwY?yEZc@*L6$oeX@IBZfMheP;?*6*9GLdu3X1vU9VWzyVbN$3|^F)UXz<%6YF1l z?5<h9z2cPpJ(ByNjKBW%A=y2!O_{2^8)NeE^Wvo|o5!z+$FFR8JH*bY<eitj^P*?| zn{5Zxz8AfWmVAAaT;H)xRXO*QBt87NuHoL1mEqO%QeBUXzvtKc<hmEr!;jo`g!NyU zSBB+4pX7gD_CLRVannB_`Ump+f*FhK>CAf?GFI?d2;~YVxAw2Io2`e%*26}MI^Q-$ zSMApxB5&ROH;*daawU@;0z-?Hoy34sQY|Ofa-xd^@v$P9ZOY<2OK&wat-P>0C^dA- z4V~MRx#}#frWtxG(7HO39gz2;W%j~(ND7>m1E(|2t>%{1fozw&2esStqP*vn)I20N z4`m$r=Z|enh<zg&o9tn-HL_=~?CBLfz1vPKOf7QTR4RqX5q*ldIdFl8=5!6i6*^s6 z^0+)Px=J)ovYOMC0(Yt8kfqGvU}#fS%EHkp>kQC`G-oWKxgs!Gn|DlRJt>%4b*`J{ zi0Ng5GVI0sq|RB{ZDOOT<%3E3r~5!Z&5bJN$8*xMRwl`Huu{sNawP3Z#}qn*WI0P{ zsgR}tNUAwa{Qpcemw4(W<Se?Wx4KAU)Er9CT*yRwkp>*M(j*LS=$u9~ZQ7Avn^eEW z!aq*goRp!Ax?*{HsSS4BRq8pd)T9lU^UKferAYfI*-KYH+4^Eh`g5|(VFo?RxL&1} zuirLbrEbwNCUKyYcg|b9PFf+CR_2=32p52LHICn6ovYvk>Fw{+N-#)Os!?M-q@0G_ zxMm`UQKwyVS0tUu3UHis{p-msJ*2T%zBWUpD!)amzfQRfb?efyQ*%v48MWm`->$S; z3)i>lRMj)k+e;;;s$(Y&Rtgj)Fjz?^W0{Ss47oMu{~2>vCo8j09#yK6)#d#PMvhMs zCyMgHNKt8&1zMKorgJ86V;$^!Ff?l3+!(B<VIdA~06;w&=%TK;OJ3fE;+q|AA$W%x zFYrD>TzCdxo=7aw!^9WR%VDG1d-NmDv9}}hi}MW7@nL{-E`wXjg{RrYXae2lx6!+N zyMU=6{TV)t7?#GP+#3ZHCxpHe6iU1$L}`e>#O#ZOh(Z7y#X<#tF{trD-me)DAbdhR zpip9w_?AbRD7a$;_8|`pd56@OI@pT%cm#f0Tvz}{pYQ_AX}V-rL8n;c!rz128>E#A z9z4_7BrFLM#1)1|HZDF7V3=ZAj76q-9Fu|!@x6$nNgPY1;x#Rs;sixQ2#g8*9w1h1 zEJzUJc<kMP_P`6pO?>juLOgm0U1abZUqQbYyhV6ITuy;!fSkwigvV~A*v_4~1nq*y z_N!RoA}%P7qP_W6LZaGLu}{siaRCq-PZ4!2S{xkBFbkfkkl+;iJgja2EaI_0@tv6L z#ROeO#Y(KMxb#&JbgTZWz0k7wE+og<O>vj37MhN-Gr)W*M7&uW7-NjP%?}{$VWc(9 zFY+(p-DynrV}fHe-vfz&GZt38?jXJ{`r80CktU=fP)p4^$G80D4D$K~Ov>Q)cI-r# z9@R9UBb;~FE#FC7^5C;J9Z0+LwZ60+UDyEl#MN8g=9S?O-?{e=xNpuOaE~xekK|pR z<?)BE_Dxs2>SPVbdydL`UXom=WY;N?{LqW56DwQuOvgj!g-zy#2X2vhL1He*%mvBS zl72aJG{67QdXwnt29Nrc70aqy^$NEsw{w)<YHC@TmRoysH{{knx%IfzbV6=A0hB*N zuWvNV<%ZXOBz7K=0)uj35T2iV+|-t}e0*T_z&2&8IuEj9nz3zLEH&rpt)AYs(Y(JE zJpP<l_CF{4k9}pP51#lv1xaT3-nncStOUgR;5XYA8tC&q&#k?(epBu_`LO5Z&7PMZ z%t$@sa?iM)6sf=YX1fZ@`9nR`(jf<4Sih1#e(H-?w#{_QDE$?MDHH)IO85r{<qH(; zX?C7MM;6lb$W~3=J>N?GYD@N}+}JDC9Fl7erB83w*5B(YJ*_<?*B(lr$sZov=wFW@ zKiRc6J0iOd$gY0T)en{CZ%VtiYP^}mht2nzw<(A7FiFxwd3S^CZp+fLdynkyS+{Mv z2SoQkKCnj)^yDtefkSfO=tiF$IFWJYo7?5)13B=Pd*$ZA4Y)a;abz5iiLd>_{S)go z;BQNT7eLvfpWSi);5rSyw$$7&H}_{8k6iwTuC`5ATedMbDl#uht^wIKAd=tXKzp`F z!U7NB3Z+pbKLK6BzaQus-fQ~p-u*ATtp<-9{ZI6dzy1w)D`haJ31)IL{9E83yk_u3 zG*6lUThRQ~!#D>GQyI%!AEoRt3v2XA-F#c}rtj|Gl?GP=<N%-7yvzJp1~CFCPN$r) zj$L_bK7Y!&D~;yIrz(;(@8eA1%V<6?_`jOJZd`+;Tp4rhACk_yHqM-?1Uc~jw*bO9 zvzixJ)CkYU+&3wHg0n(Nns)~!X`Xzt!f4+Tpr{8%0fr?u1MpY#KmhzLvk}0sdTliS zJz1gW1$WMpf3#L%^j?W>Zvbfdth&WG*E7=6{KUV74R){9r`n-vhaF6@O|JSGb))zY z=l+3p?D-ybT!LSpQpcdTu7|GGd<s4HbFKG6jhkX`akbB^>GTh(#kyzHlB+N4n_A0$ zS}htig*%U~r8j&EW5nmBal)0MWB<Z=pIPsJBrWUTq8IDS(AJVhy*c|5KzfFnD6Omw zZ9%1k+`3+`K3l@E3KkHb!@qhgfj?$^lB#-g8HT5tj2x^ecb4-c$+4uJ<(HLRZ5YqA z^?VZ6PUXEd_J29wGuPx5&i@1Z>h~FswJkEEJ&YDxYuusPf8v^+S+gH=O+Qex?=uRO zkP$=6GinBRPaTC~&0KTR`Clk5khF77Y#VUh@>kZBJ8`JkKEX3_8`}uk$kLDx!4B(k zt;_Q!oUfDCT|A7kEipinY`ajFt;2!RvI}L|<|GZ?((=a~owR@#Fk<L48WK{DOQt-4 znBiKdaLknu3y)FvR86cN5iq@dxK<<0d$fvWC2IgZ(0qs31w+rm^&dHs*8fPQYIZHZ zCad8O#T<C%+Kgoy?+oScl$SA5>*TdfBgWCr{zi{+6fgv`1%}JrSbQEJ4|Vefx9BEe zmkA<fAjSpv>td0cp-EPV2pAe6Fc3m98|PpduPy&^C+!@Bi;!p$V-O53A}>4>R#IBN z0&+1Kj~h{v(%PO$!2XT^5j*o_%aFmft`0@`w#_<-vY1g<uOZx9QX_C6Xh%~9B_4w9 zF|vGT2qsWaiA2jVGwh-uMA%s99S*k73IRWu36BzX0E`hVF|d8LfS&9yc`^QotgSJ~ zM~{n)D|Xl>g%FXj;$->B2<Xq>;h%#hqd1~rfEPGEOmGq&N06ls{q7xX&%th8JkCsq zZ|P8%b`?S~@z~21D}iSK76F^Wo?Uz<XyVV37eZuao>i<f>^z(tVCY5Iv<rWUUQf`> zV>5=mIM}}p<Ca`xI-yu5p&5LM-hpD9W2fSik)Q>3?V<~_EdK^PB?a>5@Vy-hA|+bG zw-@3urIMTg4S|*j0$fJw*9qaRFvMO(qf1WIj07GnRg;h{&0I^h2$kVRs}{}FyL1?l zwBoj?wrL6tnl#tqjxu0l@kQ91g(lxOOtwQKo^CMXfYxepV|fw4K-{0jBFIK|4+Dr8 z?xPCf1nd_Vwm+kH0G7f{LV`M}`<*zfs`w6KNPIsg1nD^rSBh;M8*)^&3yv%VMk1!= zad1=YuLI(R6=OY1YQb_EEX<$BR~F$0pHQ5y#%EL}O6ALFN!5gk{fcTfrQ!{gpX{xw zfEF&d6gw-Zo2e$iyj=Q5tyGe&UA2=a^eg-^pbyp(;EC^rYXUkc4%nI|K%-JkuApvI z)J&-)eQYicn5RJSCVqs7i>M^Ago20^I}hL)_5?)V6bp7n((3pNL_C1*1Qxb&EyK7E z>@MrJ0y;~i#~BiJPxeK4x74JArpl1MU%`7}0hWRUnNl}oAJsLa9r?!QbameAPgmv} zeCdkE2tTckN!~8m+qF%dr=17CB58W$k&0;8WOujh?i1aEd0&g{>(1F^-yzv|G-Jto z{2#f0=FVCqPbchLim-VZU^32(^O1^rya51)95@MpM`Ii8*5<n8#y+|6c*gd~-MCGi zfX&P1j*Mf=*Lv?=$=406GnNl6k7}C4nmzgEF4#!)HLFj2D}$fB^z)ab<{r7ZN36kL zzPS^#Hr~6PwW*n9-@zO!`<`2G-}Lp1zJ9XVdtPd~AU9nQ>n~t2KgqqZKD2gqWBS3x zFCwCERPv3=zR}&wsPV2uK8gQ4F0~$#TMvmf`1>wpmh{Vc*Xgy!jjjhZUj#+pu;d$- zeZy+O{*|#$&j0+p6gVgc4vIDS`(DbWas%t_YlHa%eY(@O)#M-eih|_#m|%&38rJ%E z8uYvAwO6gTWUgzyW-X}dmEZpyxfyuS{>31`bN&&8=O6`m4pLIKjjC<lY14w8zC&d; z`0l;2GLr3E9n0SM_|^YjyXIT>ZqUDO+!*>*;DPPIjo&(d*Y|fWsqa-Ocuo$UlLF_Y zhH<%JJY(AOH?7+LtLeTidqXwYI{VpiRe=W=|96jcU_|O3k(jeGb5`<?%Kp)e6`GFh z+n1}&y)OCsWnX{BlCc03Sljrdn%noCo2BgAuL}R5>vuK3h34_9<a<^2y^6&^Z}?M~ ztGw;!55j)_+EuKiBUndAu!@cly&QDlSoRLU(1Bwl$+vc7FMd1=q=g6MX~zE8%Vd3$ zHz<39q9+KU4YC`eAn2;@oMp{PE=V5+J5>Qx*}Ca!T}eo;4%yWqx;pYM??YG1rmJOT zR&sUAu5N&+^RA`>-W`-&J+iAuboIamFmQP?C&kKk_+e<pQOHx*4Urz{VT>ZUPH*k$ zxPNH9L)vp#-g7wP&bYtXHqrRp3qd2-B=4KD_f66BCIHD889FSx0-`JMxV3XNl4}-Q zUre7zHgD2fdpqyHwEoh={;|#evEOw{{TJl^3)0?;^4^OWn8Ao1hA;+7WPDZfUX#7o zM9(!~{K(y!tq|S&MaO;t=fZ#T)?Ye6{nLS(OUKQ!x94>;_0Q&-*Xzww8m0h5h%us< z@%1$uMg3*nU)Fy_CA9T5BC8y2T;Tzxr(rSROPB4n8v{Byb0MtIn8#A?Lqjl}#*@<p z<H71k!*!p?$+m-&E<R#T!)^IbAi4qc+j($yBL|FafE7Rqd9@_XoTCt;coO76pMxB` zL`zVmJ?ST-t)MIJB9X&bw(+h+m9iq@1!Zee?OJw8x+fyN-?QvCef^N=4;vurI!gmC zuCojv+B(EIRRL&yr6K;K%;pfL*$sQ}m02y4qG%sHCmp58j-+nidrrd=jdp`w>3x9f zRNkb7YLG+2;mBHBLw<M&z`R5y!2c{Bb0xe+*BXty0bTm8Ijm3DJVU>=fV%57OI0VU zf9iy22c5Pb)WuAk^Mkr%h5jjE4SIPr#3o%gO>-6Rm*MRxPtwg5!fgdxvYK-h+VxrZ zyu&(UO4TF|7Oer8zlQ21Yq)A$zNiP>>3gW*-4e9AHMeoR_@I6l8S6nt&kh-DV}Aou z)~J#ZDQk<pkE?!ylp2=uG%3H6Om$C?i36GHbuu*+WSU4qtrV_}W1QF6a^9mkE70mJ zx5M6=iT`Ap_;zYyqLQ8@%{e*eUzn1vX_HoH8IGES4}OX?xO{?qwfbkf=Cc~}WoQWZ z#*c>l?C<or$mJrmphX9hxQCk&mI+5-*$7|DFghdxzn+P~$}<kD%Sm=Jf(!o0l(ytI z0u?%pLR(tyh~m%(k4!u<f}^mY?J34`7y~#i6{3Ju3`Y|n%&Fh>;9{u&-;mFF;Nv1q zT6{MK!P`X>sOU<88dlfc5Vy^Dm)<iIJxn+XE8w|BfKd=GVkUGtej5&x;6oEnicopF zep&?qG*zI~l}RETFy<P9rl%KUQy6UnkvGPm1!g(|k@^U1O_4|%72;8`lfXm~4j>Wb ziCb}4+e3tgfFFJl%w*|0K^4Lf=7RCug?AX!qGbgn0TBie4-yC$DF#f(;F}+4K|rbn z9fNR$maJ7FPJRReT)@i4&uq{K!Ci^3aqaz|>5r)YKxg4<=aDSyEte=B=Vl0>F;8*R zL6bt?=6QG^p!dSuC5z=hI*v!#`ALpFxzwdwF>9@$_joi80FQ7IE>yZ0bQl5WuW#;B zxyye$@yiKVCA_)z=3R;etMaeHE5(j+I)Ga6IQXkUJSK#erU<TM_=@O<s`nYFx3Dn% znTbcV8zO}eh`6fPk^eJz@vQ3I0`<NwsJH&c|GM@+u05cC_13T7DysJiDl`tspHvC{ zC&>1vkbG~!lOQ<%=g0=7=U>C*A|y+vhByvF+A#1;2LY;q`|3D>7*-L2Bv>E$0;2fE zWBb21P5<1WX|M_KQ2?_bSPVWTD1LLP!d>Xns#qEU<@)dz(ILf&coM;O$(W&-Be9!` zdHNQo(3e%nY7f#9u&xB)G58E!SP}uo55kq=yb0hjaD!;DS$vbk1ltEOey~A}*P<u* z1*EpA<EcW26bp`kic^ckQyj%1T@C6=BM;ocP(Okw#Hayq7K$hq=+Czm2R3zl&fh@V zJ4owLk+slO#SSWkfR1!|{ylgpU}wZ(zU(-4N{#PwYQ27`{)uA&*j@Mu^w)2o>;IvP z^7t}|l`E3FQ+7jWJng(n@B9|QRkb{jx%k1c^fB`8C8_q5T#GSUxOS~tKAh=WJ_^BC z&P}q0B{V<z3dXx3)9*>TO;J@tCJ4=1J|S1`1!T-QsD*T`zb-MyWab#ga}6(#uV9?f zig(l9Cc4`IAG^2o(Yrr;H_P3RJ?uKN*>z;2=8HP1>xA5OLh_xI@pr0#yZ8h5-hJo` zZu)|`j<x-N+xyF2Lc9NjynhGn-j4g-lB+E}mbsm8XuS6pgroTbs}<?7d}GUMTl$qp z5Ct{1)!4dn`{TCNHeBovW8fO3@acl5@u7#=gvfud+}^j|DYqYy+fPfLGqUH5NPb`y zPkrW&=w{%T9hN%=;k<GAi>q+T`}`0HMLwXoxOzpZ>w>R0(!*Qj4<47w?x-64ih?9# z1-^mK?CTI(1<+w#vsl*+xRQE5oEd)9+?E*zU@aR43=uFIum4_D+<Qd(N!~%(JD4#8 zJXRlAS=y`%igm%<#75)h!PDZw(~p=v*`bwNnbED5w$*F7(e;aKKg#zGtlwCBXJg-k zzAp|)y)Oes(s~v#FGvAUfiyGnxRqIriU&?>KdJSM+<GQ+Hgon-Lrb=Cvths3us=7u z(Y4uoO6)zAXWFxUD>v10uH^iH<uz}N0$%wev1L?h8I@Z`Gb3A1XWF#ca6oK0kh{Hc zc=OO{@z7}iZnO12dpGm$R%?%V5a7%OxphJGFJNH<x%T^mEAOfWPUQBj_pKe+n0UZ` z@ut`^Cbf*oEn`n95Ny7uGh3Ivn7x62xz6nE`)^9^eNgp)CSAn86>DbV!)hc9W_`K( z9E*SJ4Y}F1Rteh%!cIEE532!7N>`ErK1lNjB*0Dyt{%tLncg%$9(3YI!5HBh3MmyK z{BC$Lir21C=*A)&ExfUZLR@?*6ykBcsz%a|;uVgL{Kt@dR+vXH{)tCuh9nr<C430U zUF~n%<gz-pDNF)R>z-}OnD|dx@xzuK>4@npZGCQ=+L2y1EzwqpqSU2J=C^2T{WkTq zRGsxu(4bwhg0Ho3M;)bcouE_-Q;~%`y+VRbK%g%<slzqV?5}}D&5zoGOQag@B>xMz zg+Y%J<{*J4Ow-T>=sJ<AReyP^`Y!p)Q-0C-+qRvy(IE4a)33<$-|zC4$nyUI4RpBa literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed2b0f6f101965fb42fe059ec79e8084a4b3a9bf GIT binary patch literal 2413 zcmc&$&2HO95GE<=$Exk5b`J%5Sp;rf0g2e4$i-+38*SqTXoVt4f!2mWued9jDYYx_ zE*;y*EqR6B+hbmdKu>*(o;ow6D5(mJ-ns_IoZZ>knc4Y1N^fj*Js9Ekr}DS9=lzAs z;%I<!0FPxLjy&NB|1CUkf@9PI(EzOhnlHlVUay&e)zSz+JAlXTfRG;8dB=h9j~gO5 z4n;$RZ@uHDXo?p6Z;3Ye=oHPTYMML#C+zJq7>6v$xV6k_CgdnplDTuqa+OHqc&b>6 z=4{FhpGYT-?RU#<&Y5(WJ84OMP!Cdn;AWgEo>{iX^zbFk;bF6RoRo>PefC^Rc1CB| z{%rNEPaB?TE7dUL&ViSq)>-Z5>4?E%z3L2CcBIXOyHrEOmKk}Gr$!0}vy_jJQ>lbh zuFR+Qw364iS9~(fma`)3S#XvmT(P07swEh=a7vcxSE(BBmBrcL-)B^2+vh^WlUX%B z?~$v8<=X4X7pHv%C1#J=?$7bV-CGSsYF+HEr(~V06m!3Q$2?Cs;N-!h`|Qza87tHh zF5E~go6;=NlL^#NaK~|mU-B&F!%W_%GM3Fii&YiI>7`T@?Eg>)3MZy;9+wwO3Wf6` z@c|UGf$xZxui>$GL5#iEUJO_R38(>N1cN8NpjfLfr0CB3@10+SR%WAjo@v3}zki7) z%0)@^lLbIT=2v~5opWxZZ*-DRpvi1>l)CToVe|yr;z#bzqanYR7HcVtzKU#aj2?3* z<B1kBvrz?r>2=YG<5Z<Cj_+ZlA&8dW^=~$*o%*xImE4d?D7P(mdF{RQe)nDQ#{0wf zAxF&a=7Oq%AUqTTE|w|z>fd-o5<v8q*IZ(>!aHt!CS7h+33${i%-4<wTFC|TL9b!3 z=0%H75q(8xR$PO5Q7KCS+~^e>OHla?rY!E>TD#dUlV4gN^x9Y}giIV4-54vGXZXGz z#}_%zs+D#e3!T99-Koy5<3!8R$i}0Lk4*=I_y7f7>Vm*<40a5LX_3M^Ug(FPbb|Ge z<`bA&8W`vSJoaM{%S4PM4rELOZqOJ12&}1QhpOU1K%GLe1qPw|+o?>_QJN5+S*8i1 ztfmoSHOZ6nIZczl8sz_pqls<ym<1kJ<M|yT2UQ2o{jnF&74UiBc?Jw>+1c*SRs3*g zw_@r!AKmH?&FG^6EZtvmiQQBAs}IKSM+Up<@V*CSB|M;HZH%;2tpt^@?Bd1a7_udu zS-V<HXW?w>{gPAm7&nGr*E<d`d72>^RsccbS<U0*w8~<li3@H^p)x7IcPpUAt|Cz1 zgBPMI_=!*w7RZ1otU)tjMPWBhx|d$F2=RK0wfbg??!2f)cb;U?u3~r}CJ7=(a5#aW z<(GdzM<33RTr<+3*EH*3X*N)7qPT;CK=wX-Ar!uZ$KoR5YkiyGG3W(^F;W&lNj``u SI$xDo-$#fNMQ%2>qJID($9<0g literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43d077e6552c249ec0d115a4d34f47de65e354cc GIT binary patch literal 2860 zcmc&$&2Jk;6rXjxjbobhD~L8UFhW&>p|z+`IYcy4MWIwGIkZJWsmo@(Gj=wtcioxY zwuySkp@$rLMG+E6oPw%K{4E6`5v|0Df526G>WTN>?v9ffMcf$2&olGhym|9JelNdF zPSzQW_QtR3`*Ftp#zi@*#bkFLCR?n+t~1G=FzIYp7<&%id@SXh3UI~_a2#2^%^I#> zisG+REOy_6$re*=$&qZSBAul%Sy`&eu_tWFl~tfeqzk8yWbTcqpC;ljxUtS*T;+Z! zjNwVlrRoHc;>n8QY2+)Nh#=wtiu1nEqNft2O|zaKOA;Nl(?l6sUbKUjUkTj}A`u!s z&*Szg?crtRK5i;MF-?A3DZWg1m}bdcZqk8Uu~AVw6iEVF+Ho9OH8(mOn3kJp5t&Y` zdm;&9u-I^|?x%rPlEW^&N2<Pxq>7UKJyz4myFPy;di`+!t4O*u&TwBuysZjvNiGcB z5{B`^AnMNN&RJMk;N)i06jFM<(i`tLNYx&;)q3}%d(8-3%&+jdZ@f!$hYHHTBwn)C zC+Rc_@a>167`_uOxO?&P1%CNnZY%f_0<IOhEsD7x_j=$%DH4G@;(-VQ(GJxGa$}wh z#4Nnf4IZe7jQt<{K<0R4&Xqi{v><ct_+@QiiC}$=!MCWBE_=*8+@~QOSXpVwpiU}_ zUo<M&gbhztA7<k-C#xD2b_^cjuOELl-}>4>Wwi8n@k+QNglS!i{j>+!W?I*S<jb_( zYKt{x(3eujk6NlovR2w_>p*sumzWfyA0%lK>p+AD<V~t|+!cxPda+cYX%z+2U(0Hq z7eqngdFxY@am{j#fMBM9Y_Od(Z*NwgPVLOR3qQv;;j@eH-sd2MCvwm&m~4T2R#Ak; z&(<~N4*n+YaJ3E7=XSXb^3UxV2Otg|x_+O+LXaaRWEPLq!-If;D1`8n=UEOC1>oSp zTPjI)lp_wV3(&EO7vo6n5npVKX|yssBKlbVS*?tx26Se5{PYA$Ozx}G^;5Yo_idiX zBj<o@u)#?-G5K`r&)V$owb`Fmepvl+^|xB%k6PnJ`KR9i!NtZn#s|yV^Rl{!(Mv;| zAN9QZsR#?sxaY~(hwbD2I9&7mSamwa>x81Kv7hK;K%OyDN!Dr%6cLP?xdvpzeg>5p zw>Dr%K4GWNzNk(Qsuh<Hm?gCd_k#f&CHV!Y+lQ|mWh8e`!`8tT1C0fm48*spr+_V{ zZCi;7j0Z%Cu#o^dQfN(I`9UY}39Ai{34XYRNJ4BS{FPw~qVQS(`%nFckaV6K=uuI3 zm>!6)#f3wC{0<}>v_6rB&>ak4o;&x*yL4`@=t4uRJyaixQA30d)ErTXiCO5g7h`V> z;gmJ+CM-tGgLV^ZtxP|TB)KpzkiFM&>;!bDRkimyd+w&P%JFiZ3$4YPJ#qDc2tow< zqV^C}N8fSxUh#@vOz?Kt6AF>Mm+!+G3&uAoqX>R&x=DoQGUwo5Bv_$54T5b<P#VO; z3Mf_t+v_exui<7@OoD8}#xJW6U7yv5uE@p<OAmqq72o=a5;H8aUWfZk0|+4NG$QN7 z&Y9U9VBbN2-I+N{KW`!L=q7v$G;sBCIHgY@If>*H5-RaGafX<Y7dX}u71YNtF&BaC zE$|aq;7HE9?%4qwCAlV4ve>BPXh9nH-}1WlX%0vWdKN^{=VlqmV9arxLG42aP-2w4 Z#JyKT#<$KH2aFgcFLCeHzc9$Ue*o51>5l*a literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/inputs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0c91ff3182adb1245aa7f20656e8e94336a438c GIT binary patch literal 2474 zcmc&$&2HO95GM6w$!hGRO%DZnSp-I10g+lG@Wp5h8*UpIXoMn(fxxCgued9jF}b97 zmyRvu<~&9Z?J=*=Yu|!EPkoD?Iy0mwsS1qVy2g&Vf3rK^&iAeO+FHkfa{K!q;;`j7 ze_><3)S<Bl)i5y69N`G}J=ELUF}7-=4y`)0T+w*xbejRpS|~MW?LjpgV59@{oa35s zkL#j#+z@rqc<&rHMN_Q6{}s^!AMLz(sM5^xKVfZ$LD^?P#EoG#VM2~VC7C^!EK`Bh zmWPUkIGv?j^H^G`O}|qtvsQ=0%t}MeUR9|1oa=F@cx2cPONMW#4>z0kW2X$P>9dzo zvNPJl^rxd|eOmA$F;Wd9ZY_8jCP`GeIUF$<tVXTo%8U{na~mdbV#Bn&%t9>%gI<b9 z$W$sJl`Z0_JT1lb!!?i7XfZ09Jw2RZ0at7&OSA;z26l;}<ZY<NI|VqqySt2FHhnIH zA5YQvx=XI+hAXcp-=6jrK+K-9&DZ|c=A9EoXsmB<QktEq5M#f4#Vk(P;H0<xm~EdH zX9X<b!nH)$RKkKJjsZi#Eyo^y#iNi9Bl(zMERul+OBBZ8l~i=t{{aU&j!(yVT3jqO z=s2$e7f3NJ_>F8ifNCCq89VPBAGih<SOd(c4Swv_^401>^3E*(KDc?q$Y}Jz(JQd_ z?_Umfydwi-@U*;0wmgx=*>z!iF;GYYXcJ1t-biwrY1unG___D}(etC%Px{;5FbgBm z3u1mDJ)WkK7Y3;(!Sv#h2OQ*)mL`j=x!O91?75ISQ{Ir@NQ2iQbaL&POzULKt@PtW z$jEplhtiw8?fan$t?xg=U>jf@cg3BoQ%3fugG=zB7!f?5!N)u2jq|H(Yq!pCt_v_B zK$A-X7J0lc1mp%&^6kGVjXHt?Qe;X&^HMT!;R^|9s6sQaUCKt~c#tSLH+|5pYrM96 z1z-XK=k4kJXpD<)qc9+^PQJFlwy&Ve;A&@e@~{YgVSLbSAy&vb-_JWfBAG?_eb4tV zGai*AE#DVO0NoGLB)ai~M2<$rA4Pnu+u&S(f(G+q&fsx0CLJEr;Iy{e__9%JH>fv& zj)j89+=FVq0JEs%_zHlU(+i;SJ>j3jY(i{bl|l-%RjAe=L4>|ZWe|?SfO62VggDMB z9U@tjJUE}}Jo&3s;y;Nz$<+=s@DQl+>;_T9$_;1!*el2hcwabVHR{UQ=Ek+ZwXs=B z{Y=pA^oP^v)d89BFS*3rDg9L&;{z1Is_J+@L1XE7py`PQ%B6`C1YwcG^V>0$TiUa7 zH6PC0-jw-;DD5z=HNUA=>|gOPLNzVvfy%WU$H{3KMV!R&V%-@+Ii+|omne-{MU;L7 zAEb5g8>3J>ur<=aI`uS44V*OTUb@Y^f!CX_RyUJ(W}xPsS&(_FJj2HrNd$QYn;ZHe z1Ts|oO+KCSxYDCRx2f;JOudF?9nF0-M6r*t3q3x8N(u+;dPw9LbZf*gYRnOmJdjAV PzbkmYOVmV&*1!1&Ix?AS literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/loss_function.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1e26394365e683dbec6da95fbe223ebcee10ef4 GIT binary patch literal 13488 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 Bp;Z6? literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ebbfad9c34b1f9e6c819ea7cf7852af65591444 GIT binary patch literal 42392 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 J{$pjC|2Gc|fYty2 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff5e3935b0dd191141f8dfb60bedbeb9a3441d01 GIT binary patch literal 87304 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 VVvQP|=-}`ZcKvS-xy!oPe*=NpfUp1n literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/meta_model_engine.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd6eb8fcd459fd95ff1b85514f996344b6e4880c GIT binary patch literal 42705 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 X0Qd@E+a(_g`Az8O{>jTCN=^RXpccWy literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..543416416ef052c2402c2e9a97976dc4aab22866 GIT binary patch literal 8915 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 StX4>a*409eT+%Xuv;M!r+lnOs literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2b6e8e274e98df5f28013ef45589d246125aff5 GIT binary patch literal 14832 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/orthogonal_matching_pursuit.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f1ec9479869fec42f363e7f46e07dba2f1c6be5 GIT binary patch literal 8930 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 H7PS8b3n7jV literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97ed55acc1e800a138ddf489ccea709a8b28f634 GIT binary patch literal 11629 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 avA&6Yk^<6Wno`U`AM%$xPx3uy*Z&u-bVhUl literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0784caa91ce5a8acf65a6e83b8f58a47f8e12bcb GIT binary patch literal 19787 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 M>^HBe!Eo^Z0iAV!9smFU literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_ard.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0843cdf8bd820d9cccfdcde3a1193f3f416ccc10 GIT binary patch literal 11717 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 Zi*F}O^<C;cm`0%G$mvY}IHnd?{}%}UP3r&v literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30079dce4bc04802324f720381b872c1a2f64018 GIT binary patch literal 9509 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 X4&uxQi9kPt=A@8#$;cEg3d(;2)UokG literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..489534282f927e599530fd2c176b5240e2214e1d GIT binary patch literal 19040 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 RV>v$k20#DP38fgR{|_UFGxGod literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/reg_fast_laplace.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a3bbc05003eab405d52a934e83053ae50080d25 GIT binary patch literal 9581 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/sequential_design.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af35ff42f1ea1e8ee19d476f7b51c19199513cde GIT binary patch literal 87535 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 E|3L9E)c^nh literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b856dfef2c2658af8ecc6b1ab85b99c499a39705 GIT binary patch literal 35103 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 RfEonip2Lr$Q;xp){{<f=hrs{< literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d6f35b0e889d838247709ac2440fed2799abfce GIT binary patch literal 61708 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 literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/__pycache__/surrogate_models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f44a774b4165e6ff769d8db2f2c13c4dd0cbe8b3 GIT binary patch literal 35188 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 X?l%ZtK(YD%eZCe!@XRZi#_|6P0+p{e literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/adaptPlot.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/adaptPlot.py new file mode 100644 index 000000000..102f0373c --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/adaptPlot.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 13 13:46:24 2020 + +@author: farid +""" +import os +from sklearn.metrics import mean_squared_error, r2_score +from itertools import cycle +from matplotlib.backends.backend_pdf import PdfPages +import matplotlib.pyplot as plt + + +def adaptPlot(PCEModel, Y_Val, Y_PC_Val, Y_PC_Val_std, x_values=[], + plotED=False, SaveFig=True): + + NrofSamples = PCEModel.ExpDesign.n_new_samples + initNSamples = PCEModel.ExpDesign.n_init_samples + itrNr = 1 + (PCEModel.ExpDesign.X.shape[0] - initNSamples)//NrofSamples + + oldEDY = PCEModel.ExpDesign.Y + + if SaveFig: + newpath = 'adaptivePlots' + os.makedirs(newpath, exist_ok=True) + + # create a PdfPages object + pdf = PdfPages(f'./{newpath}/Model_vs_PCEModel_itr_{itrNr}.pdf') + + # List of markers and colors + color = cycle((['b', 'g', 'r', 'y', 'k'])) + marker = cycle(('x', 'd', '+', 'o', '*')) + + OutNames = list(Y_Val.keys()) + x_axis = 'Time [s]' + + if len(OutNames) == 1: + OutNames.insert(0, x_axis) + try: + x_values = Y_Val['x_values'] + except KeyError: + x_values = x_values + + fig = plt.figure(figsize=(24, 16)) + + # Plot the model vs PCE model + for keyIdx, key in enumerate(PCEModel.ModelObj.Output.names): + Y_PC_Val_ = Y_PC_Val[key] + Y_PC_Val_std_ = Y_PC_Val_std[key] + Y_Val_ = Y_Val[key] + if Y_Val_.ndim == 1: + Y_Val_ = Y_Val_.reshape(1, -1) + old_EDY = oldEDY[key] + if isinstance(x_values, dict): + x = x_values[key] + else: + x = x_values + + for idx, y in enumerate(Y_Val_): + Color = next(color) + Marker = next(marker) + + plt.plot( + x, y, color=Color, marker=Marker, + lw=2.0, label='$Y_{%s}^{M}$'%(idx+itrNr) + ) + + plt.plot( + x, Y_PC_Val_[idx], color=Color, marker=Marker, + lw=2.0, linestyle='--', label='$Y_{%s}^{PCE}$'%(idx+itrNr) + ) + plt.fill_between( + x, Y_PC_Val_[idx]-1.96*Y_PC_Val_std_[idx], + Y_PC_Val_[idx]+1.96*Y_PC_Val_std_[idx], color=Color, + alpha=0.15 + ) + + if plotED: + for output in old_EDY: + plt.plot(x, output, color='grey', alpha=0.1) + + # Calculate the RMSE + RMSE = mean_squared_error(Y_PC_Val_, Y_Val_, squared=False) + R2 = r2_score(Y_PC_Val_.reshape(-1, 1), Y_Val_.reshape(-1, 1)) + + plt.ylabel(key) + plt.xlabel(x_axis) + plt.title(key) + + ax = fig.axes[0] + ax.legend(loc='best', frameon=True) + fig.canvas.draw() + ax.text(0.65, 0.85, + f'RMSE = {round(RMSE, 3)}\n$R^2$ = {round(R2, 3)}', + transform=ax.transAxes, color='black', + bbox=dict(facecolor='none', + edgecolor='black', + boxstyle='round,pad=1') + ) + plt.grid() + + if SaveFig: + # save the current figure + pdf.savefig(fig, bbox_inches='tight') + + # Destroy the current plot + plt.clf() + pdf.close() diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/apoly_construction.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/apoly_construction.py new file mode 100644 index 000000000..40830fe8a --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/apoly_construction.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import numpy as np + + +def apoly_construction(Data, degree): + """ + Construction of Data-driven Orthonormal Polynomial Basis + Author: Dr.-Ing. habil. Sergey Oladyshkin + Department of Stochastic Simulation and Safety Research for Hydrosystems + Institute for Modelling Hydraulic and Environmental Systems + Universitaet Stuttgart, Pfaffenwaldring 5a, 70569 Stuttgart + E-mail: Sergey.Oladyshkin@iws.uni-stuttgart.de + http://www.iws-ls3.uni-stuttgart.de + The current script is based on definition of arbitrary polynomial chaos + expansion (aPC), which is presented in the following manuscript: + Oladyshkin, S. and W. Nowak. Data-driven uncertainty quantification using + the arbitrary polynomial chaos expansion. Reliability Engineering & System + Safety, Elsevier, V. 106, P. 179-190, 2012. + DOI: 10.1016/j.ress.2012.05.002. + + Parameters + ---------- + Data : array + Raw data. + degree : int + Maximum polynomial degree. + + Returns + ------- + Polynomial : array + The coefficients of the univariate orthonormal polynomials. + + """ + if Data.ndim !=1: + raise AttributeError('Data should be a 1D array') + + # Initialization + dd = degree + 1 + nsamples = len(Data) + + # Forward linear transformation (Avoiding numerical issues) + MeanOfData = np.mean(Data) + Data = Data/MeanOfData + + # Compute raw moments of input data + raw_moments = [np.sum(np.power(Data, p))/nsamples for p in range(2*dd+2)] + + # Main Loop for Polynomial with degree up to dd + PolyCoeff_NonNorm = np.empty((0, 1)) + Polynomial = np.zeros((dd+1, dd+1)) + + for degree in range(dd+1): + Mm = np.zeros((degree+1, degree+1)) + Vc = np.zeros((degree+1)) + + # Define Moments Matrix Mm + for i in range(degree+1): + for j in range(degree+1): + if (i < degree): + Mm[i, j] = raw_moments[i+j] + + elif (i == degree) and (j == degree): + Mm[i, j] = 1 + + # Numerical Optimization for Matrix Solver + Mm[i] = Mm[i] / max(abs(Mm[i])) + + # Defenition of Right Hand side ortogonality conditions: Vc + for i in range(degree+1): + Vc[i] = 1 if i == degree else 0 + + # Solution: Coefficients of Non-Normal Orthogonal Polynomial: Vp Eq.(4) + try: + Vp = np.linalg.solve(Mm, Vc) + except: + inv_Mm = np.linalg.pinv(Mm) + Vp = np.dot(inv_Mm, Vc.T) + + if degree == 0: + PolyCoeff_NonNorm = np.append(PolyCoeff_NonNorm, Vp) + + if degree != 0: + if degree == 1: + zero = [0] + else: + zero = np.zeros((degree, 1)) + PolyCoeff_NonNorm = np.hstack((PolyCoeff_NonNorm, zero)) + + PolyCoeff_NonNorm = np.vstack((PolyCoeff_NonNorm, Vp)) + + if 100*abs(sum(abs(np.dot(Mm, Vp)) - abs(Vc))) > 0.5: + print('\n---> Attention: Computational Error too high !') + print('\n---> Problem: Convergence of Linear Solver') + + # Original Numerical Normalization of Coefficients with Norm and + # orthonormal Basis computation Matrix Storrage + # Note: Polynomial(i,j) correspont to coefficient number "j-1" + # of polynomial degree "i-1" + P_norm = 0 + for i in range(nsamples): + Poly = 0 + for k in range(degree+1): + if degree == 0: + Poly += PolyCoeff_NonNorm[k] * (Data[i]**k) + else: + Poly += PolyCoeff_NonNorm[degree, k] * (Data[i]**k) + + P_norm += Poly**2 / nsamples + + P_norm = np.sqrt(P_norm) + + for k in range(degree+1): + if degree == 0: + Polynomial[degree, k] = PolyCoeff_NonNorm[k]/P_norm + else: + Polynomial[degree, k] = PolyCoeff_NonNorm[degree, k]/P_norm + + # Backward linear transformation to the real data space + Data *= MeanOfData + for k in range(len(Polynomial)): + Polynomial[:, k] = Polynomial[:, k] / (MeanOfData**(k)) + + return Polynomial diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/bayes_linear.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/bayes_linear.py new file mode 100644 index 000000000..3bd827ac0 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/bayes_linear.py @@ -0,0 +1,523 @@ +import numpy as np +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +from sklearn.utils import check_X_y, check_array, as_float_array +from sklearn.utils.validation import check_is_fitted +from scipy.linalg import svd +import warnings +from sklearn.preprocessing import normalize as f_normalize + + + +class BayesianLinearRegression(RegressorMixin,LinearModel): + ''' + Superclass for Empirical Bayes and Variational Bayes implementations of + Bayesian Linear Regression Model + ''' + def __init__(self, n_iter, tol, fit_intercept,copy_X, verbose): + self.n_iter = n_iter + self.fit_intercept = fit_intercept + self.copy_X = copy_X + self.verbose = verbose + self.tol = tol + + + def _check_convergence(self, mu, mu_old): + ''' + Checks convergence of algorithm using changes in mean of posterior + distribution of weights + ''' + return np.sum(abs(mu-mu_old)>self.tol) == 0 + + + def _center_data(self,X,y): + ''' Centers data''' + X = as_float_array(X,copy = self.copy_X) + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype = X.dtype) + if self.fit_intercept: + X_mean = np.average(X,axis = 0) + y_mean = np.average(y,axis = 0) + X -= X_mean + y = y - y_mean + else: + X_mean = np.zeros(X.shape[1],dtype = X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X,y, X_mean, y_mean, X_std + + + def predict_dist(self,X): + ''' + Calculates mean and variance of predictive distribution for each data + point of test set.(Note predictive distribution for each data point is + Gaussian, therefore it is uniquely determined by mean and variance) + + Parameters + ---------- + x: array-like of size (n_test_samples, n_features) + Set of features for which corresponding responses should be predicted + + Returns + ------- + :list of two numpy arrays [mu_pred, var_pred] + + mu_pred : numpy array of size (n_test_samples,) + Mean of predictive distribution + + var_pred: numpy array of size (n_test_samples,) + Variance of predictive distribution + ''' + # Note check_array and check_is_fitted are done within self._decision_function(X) + mu_pred = self._decision_function(X) + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + return [mu_pred,var_pred] + + + + +class EBLinearRegression(BayesianLinearRegression): + ''' + Bayesian Regression with type II maximum likelihood (Empirical Bayes) + + Parameters: + ----------- + n_iter: int, optional (DEFAULT = 300) + Maximum number of iterations + + tol: float, optional (DEFAULT = 1e-3) + Threshold for convergence + + optimizer: str, optional (DEFAULT = 'fp') + Method for optimization , either Expectation Maximization or + Fixed Point Gull-MacKay {'em','fp'}. Fixed point iterations are + faster, but can be numerically unstable (especially in case of near perfect fit). + + fit_intercept: bool, optional (DEFAULT = True) + If True includes bias term in model + + perfect_fit_tol: float (DEAFAULT = 1e-5) + Prevents overflow of precision parameters (this is smallest value RSS can have). + ( !!! Note if using EM instead of fixed-point, try smaller values + of perfect_fit_tol, for better estimates of variance of predictive distribution ) + + alpha: float (DEFAULT = 1) + Initial value of precision paramter for coefficients ( by default we define + very broad distribution ) + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied, otherwise will be + + verbose: bool, optional (Default = False) + If True at each iteration progress report is printed out + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + intercept_: float + Value of bias term (if fit_intercept is False, then intercept_ = 0) + + alpha_ : float + Estimated precision of coefficients + + beta_ : float + Estimated precision of noise + + eigvals_ : array, shape = (n_features, ) + Eigenvalues of covariance matrix (from posterior distribution of weights) + + eigvecs_ : array, shape = (n_features, n_featues) + Eigenvectors of covariance matrix (from posterior distribution of weights) + + ''' + + def __init__(self,n_iter = 300, tol = 1e-3, optimizer = 'fp', fit_intercept = True, + normalize=True, perfect_fit_tol = 1e-6, alpha = 1, copy_X = True, verbose = False): + super(EBLinearRegression,self).__init__(n_iter, tol, fit_intercept, copy_X, verbose) + if optimizer not in ['em','fp']: + raise ValueError('Optimizer can be either "em" or "fp" ') + self.optimizer = optimizer + self.alpha = alpha + self.perfect_fit = False + self.normalize = True + self.scores_ = [np.NINF] + self.perfect_fit_tol = perfect_fit_tol + + def _check_convergence(self, mu, mu_old): + ''' + Checks convergence of algorithm using changes in mean of posterior + distribution of weights + ''' + return np.sum(abs(mu-mu_old)>self.tol) == 0 + + + def _center_data(self,X,y): + ''' Centers data''' + X = as_float_array(X,copy = self.copy_X) + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype = X.dtype) + if self.fit_intercept: + X_mean = np.average(X, axis=0) + X -= X_mean + if self.normalize: + X, X_std = f_normalize(X, axis=0, copy=False, + return_norm=True) + else: + X_std = np.ones(X.shape[1], dtype=X.dtype) + y_mean = np.average(y, axis=0) + y = y - y_mean + else: + X_mean = np.zeros(X.shape[1],dtype = X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X,y, X_mean, y_mean, X_std + + def fit(self, X, y): + ''' + Fits Bayesian Linear Regression using Empirical Bayes + + Parameters + ---------- + X: array-like of size [n_samples,n_features] + Matrix of explanatory variables (should not include bias term) + + y: array-like of size [n_features] + Vector of dependent variables. + + Returns + ------- + object: self + self + + ''' + # preprocess data + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # precision of noise & and coefficients + alpha = self.alpha + var_y = np.var(y) + # check that variance is non zero !!! + if var_y == 0 : + beta = 1e-2 + else: + beta = 1. / np.var(y) + + # to speed all further computations save svd decomposition and reuse it later + u,d,vt = svd(X, full_matrices = False) + Uy = np.dot(u.T,y) + dsq = d**2 + mu = 0 + + for i in range(self.n_iter): + + # find mean for posterior of w ( for EM this is E-step) + mu_old = mu + if n_samples > n_features: + mu = vt.T * d/(dsq+alpha/beta) + else: + # clever use of SVD here , faster for large n_features + mu = u * 1./(dsq + alpha/beta) + mu = np.dot(X.T,mu) + mu = np.dot(mu,Uy) + + # precompute errors, since both methods use it in estimation + error = y - np.dot(X,mu) + sqdErr = np.sum(error**2) + + if sqdErr / n_samples < self.perfect_fit_tol: + self.perfect_fit = True + warnings.warn( ('Almost perfect fit!!! Estimated values of variance ' + 'for predictive distribution are computed using only RSS')) + break + + if self.optimizer == "fp": + gamma = np.sum(beta*dsq/(beta*dsq + alpha)) + # use updated mu and gamma parameters to update alpha and beta + # !!! made computation numerically stable for perfect fit case + alpha = gamma / (np.sum(mu**2) + np.finfo(np.float32).eps ) + beta = ( n_samples - gamma ) / (sqdErr + np.finfo(np.float32).eps ) + else: + # M-step, update parameters alpha and beta to maximize ML TYPE II + eigvals = 1. / (beta * dsq + alpha) + alpha = n_features / ( np.sum(mu**2) + np.sum(1/eigvals) ) + beta = n_samples / ( sqdErr + np.sum(dsq/eigvals) ) + + # if converged or exceeded maximum number of iterations => terminate + converged = self._check_convergence(mu_old,mu) + if self.verbose: + print( "Iteration {0} completed".format(i) ) + if converged is True: + print("Algorithm converged after {0} iterations".format(i)) + if converged or i==self.n_iter -1: + break + eigvals = 1./(beta * dsq + alpha) + self.coef_ = beta*np.dot(vt.T*d*eigvals ,Uy) + self._set_intercept(X_mean,y_mean,X_std) + self.beta_ = beta + self.alpha_ = alpha + self.eigvals_ = eigvals + self.eigvecs_ = vt.T + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self,X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of predictive + distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + ''' + y_hat = np.dot(X,self.coef_) + self.intercept_ + + if return_std: + if self.normalize: + X = (X - self._x_mean_) / self._x_std + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + std_hat = np.sqrt(var_pred) + return y_hat, std_hat + else: + return y_hat + + +# ============================== VBLR ========================================= + +def gamma_mean(a,b): + ''' + Computes mean of gamma distribution + + Parameters + ---------- + a: float + Shape parameter of Gamma distribution + + b: float + Rate parameter of Gamma distribution + + Returns + ------- + : float + Mean of Gamma distribution + ''' + return float(a) / b + + + +class VBLinearRegression(BayesianLinearRegression): + ''' + Implements Bayesian Linear Regression using mean-field approximation. + Assumes gamma prior on precision parameters of coefficients and noise. + + Parameters: + ----------- + n_iter: int, optional (DEFAULT = 100) + Maximum number of iterations for KL minimization + + tol: float, optional (DEFAULT = 1e-3) + Convergence threshold + + fit_intercept: bool, optional (DEFAULT = True) + If True will use bias term in model fitting + + a: float, optional (Default = 1e-4) + Shape parameter of Gamma prior for precision of coefficients + + b: float, optional (Default = 1e-4) + Rate parameter of Gamma prior for precision coefficients + + c: float, optional (Default = 1e-4) + Shape parameter of Gamma prior for precision of noise + + d: float, optional (Default = 1e-4) + Rate parameter of Gamma prior for precision of noise + + verbose: bool, optional (Default = False) + If True at each iteration progress report is printed out + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + intercept_: float + Value of bias term (if fit_intercept is False, then intercept_ = 0) + + alpha_ : float + Mean of precision of coefficients + + beta_ : float + Mean of precision of noise + + eigvals_ : array, shape = (n_features, ) + Eigenvalues of covariance matrix (from posterior distribution of weights) + + eigvecs_ : array, shape = (n_features, n_featues) + Eigenvectors of covariance matrix (from posterior distribution of weights) + + ''' + + def __init__(self, n_iter = 100, tol =1e-4, fit_intercept = True, + a = 1e-4, b = 1e-4, c = 1e-4, d = 1e-4, copy_X = True, + verbose = False): + super(VBLinearRegression,self).__init__(n_iter, tol, fit_intercept, copy_X, + verbose) + self.a,self.b = a, b + self.c,self.d = c, d + + + def fit(self,X,y): + ''' + Fits Variational Bayesian Linear Regression Model + + Parameters + ---------- + X: array-like of size [n_samples,n_features] + Matrix of explanatory variables (should not include bias term) + + Y: array-like of size [n_features] + Vector of dependent variables. + + Returns + ------- + object: self + self + ''' + # preprocess data + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # SVD decomposition, done once , reused at each iteration + u,D,vt = svd(X, full_matrices = False) + dsq = D**2 + UY = np.dot(u.T,y) + + # some parameters of Gamma distribution have closed form solution + a = self.a + 0.5 * n_features + c = self.c + 0.5 * n_samples + b,d = self.b, self.d + + # initial mean of posterior for coefficients + mu = 0 + + for i in range(self.n_iter): + + # update parameters of distribution Q(weights) + e_beta = gamma_mean(c,d) + e_alpha = gamma_mean(a,b) + mu_old = np.copy(mu) + mu,eigvals = self._posterior_weights(e_beta,e_alpha,UY,dsq,u,vt,D,X) + + # update parameters of distribution Q(precision of weights) + b = self.b + 0.5*( np.sum(mu**2) + np.sum(eigvals)) + + # update parameters of distribution Q(precision of likelihood) + sqderr = np.sum((y - np.dot(X,mu))**2) + xsx = np.sum(dsq*eigvals) + d = self.d + 0.5*(sqderr + xsx) + + # check convergence + converged = self._check_convergence(mu,mu_old) + if self.verbose is True: + print("Iteration {0} is completed".format(i)) + if converged is True: + print("Algorithm converged after {0} iterations".format(i)) + + # terminate if convergence or maximum number of iterations are achieved + if converged or i==(self.n_iter-1): + break + + # save necessary parameters + self.beta_ = gamma_mean(c,d) + self.alpha_ = gamma_mean(a,b) + self.coef_, self.eigvals_ = self._posterior_weights(self.beta_, self.alpha_, UY, + dsq, u, vt, D, X) + self._set_intercept(X_mean,y_mean,X_std) + self.eigvecs_ = vt.T + return self + + + def _posterior_weights(self, e_beta, e_alpha, UY, dsq, u, vt, d, X): + ''' + Calculates parameters of approximate posterior distribution + of weights + ''' + # eigenvalues of covariance matrix + sigma = 1./ (e_beta*dsq + e_alpha) + + # mean of approximate posterior distribution + n_samples, n_features = X.shape + if n_samples > n_features: + mu = vt.T * d/(dsq + e_alpha/e_beta)# + np.finfo(np.float64).eps) + else: + mu = u * 1./(dsq + e_alpha/e_beta)# + np.finfo(np.float64).eps) + mu = np.dot(X.T,mu) + mu = np.dot(mu,UY) + return mu,sigma + + def predict(self,X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of predictive + distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + ''' + x = (X - self._x_mean_) / self._x_std + y_hat = np.dot(x,self.coef_) + self._y_mean + + if return_std: + data_noise = 1./self.beta_ + model_noise = np.sum(np.dot(X,self.eigvecs_)**2 * self.eigvals_,1) + var_pred = data_noise + model_noise + std_hat = np.sqrt(var_pred) + return y_hat, std_hat + else: + return y_hat \ No newline at end of file diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/engine.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/engine.py new file mode 100644 index 000000000..7f5c1bf77 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/engine.py @@ -0,0 +1,2195 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Dec 16 10:16:50 2023 +Engine to train the surrogate with + +@author: Rebecca Kohlhaas +""" +import copy +from copy import deepcopy, copy +import h5py +import joblib +import numpy as np +import os + +from scipy import stats, signal, linalg, sparse +from scipy.spatial import distance +from tqdm import tqdm +import scipy.optimize as opt +from sklearn.metrics import mean_squared_error +import multiprocessing +import matplotlib.pyplot as plt +import sys +import seaborn as sns +from joblib import Parallel, delayed +from .exploration import Exploration +import pathlib + +#from .inputs import Input +#from .exp_designs import ExpDesigns +#from .surrogate_models import MetaModel +#from bayesvalidrox.post_processing.post_processing import PostProcessing + +def hellinger_distance(P, Q): + """ + Hellinger distance between two continuous distributions. + + The maximum distance 1 is achieved when P assigns probability zero to + every set to which Q assigns a positive probability, and vice versa. + 0 (identical) and 1 (maximally different) + + Parameters + ---------- + P : array + Reference likelihood. + Q : array + Estimated likelihood. + + Returns + ------- + float + Hellinger distance of two distributions. + + """ + P = np.array(P) + Q= np.array(Q) + + mu1 = P.mean() + Sigma1 = np.std(P) + + mu2 = Q.mean() + Sigma2 = np.std(Q) + + term1 = np.sqrt(2*Sigma1*Sigma2 / (Sigma1**2 + Sigma2**2)) + + term2 = np.exp(-.25 * (mu1 - mu2)**2 / (Sigma1**2 + Sigma2**2)) + + H_squared = 1 - term1 * term2 + + return np.sqrt(H_squared) + + +def logpdf(x, mean, cov): + """ + Computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = linalg.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(linalg.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + + return log_lik + +def subdomain(Bounds, n_new_samples): + """ + Divides a domain defined by Bounds into sub domains. + + Parameters + ---------- + Bounds : list of tuples + List of lower and upper bounds. + n_new_samples : int + Number of samples to divide the domain for. + n_params : int + The number of params to build the subdomains for + + Returns + ------- + Subdomains : List of tuples of tuples + Each tuple of tuples divides one set of bounds into n_new_samples parts. + + """ + n_params = len(Bounds) + n_subdomains = n_new_samples + 1 + LinSpace = np.zeros((n_params, n_subdomains)) + + for i in range(n_params): + LinSpace[i] = np.linspace(start=Bounds[i][0], stop=Bounds[i][1], + num=n_subdomains) + Subdomains = [] + for k in range(n_subdomains-1): + mylist = [] + for i in range(n_params): + mylist.append((LinSpace[i, k+0], LinSpace[i, k+1])) + Subdomains.append(tuple(mylist)) + + return Subdomains + +class Engine(): + + + def __init__(self, MetaMod, Model, ExpDes): + self.MetaModel = MetaMod + self.Model = Model + self.ExpDesign = ExpDes + self.parallel = False + + def start_engine(self) -> None: + """ + Do all the preparations that need to be run before the actual training + + Returns + ------- + None + + """ + self.out_names = self.Model.Output.names + self.MetaModel.out_names = self.out_names + + + def train_normal(self, parallel = False, verbose = False, save = False) -> None: + """ + Trains surrogate on static samples only. + Samples are taken from the experimental design and the specified + model is run on them. + Alternatively the samples can be read in from a provided hdf5 file. + + + Returns + ------- + None + + """ + + ExpDesign = self.ExpDesign + MetaModel = self.MetaModel + + # Read ExpDesign (training and targets) from the provided hdf5 + if ExpDesign.hdf5_file is not None: + # TODO: need to run 'generate_ED' as well after this or not? + ExpDesign.read_from_file(self.out_names) + else: + # Check if an old hdf5 file exists: if yes, rename it + hdf5file = f'ExpDesign_{self.Model.name}.hdf5' + if os.path.exists(hdf5file): + # os.rename(hdf5file, 'old_'+hdf5file) + file = pathlib.Path(hdf5file) + file.unlink() + + # Prepare X samples + # For training the surrogate use ExpDesign.X_tr, ExpDesign.X is for the model to run on + ExpDesign.generate_ED(ExpDesign.n_init_samples, + transform=True, + max_pce_deg=np.max(MetaModel.pce_deg)) + + # Run simulations at X + if not hasattr(ExpDesign, 'Y') or ExpDesign.Y is None: + print('\n Now the forward model needs to be run!\n') + ED_Y, up_ED_X = self.Model.run_model_parallel(ExpDesign.X, mp = parallel) + ExpDesign.Y = ED_Y + else: + # Check if a dict has been passed. + if not type(ExpDesign.Y) is dict: + raise Exception('Please provide either a dictionary or a hdf5' + 'file to ExpDesign.hdf5_file argument.') + + # Separate output dict and x-values + if 'x_values' in ExpDesign.Y: + ExpDesign.x_values = ExpDesign.Y['x_values'] + del ExpDesign.Y['x_values'] + else: + print('No x_values are given, this might lead to issues during PostProcessing') + + + # Fit the surrogate + MetaModel.fit(ExpDesign.X_tr, ExpDesign.Y, parallel, verbose) + + # Save what there is to save + if save: + # Save surrogate + with open(f'surrogates/surrogate_{self.Model.name}.pk1', 'wb') as output: + joblib.dump(MetaModel, output, 2) + + # Zip the model run directories + if self.Model.link_type.lower() == 'pylink' and\ + self.ExpDesign.sampling_method.lower() != 'user': + self.Model.zip_subdirs(self.Model.name, f'{self.Model.name}_') + + + def train_sequential(self, parallel = False, verbose = False) -> None: + """ + Train the surrogate in a sequential manner. + First build and train evereything on the static samples, then iterate + choosing more samples and refitting the surrogate on them. + + Returns + ------- + None + + """ + #self.train_normal(parallel, verbose) + self.parallel = parallel + self.train_seq_design(parallel, verbose) + + + # ------------------------------------------------------------------------- + def eval_metamodel(self, samples=None, nsamples=None, + sampling_method='random', return_samples=False): + """ + Evaluates meta-model at the requested samples. One can also generate + nsamples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate meta-model at. The default is None. + nsamples : int, optional + Number of samples to generate, if no `samples` is provided. The + default is None. + sampling_method : str, optional + Type of sampling, if no `samples` is provided. The default is + 'random'. + return_samples : bool, optional + Retun samples, if no `samples` is provided. The default is False. + + Returns + ------- + mean_pred : dict + Mean of the predictions. + std_pred : dict + Standard deviatioon of the predictions. + """ + # Generate or transform (if need be) samples + if samples is None: + # Generate + samples = self.ExpDesign.generate_samples( + nsamples, + sampling_method + ) + + # Transformation to other space is to be done in the MetaModel + # TODO: sort the transformations better + mean_pred, std_pred = self.MetaModel.eval_metamodel(samples) + + if return_samples: + return mean_pred, std_pred, samples + else: + return mean_pred, std_pred + + + # ------------------------------------------------------------------------- + def train_seq_design(self, parallel = False, verbose = False): + """ + Starts the adaptive sequential design for refining the surrogate model + by selecting training points in a sequential manner. + + Returns + ------- + MetaModel : object + Meta model object. + + """ + self.parallel = parallel + + # Initialization + self.SeqModifiedLOO = {} + self.seqValidError = {} + self.SeqBME = {} + self.SeqKLD = {} + self.SeqDistHellinger = {} + self.seqRMSEMean = {} + self.seqRMSEStd = {} + self.seqMinDist = [] + + if not hasattr(self.MetaModel, 'valid_samples'): + self.ExpDesign.valid_samples = [] + self.ExpDesign.valid_model_runs = [] + self.valid_likelihoods = [] + + validError = None + + + # Determine the metamodel type + if self.MetaModel.meta_model_type.lower() != 'gpe': + pce = True + else: + pce = False + mc_ref = True if bool(self.Model.mc_reference) else False + if mc_ref: + self.Model.read_observation('mc_ref') + + # Get the parameters + max_n_samples = self.ExpDesign.n_max_samples + mod_LOO_threshold = self.ExpDesign.mod_LOO_threshold + n_canddidate = self.ExpDesign.n_canddidate + post_snapshot = self.ExpDesign.post_snapshot + n_replication = self.ExpDesign.n_replication + util_func = self.ExpDesign.util_func + output_name = self.out_names + + # Handle if only one UtilityFunctions is provided + if not isinstance(util_func, list): + util_func = [self.ExpDesign.util_func] + + # Read observations or MCReference + # TODO: recheck the logic in this if statement + if (len(self.Model.observations) != 0 or self.Model.meas_file is not None) and hasattr(self.MetaModel, 'Discrepancy'): + self.observations = self.Model.read_observation() + obs_data = self.observations + else: + obs_data = [] + # TODO: TotalSigma2 not defined if not in this else??? + # TODO: no self.observations if in here + TotalSigma2 = {} + + # ---------- Initial self.MetaModel ---------- + self.train_normal(parallel = parallel, verbose=verbose) + + initMetaModel = deepcopy(self.MetaModel) + + # Validation error if validation set is provided. + if self.ExpDesign.valid_model_runs: + init_rmse, init_valid_error = self._validError(initMetaModel) + init_valid_error = list(init_valid_error.values()) + else: + init_rmse = None + + # Check if discrepancy is provided + if len(obs_data) != 0 and hasattr(self.MetaModel, 'Discrepancy'): + TotalSigma2 = self.MetaModel.Discrepancy.parameters + + # Calculate the initial BME + out = self._BME_Calculator( + obs_data, TotalSigma2, init_rmse) + init_BME, init_KLD, init_post, init_likes, init_dist_hellinger = out + print(f"\nInitial BME: {init_BME:.2f}") + print(f"Initial KLD: {init_KLD:.2f}") + + # Posterior snapshot (initial) + if post_snapshot: + parNames = self.ExpDesign.par_names + print('Posterior snapshot (initial) is being plotted...') + self.__posteriorPlot(init_post, parNames, 'SeqPosterior_init') + + # Check the convergence of the Mean & Std + if mc_ref and pce: + init_rmse_mean, init_rmse_std = self._error_Mean_Std() + print(f"Initial Mean and Std error: {init_rmse_mean:.2f}," + f" {init_rmse_std:.2f}") + + # Read the initial experimental design + Xinit = self.ExpDesign.X + init_n_samples = len(self.ExpDesign.X) + initYprev = self.ExpDesign.Y#initMetaModel.ModelOutputDict + #self.MetaModel.ModelOutputDict = self.ExpDesign.Y + initLCerror = initMetaModel.LCerror + n_itrs = max_n_samples - init_n_samples + + ## Get some initial statistics + # Read the initial ModifiedLOO + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = self.ExpDesign.Y[out_name] + Scores_all.append(list( + self.MetaModel.score_dict['b_1'][out_name].values())) + if self.MetaModel.dim_red_method.lower() == 'pca': + pca = self.MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + + Scores = [item for sublist in Scores_all for item in sublist] + weights = [item for sublist in varExpDesignY for item in sublist] + init_mod_LOO = [np.average([1-score for score in Scores], + weights=weights)] + + prevMetaModel_dict = {} + #prevExpDesign_dict = {} + # Can run sequential design multiple times for comparison + for repIdx in range(n_replication): + print(f'\n>>>> Replication: {repIdx+1}<<<<') + + # util_func: the function to use inside the type of exploitation + for util_f in util_func: + print(f'\n>>>> Utility Function: {util_f} <<<<') + # To avoid changes ub original aPCE object + self.ExpDesign.X = Xinit + self.ExpDesign.Y = initYprev + self.ExpDesign.LCerror = initLCerror + + # Set the experimental design + Xprev = Xinit + total_n_samples = init_n_samples + Yprev = initYprev + + Xfull = [] + Yfull = [] + + # Store the initial ModifiedLOO + if pce: + print("\nInitial ModifiedLOO:", init_mod_LOO) + SeqModifiedLOO = np.array(init_mod_LOO) + + if len(self.ExpDesign.valid_model_runs) != 0: + SeqValidError = np.array(init_valid_error) + + # Check if data is provided + if len(obs_data) != 0 and hasattr(self.MetaModel, 'Discrepancy'): + SeqBME = np.array([init_BME]) + SeqKLD = np.array([init_KLD]) + SeqDistHellinger = np.array([init_dist_hellinger]) + + if mc_ref and pce: + seqRMSEMean = np.array([init_rmse_mean]) + seqRMSEStd = np.array([init_rmse_std]) + + # ------- Start Sequential Experimental Design ------- + postcnt = 1 + for itr_no in range(1, n_itrs+1): + print(f'\n>>>> Iteration number {itr_no} <<<<') + + # Save the metamodel prediction before updating + prevMetaModel_dict[itr_no] = deepcopy(self.MetaModel) + #prevExpDesign_dict[itr_no] = deepcopy(self.ExpDesign) + if itr_no > 1: + pc_model = prevMetaModel_dict[itr_no-1] + self._y_hat_prev, _ = pc_model.eval_metamodel( + samples=Xfull[-1].reshape(1, -1)) + del prevMetaModel_dict[itr_no-1] + + # Optimal Bayesian Design + #self.MetaModel.ExpDesignFlag = 'sequential' + Xnew, updatedPrior = self.choose_next_sample(TotalSigma2, + n_canddidate, + util_f) + S = np.min(distance.cdist(Xinit, Xnew, 'euclidean')) + self.seqMinDist.append(S) + print(f"\nmin Dist from OldExpDesign: {S:2f}") + print("\n") + + # Evaluate the full model response at the new sample + Ynew, _ = self.Model.run_model_parallel( + Xnew, prevRun_No=total_n_samples + ) + total_n_samples += Xnew.shape[0] + + # ------ Plot the surrogate model vs Origninal Model ------ + if hasattr(self.ExpDesign, 'adapt_verbose') and \ + self.ExpDesign.adapt_verbose: + from .adaptPlot import adaptPlot + y_hat, std_hat = self.MetaModel.eval_metamodel( + samples=Xnew + ) + adaptPlot( + self.MetaModel, Ynew, y_hat, std_hat, + plotED=False + ) + + # -------- Retrain the surrogate model ------- + # Extend new experimental design + Xfull = np.vstack((Xprev, Xnew)) + + # Updating experimental design Y + for out_name in output_name: + Yfull = np.vstack((Yprev[out_name], Ynew[out_name])) + self.ExpDesign.Y[out_name] = Yfull + + # Pass new design to the metamodel object + self.ExpDesign.sampling_method = 'user' + self.ExpDesign.X = Xfull + #self.ExpDesign.Y = self.MetaModel.ModelOutputDict + + # Save the Experimental Design for next iteration + Xprev = Xfull + Yprev = self.ExpDesign.Y + + # Pass the new prior as the input + # TODO: another look at this - no difference apc to pce to gpe? + self.MetaModel.input_obj.poly_coeffs_flag = False + if updatedPrior is not None: + self.MetaModel.input_obj.poly_coeffs_flag = True + print("updatedPrior:", updatedPrior.shape) + # Arbitrary polynomial chaos + for i in range(updatedPrior.shape[1]): + self.MetaModel.input_obj.Marginals[i].dist_type = None + x = updatedPrior[:, i] + self.MetaModel.input_obj.Marginals[i].raw_data = x + + # Train the surrogate model for new ExpDesign + self.train_normal(parallel=False) + + # -------- Evaluate the retrained surrogate model ------- + # Extract Modified LOO from Output + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = self.ExpDesign.Y[out_name] + Scores_all.append(list( + self.MetaModel.score_dict['b_1'][out_name].values())) + if self.MetaModel.dim_red_method.lower() == 'pca': + pca = self.MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, + axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + Scores = [item for sublist in Scores_all for item + in sublist] + weights = [item for sublist in varExpDesignY for item + in sublist] + ModifiedLOO = [np.average( + [1-score for score in Scores], weights=weights)] + + print('\n') + print(f"Updated ModifiedLOO {util_f}:\n", ModifiedLOO) + print('\n') + + # Compute the validation error + if self.ExpDesign.valid_model_runs: + rmse, validError = self._validError(self.MetaModel) + ValidError = list(validError.values()) + else: + rmse = None + + # Store updated ModifiedLOO + if pce: + SeqModifiedLOO = np.vstack( + (SeqModifiedLOO, ModifiedLOO)) + if len(self.ExpDesign.valid_model_runs) != 0: + SeqValidError = np.vstack( + (SeqValidError, ValidError)) + # -------- Caclulation of BME as accuracy metric ------- + # Check if data is provided + if len(obs_data) != 0: + # Calculate the initial BME + out = self._BME_Calculator(obs_data, TotalSigma2, rmse) + BME, KLD, Posterior, likes, DistHellinger = out + print('\n') + print(f"Updated BME: {BME:.2f}") + print(f"Updated KLD: {KLD:.2f}") + print('\n') + + # Plot some snapshots of the posterior + step_snapshot = self.ExpDesign.step_snapshot + if post_snapshot and postcnt % step_snapshot == 0: + parNames = self.ExpDesign.par_names + print('Posterior snapshot is being plotted...') + self.__posteriorPlot(Posterior, parNames, + f'SeqPosterior_{postcnt}') + postcnt += 1 + + # Check the convergence of the Mean&Std + if mc_ref and pce: + print('\n') + RMSE_Mean, RMSE_std = self._error_Mean_Std() + print(f"Updated Mean and Std error: {RMSE_Mean:.2f}, " + f"{RMSE_std:.2f}") + print('\n') + + # Store the updated BME & KLD + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.vstack((SeqBME, BME)) + SeqKLD = np.vstack((SeqKLD, KLD)) + SeqDistHellinger = np.vstack((SeqDistHellinger, + DistHellinger)) + if mc_ref and pce: + seqRMSEMean = np.vstack((seqRMSEMean, RMSE_Mean)) + seqRMSEStd = np.vstack((seqRMSEStd, RMSE_std)) + + if pce and any(LOO < mod_LOO_threshold + for LOO in ModifiedLOO): + break + + # Clean up + if len(obs_data) != 0: + del out + print() + print('-'*50) + print() + + # Store updated ModifiedLOO and BME in dictonary + strKey = f'{util_f}_rep_{repIdx+1}' + if pce: + self.SeqModifiedLOO[strKey] = SeqModifiedLOO + if len(self.ExpDesign.valid_model_runs) != 0: + self.seqValidError[strKey] = SeqValidError + + # Check if data is provided + if len(obs_data) != 0: + self.SeqBME[strKey] = SeqBME + self.SeqKLD[strKey] = SeqKLD + if hasattr(self.MetaModel, 'valid_likelihoods') and \ + self.valid_likelihoods: + self.SeqDistHellinger[strKey] = SeqDistHellinger + if mc_ref and pce: + self.seqRMSEMean[strKey] = seqRMSEMean + self.seqRMSEStd[strKey] = seqRMSEStd + + # return self.MetaModel + + # ------------------------------------------------------------------------- + def util_VarBasedDesign(self, X_can, index, util_func='Entropy'): + """ + Computes the exploitation scores based on: + active learning MacKay(ALM) and active learning Cohn (ALC) + Paper: Sequential Design with Mutual Information for Computer + Experiments (MICE): Emulation of a Tsunami Model by Beck and Guillas + (2016) + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + index : int + Model output index. + UtilMethod : string, optional + Exploitation utility function. The default is 'Entropy'. + + Returns + ------- + float + Score. + + """ + MetaModel = self.MetaModel + ED_X = self.ExpDesign.X + out_dict_y = self.ExpDesign.Y + out_names = self.out_names + + # Run the Metamodel for the candidate + X_can = X_can.reshape(1, -1) + Y_PC_can, std_PC_can = MetaModel.eval_metamodel(samples=X_can) + + if util_func.lower() == 'alm': + # ----- Entropy/MMSE/active learning MacKay(ALM) ----- + # Compute perdiction variance of the old model + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + varPCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + varPCE[KeyIdx] = np.max(canPredVar[key], axis=1) + score = np.max(varPCE, axis=0) + + elif util_func.lower() == 'eigf': + # ----- Expected Improvement for Global fit ----- + # Find closest EDX to the candidate + distances = distance.cdist(ED_X, X_can, 'euclidean') + index = np.argmin(distances) + + # Compute perdiction error and variance of the old model + predError = {key: Y_PC_can[key] for key in out_names} + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + # Compute perdiction error and variance of the old model + # Eq (5) from Liu et al.(2018) + EIGF_PCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + residual = predError[key] - out_dict_y[key][int(index)] + var = canPredVar[key] + EIGF_PCE[KeyIdx] = np.max(residual**2 + var, axis=1) + score = np.max(EIGF_PCE, axis=0) + + return -1 * score # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianActiveDesign(self, y_hat, std, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian active design criterion (var). + + It is based on the following paper: + Oladyshkin, Sergey, Farid Mohammadi, Ilja Kroeker, and Wolfgang Nowak. + "Bayesian3 active learning for the gaussian process emulator using + information theory." Entropy 22, no. 8 (2020): 890. + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + BAL design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # Get the data + obs_data = self.observations + # TODO: this should be optimizable to be calculated explicitly + if hasattr(self.Model, 'n_obs'): + n_obs = self.Model.n_obs + else: + n_obs = self.n_obs + mc_size = 10000 + + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + Y_MC, std_MC = {}, {} + logPriorLikelihoods = np.zeros((mc_size)) + # print(y_hat) + # print(list[y_hat]) + for key in list(y_hat): + cov = np.diag(std[key]**2) + # print(y_hat[key], cov) + # TODO: added the allow_singular = True here + rv = stats.multivariate_normal(mean=y_hat[key], cov=cov,) + Y_MC[key] = rv.rvs(size=mc_size) + logPriorLikelihoods += rv.logpdf(Y_MC[key]) + std_MC[key] = np.zeros((mc_size, y_hat[key].shape[0])) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self._normpdf(Y_MC, std_MC, obs_data, sigma2Dict) + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, mc_size)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods), dtype=np.longdouble)#float128) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + # Utility function Eq.2 in Ref. (2) + # Posterior covariance matrix after observing data y + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # TODO: Calculate the correction factor for BME + # BMECorrFactor = self.BME_Corr_Weight(PCE_SparseBayes_can, + # ObservationData, sigma2Dict) + # BME += BMECorrFactor + # Haun et al implementation + # U_J_d = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + U_J_d = postExpLikelihoods - logBME + + # Marginal log likelihood + elif var == 'BME': + U_J_d = np.nanmean(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + logBME = np.log(np.nanmean(likelihoods)) + infEntropy = logBME - postExpPrior - postExpLikelihoods + U_J_d = infEntropy * -1 # -1 for minimization + + # Bayesian information criterion + elif var == 'BIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxL = np.nanmax(likelihoods) + U_J_d = -2 * np.log(maxL) + np.log(n_obs) * nModelParams + + # Akaike information criterion + elif var == 'AIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxlogL = np.log(np.nanmax(likelihoods)) + AIC = -2 * maxlogL + 2 * nModelParams + # 2 * nModelParams * (nModelParams+1) / (n_obs-nModelParams-1) + penTerm = 0 + U_J_d = 1*(AIC + penTerm) + + # Deviance information criterion + elif var == 'DIC': + # D_theta_bar = np.mean(-2 * Likelihoods) + N_star_p = 0.5 * np.var(np.log(likelihoods[likelihoods != 0])) + Likelihoods_theta_mean = self._normpdf( + y_hat, std, obs_data, sigma2Dict + ) + DIC = -2 * np.log(Likelihoods_theta_mean) + 2 * N_star_p + + U_J_d = DIC + + else: + print('The algorithm you requested has not been implemented yet!') + + # Handle inf and NaN (replace by zero) + if np.isnan(U_J_d) or U_J_d == -np.inf or U_J_d == np.inf: + U_J_d = 0.0 + + # Clear memory + del likelihoods + del Y_MC + del std_MC + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianDesign(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + MetaModel = self.MetaModel + out_names = self.out_names + if X_can.ndim == 1: + X_can = X_can.reshape(1, -1) + + # Compute the mean and std based on the MetaModel + # pce_means, pce_stds = self._compute_pce_moments(MetaModel) + if var == 'ALC': + Y_MC, Y_MC_std = MetaModel.eval_metamodel(samples=X_MC) + + # Old Experimental design + oldExpDesignX = self.ExpDesign.X + oldExpDesignY = self.ExpDesign.Y + + # Evaluate the PCE metamodels at that location ??? + Y_PC_can, Y_std_can = MetaModel.eval_metamodel(samples=X_can) + PCE_Model_can = deepcopy(MetaModel) + engine_can = deepcopy(self) + # Add the candidate to the ExpDesign + NewExpDesignX = np.vstack((oldExpDesignX, X_can)) + + NewExpDesignY = {} + for key in oldExpDesignY.keys(): + NewExpDesignY[key] = np.vstack( + (oldExpDesignY[key], Y_PC_can[key]) + ) + + engine_can.ExpDesign.sampling_method = 'user' + engine_can.ExpDesign.X = NewExpDesignX + #engine_can.ModelOutputDict = NewExpDesignY + engine_can.ExpDesign.Y = NewExpDesignY + + # Train the model for the observed data using x_can + engine_can.MetaModel.input_obj.poly_coeffs_flag = False + engine_can.start_engine() + engine_can.train_normal(parallel=False) + engine_can.MetaModel.fit(NewExpDesignX, NewExpDesignY) +# engine_can.train_norm_design(parallel=False) + + # Set the ExpDesign to its original values + engine_can.ExpDesign.X = oldExpDesignX + engine_can.ModelOutputDict = oldExpDesignY + engine_can.ExpDesign.Y = oldExpDesignY + + if var.lower() == 'mi': + # Mutual information based on Krause et al + # Adapted from Beck & Guillas (MICE) paper + _, std_PC_can = engine_can.MetaModel.eval_metamodel(samples=X_can) + std_can = {key: std_PC_can[key] for key in out_names} + + std_old = {key: Y_std_can[key] for key in out_names} + + varPCE = np.zeros((len(out_names))) + for i, key in enumerate(out_names): + varPCE[i] = np.mean(std_old[key]**2/std_can[key]**2) + score = np.mean(varPCE) + + return -1 * score + + elif var.lower() == 'alc': + # Active learning based on Gramyc and Lee + # Adaptive design and analysis of supercomputer experiments Techno- + # metrics, 51 (2009), pp. 130–145. + + # Evaluate the MetaModel at the given samples + Y_MC_can, Y_MC_std_can = engine_can.MetaModel.eval_metamodel(samples=X_MC) + + # Compute the score + score = [] + for i, key in enumerate(out_names): + pce_var = Y_MC_std_can[key]**2 + pce_var_can = Y_MC_std[key]**2 + score.append(np.mean(pce_var-pce_var_can, axis=0)) + score = np.mean(score) + + return -1 * score + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = X_MC.shape[0] + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Enriching Monte Carlo samples if need be + if ESS != 0: + X_MC = self.ExpDesign.generate_samples( + MCsize, 'random' + ) + + # Evaluate the MetaModel at the given samples + Y_MC, std_MC = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self._normpdf( + Y_MC, std_MC, self.observations, sigma2Dict + ) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.sum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + print("--- increasing MC size---") + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # -------------------- Utility functions -------------------- + # Utility function Eq.2 in Ref. (2) + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods, dtype=np.longdouble))#float128)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Haun et al implementation + U_J_d = np.mean(np.log(likelihoods[likelihoods != 0]) - logBME) + + # U_J_d = np.sum(G_n_m_all) + # Ryan et al (2014) implementation + # importanceWeights = Likelihoods[Likelihoods!=0]/np.sum(Likelihoods[Likelihoods!=0]) + # U_J_d = np.mean(importanceWeights*np.log(Likelihoods[Likelihoods!=0])) - logBME + + # U_J_d = postExpLikelihoods - logBME + + # Marginal likelihood + elif var == 'BME': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + U_J_d = logBME + + # Bayes risk likelihood + elif var == 'BayesRisk': + + U_J_d = -1 * np.var(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postLikelihoods /= np.nansum(likelihoods[accepted]) + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + infEntropy = logBME - postExpPrior - postExpLikelihoods + + U_J_d = infEntropy * -1 # -1 for minimization + + # D-Posterior-precision + elif var == 'DPP': + X_Posterior = X_MC[accepted] + # covariance of the posterior parameters + U_J_d = -np.log(np.linalg.det(np.cov(X_Posterior))) + + # A-Posterior-precision + elif var == 'APP': + X_Posterior = X_MC[accepted] + # trace of the posterior parameters + U_J_d = -np.log(np.trace(np.cov(X_Posterior))) + + else: + print('The algorithm you requested has not been implemented yet!') + + # Clear memory + del likelihoods + del Y_MC + del std_MC + + return -1 * U_J_d # -1 is for minimization instead of maximization + + + # ------------------------------------------------------------------------- + def run_util_func(self, method, candidates, index, sigma2Dict=None, + var=None, X_MC=None): + """ + Runs the utility function based on the given method. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + candidates : array of shape (n_samples, n_params) + All candidate parameter sets. + index : int + ExpDesign index. + sigma2Dict : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + var : string, optional + Utility function. The default is None. + X_MC : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + index : TYPE + DESCRIPTION. + List + Scores. + + """ + + if method.lower() == 'varoptdesign': + # U_J_d = self.util_VarBasedDesign(candidates, index, var) + U_J_d = np.zeros((candidates.shape[0])) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="varoptdesign"): + U_J_d[idx] = self.util_VarBasedDesign(X_can, index, var) + + elif method.lower() == 'bayesactdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + # Evaluate all candidates + y_can, std_can = self.MetaModel.eval_metamodel(samples=candidates) + # loop through candidates + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="BAL Design"): + y_hat = {key: items[idx] for key, items in y_can.items()} + std = {key: items[idx] for key, items in std_can.items()} + + # print(y_hat) + # print(std) + U_J_d[idx] = self.util_BayesianActiveDesign( + y_hat, std, sigma2Dict, var) + + elif method.lower() == 'bayesoptdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianDesign(X_can, X_MC, sigma2Dict, + var) + return (index, -1 * U_J_d) + + # ------------------------------------------------------------------------- + def dual_annealing(self, method, Bounds, sigma2Dict, var, Run_No, + verbose=False): + """ + Exploration algorithm to find the optimum parameter space. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + Bounds : list of tuples + List of lower and upper boundaries of parameters. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + Run_No : int + Run number. + verbose : bool, optional + Print out a summary. The default is False. + + Returns + ------- + Run_No : int + Run number. + array + Optimial candidate. + + """ + + Model = self.Model + max_func_itr = self.ExpDesign.max_func_itr + + if method == 'VarOptDesign': + Res_Global = opt.dual_annealing(self.util_VarBasedDesign, + bounds=Bounds, + args=(Model, var), + maxfun=max_func_itr) + + elif method == 'BayesOptDesign': + Res_Global = opt.dual_annealing(self.util_BayesianDesign, + bounds=Bounds, + args=(Model, sigma2Dict, var), + maxfun=max_func_itr) + + if verbose: + print(f"Global minimum: xmin = {Res_Global.x}, " + f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}") + + return (Run_No, Res_Global.x) + + # ------------------------------------------------------------------------- + def tradeoff_weights(self, tradeoff_scheme, old_EDX, old_EDY): + """ + Calculates weights for exploration scores based on the requested + scheme: `None`, `equal`, `epsilon-decreasing` and `adaptive`. + + `None`: No exploration. + `equal`: Same weights for exploration and exploitation scores. + `epsilon-decreasing`: Start with more exploration and increase the + influence of exploitation along the way with a exponential decay + function + `adaptive`: An adaptive method based on: + Liu, Haitao, Jianfei Cai, and Yew-Soon Ong. "An adaptive sampling + approach for Kriging metamodeling by maximizing expected prediction + error." Computers & Chemical Engineering 106 (2017): 171-182. + + Parameters + ---------- + tradeoff_scheme : string + Trade-off scheme for exloration and exploitation scores. + old_EDX : array (n_samples, n_params) + Old experimental design (training points). + old_EDY : dict + Old model responses (targets). + + Returns + ------- + exploration_weight : float + Exploration weight. + exploitation_weight: float + Exploitation weight. + + """ + if tradeoff_scheme is None: + exploration_weight = 0 + + elif tradeoff_scheme == 'equal': + exploration_weight = 0.5 + + elif tradeoff_scheme == 'epsilon-decreasing': + # epsilon-decreasing scheme + # Start with more exploration and increase the influence of + # exploitation along the way with a exponential decay function + initNSamples = self.ExpDesign.n_init_samples + n_max_samples = self.ExpDesign.n_max_samples + + itrNumber = (self.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.ExpDesign.n_new_samples + + tau2 = -(n_max_samples-initNSamples-1) / np.log(1e-8) + exploration_weight = signal.exponential(n_max_samples-initNSamples, + 0, tau2, False)[itrNumber] + + elif tradeoff_scheme == 'adaptive': + + # Extract itrNumber + initNSamples = self.ExpDesign.n_init_samples + n_max_samples = self.ExpDesign.n_max_samples + itrNumber = (self.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.ExpDesign.n_new_samples + + if itrNumber == 0: + exploration_weight = 0.5 + else: + # New adaptive trade-off according to Liu et al. (2017) + # Mean squared error for last design point + last_EDX = old_EDX[-1].reshape(1, -1) + lastPCEY, _ = self.MetaModel.eval_metamodel(samples=last_EDX) + pce_y = np.array(list(lastPCEY.values()))[:, 0] + y = np.array(list(old_EDY.values()))[:, -1, :] + mseError = mean_squared_error(pce_y, y) + + # Mean squared CV - error for last design point + pce_y_prev = np.array(list(self._y_hat_prev.values()))[:, 0] + mseCVError = mean_squared_error(pce_y_prev, y) + + exploration_weight = min([0.5*mseError/mseCVError, 1]) + + # Exploitation weight + exploitation_weight = 1 - exploration_weight + + return exploration_weight, exploitation_weight + + # ------------------------------------------------------------------------- + def choose_next_sample(self, sigma2=None, n_candidates=5, var='DKL'): + """ + Runs optimal sequential design. + + Parameters + ---------- + sigma2 : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + n_candidates : int, optional + Number of candidate samples. The default is 5. + var : string, optional + Utility function. The default is None. # TODO: default is set to DKL, not none + + Raises + ------ + NameError + Wrong utility function. + + Returns + ------- + Xnew : array (n_samples, n_params) + Selected new training point(s). + """ + + # Initialization + Bounds = self.ExpDesign.bound_tuples + n_new_samples = self.ExpDesign.n_new_samples + explore_method = self.ExpDesign.explore_method + exploit_method = self.ExpDesign.exploit_method + n_cand_groups = self.ExpDesign.n_cand_groups + tradeoff_scheme = self.ExpDesign.tradeoff_scheme + + old_EDX = self.ExpDesign.X + old_EDY = self.ExpDesign.Y.copy() + ndim = self.ExpDesign.X.shape[1] + OutputNames = self.out_names + + # ----------------------------------------- + # ----------- CUSTOMIZED METHODS ---------- + # ----------------------------------------- + # Utility function exploit_method provided by user + if exploit_method.lower() == 'user': + if not hasattr(self.ExpDesign, 'ExploitFunction'): + raise AttributeError('Function `ExploitFunction` not given to the ExpDesign, thus cannor run user-defined sequential scheme') + # TODO: syntax does not fully match the rest - can test this?? + Xnew, filteredSamples = self.ExpDesign.ExploitFunction(self) + + print("\n") + print("\nXnew:\n", Xnew) + + return Xnew, filteredSamples + + + # Dual-Annealing works differently from the rest, so deal with this first + # Here exploration and exploitation are performed simulataneously + if explore_method == 'dual annealing': + # ------- EXPLORATION: OPTIMIZATION ------- + import time + start_time = time.time() + + # Divide the domain to subdomains + subdomains = subdomain(Bounds, n_new_samples) + + # Multiprocessing + if self.parallel: + args = [] + for i in range(n_new_samples): + args.append((exploit_method, subdomains[i], sigma2, var, i)) + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + + # With Pool.starmap_async() + results = pool.starmap_async(self.dual_annealing, args).get() + + # Close the pool + pool.close() + # Without multiprocessing + else: + results = [] + for i in range(n_new_samples): + results.append(self.dual_annealing(exploit_method, subdomains[i], sigma2, var, i)) + + # New sample + Xnew = np.array([results[i][1] for i in range(n_new_samples)]) + print("\nXnew:\n", Xnew) + + # Computational cost + elapsed_time = time.time() - start_time + print("\n") + print(f"Elapsed_time: {round(elapsed_time,2)} sec.") + print('-'*20) + + return Xnew, None + + # Generate needed Exploration class + explore = Exploration(self.ExpDesign, n_candidates) + explore.w = 100 # * ndim #500 # TODO: where does this value come from? + + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + + # Generate the candidate samples + # TODO: here use the sampling method provided by the expdesign? + sampling_method = self.ExpDesign.sampling_method + + # TODO: changed this from 'random' for LOOCV + if explore_method == 'LOOCV': + allCandidates = self.ExpDesign.generate_samples(n_candidates, + sampling_method) + else: + allCandidates, scoreExploration = explore.get_exploration_samples() + + # ----------------------------------------- + # ---------- EXPLORATION METHODS ---------- + # ----------------------------------------- + if explore_method == 'LOOCV': + # ----------------------------------------------------------------- + # TODO: LOOCV model construnction based on Feng et al. (2020) + # 'LOOCV': + # Initilize the ExploitScore array + + # Generate random samples + allCandidates = self.ExpDesign.generate_samples(n_candidates, + 'random') + + # Construct error model based on LCerror + errorModel = self.MetaModel.create_ModelError(old_EDX, self.LCerror) + self.errorModel.append(copy(errorModel)) + + # Evaluate the error models for allCandidates + eLCAllCands, _ = errorModel.eval_errormodel(allCandidates) + # Select the maximum as the representative error + eLCAllCands = np.dstack(eLCAllCands.values()) + eLCAllCandidates = np.max(eLCAllCands, axis=1)[:, 0] + + # Normalize the error w.r.t the maximum error + scoreExploration = eLCAllCandidates / np.sum(eLCAllCandidates) + + else: + # ------- EXPLORATION: SPACE-FILLING DESIGN ------- + # Generate candidate samples from Exploration class + explore = Exploration(self.ExpDesign, n_candidates) + explore.w = 100 # * ndim #500 + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + allCandidates, scoreExploration = explore.get_exploration_samples() + + # Temp: ---- Plot all candidates ----- + if ndim == 2: + def plotter(points, allCandidates, Method, + scoreExploration=None): + if Method == 'Voronoi': + from scipy.spatial import Voronoi, voronoi_plot_2d + vor = Voronoi(points) + fig = voronoi_plot_2d(vor) + ax1 = fig.axes[0] + else: + fig = plt.figure() + ax1 = fig.add_subplot(111) + ax1.scatter(points[:, 0], points[:, 1], s=10, c='r', + marker="s", label='Old Design Points') + ax1.scatter(allCandidates[:, 0], allCandidates[:, 1], s=10, + c='b', marker="o", label='Design candidates') + for i in range(points.shape[0]): + txt = 'p'+str(i+1) + ax1.annotate(txt, (points[i, 0], points[i, 1])) + if scoreExploration is not None: + for i in range(allCandidates.shape[0]): + txt = str(round(scoreExploration[i], 5)) + ax1.annotate(txt, (allCandidates[i, 0], + allCandidates[i, 1])) + + plt.xlim(self.bound_tuples[0]) + plt.ylim(self.bound_tuples[1]) + # plt.show() + plt.legend(loc='upper left') + + # ----------------------------------------- + # --------- EXPLOITATION METHODS ---------- + # ----------------------------------------- + if exploit_method == 'BayesOptDesign' or\ + exploit_method == 'BayesActDesign': + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradeoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\n Exploration weight={explore_w:0.3f} " + f"Exploitation weight={exploit_w:0.3f}\n") + + # ------- EXPLOITATION: BayesOptDesign & ActiveLearning ------- + if explore_w != 1.0: + # Check if all needed properties are set + if not hasattr(self.ExpDesign, 'max_func_itr'): + raise AttributeError('max_func_itr not given to the experimental design') + + # Create a sample pool for rejection sampling + MCsize = 15000 + X_MC = self.ExpDesign.generate_samples(MCsize, 'random') + candidates = self.ExpDesign.generate_samples( + n_candidates, 'latin_hypercube') + + # Split the candidates in groups for multiprocessing + split_cand = np.array_split( + candidates, n_cand_groups, axis=0 + ) + # print(candidates) + # print(split_cand) + if self.parallel: + results = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.run_util_func)( + exploit_method, split_cand[i], i, sigma2, var, X_MC) + for i in range(n_cand_groups)) + else: + results = [] + for i in range(n_cand_groups): + results.append(self.run_util_func(exploit_method, split_cand[i], i, sigma2, var, X_MC)) + + # Retrieve the results and append them + U_J_d = np.concatenate([results[NofE][1] for NofE in + range(n_cand_groups)]) + + # Check if all scores are inf + if np.isinf(U_J_d).all() or np.isnan(U_J_d).all(): + U_J_d = np.ones(len(U_J_d)) + + # Get the expected value (mean) of the Utility score + # for each cell + if explore_method == 'Voronoi': + U_J_d = np.mean(U_J_d.reshape(-1, n_candidates), axis=1) + + # Normalize U_J_d + norm_U_J_d = U_J_d / np.sum(U_J_d) + else: + norm_U_J_d = np.zeros((len(scoreExploration))) + + # ------- Calculate Total score ------- + # ------- Trade off between EXPLORATION & EXPLOITATION ------- + # Total score + totalScore = exploit_w * norm_U_J_d + totalScore += explore_w * scoreExploration + + # temp: Plot + # dim = self.ExpDesign.X.shape[1] + # if dim == 2: + # plotter(self.ExpDesign.X, allCandidates, explore_method) + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + # select the requested number of samples + if explore_method == 'Voronoi': + Xnew = np.zeros((n_new_samples, ndim)) + for i, idx in enumerate(bestIdx): + X_can = explore.closestPoints[idx] + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + else: + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + elif exploit_method == 'VarOptDesign': + # ------- EXPLOITATION: VarOptDesign ------- + UtilMethod = var + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradeoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\nweightExploration={explore_w:0.3f} " + f"weightExploitation={exploit_w:0.3f}") + + # Generate candidate samples from Exploration class + nMeasurement = old_EDY[OutputNames[0]].shape[1] + + # print(UtilMethod) + + # Find sensitive region + if UtilMethod == 'LOOCV': + LCerror = self.MetaModel.LCerror + allModifiedLOO = np.zeros((len(old_EDX), len(OutputNames), + nMeasurement)) + for y_idx, y_key in enumerate(OutputNames): + for idx, key in enumerate(LCerror[y_key].keys()): + allModifiedLOO[:, y_idx, idx] = abs( + LCerror[y_key][key]) + + ExploitScore = np.max(np.max(allModifiedLOO, axis=1), axis=1) + # print(allModifiedLOO.shape) + + elif UtilMethod in ['EIGF', 'ALM']: + # ----- All other in ['EIGF', 'ALM'] ----- + # Initilize the ExploitScore array + ExploitScore = np.zeros((len(old_EDX), len(OutputNames))) + + # Split the candidates in groups for multiprocessing + if explore_method != 'Voronoi': + split_cand = np.array_split(allCandidates, + n_cand_groups, + axis=0) + goodSampleIdx = range(n_cand_groups) + else: + # Find indices of the Vornoi cells with samples + goodSampleIdx = [] + for idx in range(len(explore.closest_points)): + if len(explore.closest_points[idx]) != 0: + goodSampleIdx.append(idx) + split_cand = explore.closest_points + + # Split the candidates in groups for multiprocessing + args = [] + for index in goodSampleIdx: + args.append((exploit_method, split_cand[index], index, + sigma2, var)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + # With Pool.starmap_async() + results = pool.starmap_async(self.run_util_func, args).get() + + # Close the pool + pool.close() + + # Retrieve the results and append them + if explore_method == 'Voronoi': + ExploitScore = [np.mean(results[k][1]) for k in + range(len(goodSampleIdx))] + else: + ExploitScore = np.concatenate( + [results[k][1] for k in range(len(goodSampleIdx))]) + + else: + raise NameError('The requested utility function is not ' + 'available.') + + # print("ExploitScore:\n", ExploitScore) + + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + # Total score + # Normalize U_J_d + ExploitScore = ExploitScore / np.sum(ExploitScore) + totalScore = exploit_w * ExploitScore + # print(totalScore.shape) + # print(explore_w) + # print(scoreExploration.shape) + totalScore += explore_w * scoreExploration + + temp = totalScore.copy() + sorted_idxtotalScore = np.argsort(temp, axis=0)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + Xnew = np.zeros((n_new_samples, ndim)) + if explore_method != 'Voronoi': + Xnew = allCandidates[bestIdx] + else: + for i, idx in enumerate(bestIdx.flatten()): + X_can = explore.closest_points[idx] + # plotter(self.ExpDesign.X, X_can, explore_method, + # scoreExploration=None) + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + + elif exploit_method == 'alphabetic': + # ------- EXPLOITATION: ALPHABETIC ------- + Xnew = self.util_AlphOptDesign(allCandidates, var) + + elif exploit_method == 'Space-filling': + # ------- EXPLOITATION: SPACE-FILLING ------- + totalScore = scoreExploration + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + + # select the requested number of samples + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + else: + raise NameError('The requested design method is not available.') + + print("\n") + print("\nRun No. {}:".format(old_EDX.shape[0]+1)) + print("Xnew:\n", Xnew) + + # TODO: why does it also return None? + return Xnew, None + + # ------------------------------------------------------------------------- + def util_AlphOptDesign(self, candidates, var='D-Opt'): + """ + Enriches the Experimental design with the requested alphabetic + criterion based on exploring the space with number of sampling points. + + Ref: Hadigol, M., & Doostan, A. (2018). Least squares polynomial chaos + expansion: A review of sampling strategies., Computer Methods in + Applied Mechanics and Engineering, 332, 382-407. + + Arguments + --------- + NCandidate : int + Number of candidate points to be searched + + var : string + Alphabetic optimality criterion + + Returns + ------- + X_new : array of shape (1, n_params) + The new sampling location in the input space. + """ + MetaModelOrig = self # TODO: this doesn't fully seem correct? + n_new_samples = MetaModelOrig.ExpDesign.n_new_samples + NCandidate = candidates.shape[0] + + # TODO: Loop over outputs + OutputName = self.out_names[0] + + # To avoid changes ub original aPCE object + MetaModel = deepcopy(MetaModelOrig) + + # Old Experimental design + oldExpDesignX = self.ExpDesign.X + + # TODO: Only one psi can be selected. + # Suggestion: Go for the one with the highest LOO error + # TODO: this is just a patch, need to look at again! + Scores = list(self.MetaModel.score_dict['b_1'][OutputName].values()) + #print(Scores) + #print(self.MetaModel.score_dict) + #print(self.MetaModel.score_dict.values()) + #print(self.MetaModel.score_dict['b_1'].values()) + #print(self.MetaModel.score_dict['b_1'][OutputName].values()) + ModifiedLOO = [1-score for score in Scores] + outIdx = np.argmax(ModifiedLOO) + + # Initialize Phi to save the criterion's values + Phi = np.zeros((NCandidate)) + + # TODO: also patched here + BasisIndices = self.MetaModel.basis_dict['b_1'][OutputName]["y_"+str(outIdx+1)] + P = len(BasisIndices) + + # ------ Old Psi ------------ + univ_p_val = self.MetaModel.univ_basis_vals(oldExpDesignX) + Psi = self.MetaModel.create_psi(BasisIndices, univ_p_val) + + # ------ New candidates (Psi_c) ------------ + # Assemble Psi_c + univ_p_val_c = self.MetaModel.univ_basis_vals(candidates) + Psi_c = self.MetaModel.create_psi(BasisIndices, univ_p_val_c) + + for idx in range(NCandidate): + + # Include the new row to the original Psi + Psi_cand = np.vstack((Psi, Psi_c[idx])) + + # Information matrix + PsiTPsi = np.dot(Psi_cand.T, Psi_cand) + M = PsiTPsi / (len(oldExpDesignX)+1) + + if np.linalg.cond(PsiTPsi) > 1e-12 \ + and np.linalg.cond(PsiTPsi) < 1 / sys.float_info.epsilon: + # faster + invM = linalg.solve(M, sparse.eye(PsiTPsi.shape[0]).toarray()) + else: + # stabler + invM = np.linalg.pinv(M) + + # ---------- Calculate optimality criterion ---------- + # Optimality criteria according to Section 4.5.1 in Ref. + + # D-Opt + if var.lower() == 'd-opt': + Phi[idx] = (np.linalg.det(invM)) ** (1/P) + + # A-Opt + elif var.lower() == 'a-opt': + Phi[idx] = np.trace(invM) + + # K-Opt + elif var.lower() == 'k-opt': + Phi[idx] = np.linalg.cond(M) + + else: + # print(var.lower()) + raise Exception('The optimality criterion you requested has ' + 'not been implemented yet!') + + # find an optimal point subset to add to the initial design + # by minimization of the Phi + sorted_idxtotalScore = np.argsort(Phi) + + # select the requested number of samples + Xnew = candidates[sorted_idxtotalScore[:n_new_samples]] + + return Xnew + + # ------------------------------------------------------------------------- + def _normpdf(self, y_hat_pce, std_pce, obs_data, total_sigma2s, + rmse=None): + """ + Calculated gaussian likelihood for given y+std based on given obs+sigma + # TODO: is this understanding correct? + + Parameters + ---------- + y_hat_pce : dict of 2d np arrays + Mean output of the surrogate. + std_pce : dict of 2d np arrays + Standard deviation output of the surrogate. + obs_data : dict of 1d np arrays + Observed data. + total_sigma2s : pandas dataframe, matches obs_data + Estimated uncertainty for the observed data. + rmse : dict, optional + RMSE values from validation of the surrogate. The default is None. + + Returns + ------- + likelihoods : dict of float + The likelihood for each surrogate eval in y_hat_pce compared to the + observations (?). + + """ + + likelihoods = 1.0 + + # Loop over the outputs + for idx, out in enumerate(self.out_names): + + # (Meta)Model Output + # print(y_hat_pce[out]) + nsamples, nout = y_hat_pce[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout].values + + # Surrogate error if valid dataset is given. + if rmse is not None: + tot_sigma2s += rmse[out]**2 + else: + tot_sigma2s += np.mean(std_pce[out])**2 + + likelihoods *= stats.multivariate_normal.pdf( + y_hat_pce[out], data, np.diag(tot_sigma2s), + allow_singular=True) + + # TODO: remove this here + self.Likelihoods = likelihoods + + return likelihoods + + # ------------------------------------------------------------------------- + def _corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = self.ExpDesign.X # valid_samples + model_outputs = self.ExpDesign.Y # valid_model_runs + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = self.out_names + + # TODO: Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + # covMatrix = np.diag(stdOutputRS[out][i]**2) + covMatrix = np.diag((y_m-y_m_hat)**2) + covMatrix = np.diag( + np.mean((model_outputs[out]-OutputRS[out]), axis=0)**2 + ) + + # Compute likelilhood output vs data + logLik_data[i] += logpdf( + y_m_hat, data, covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += logpdf(y_m_hat, y_m, covMatrix) + + # Weight + logLik_data -= logBME + weights = np.exp(logLik_model+logLik_data) + + return np.log(np.mean(weights)) + + # ------------------------------------------------------------------------- + def _posteriorPlot(self, posterior, par_names, key): + """ + Plot the posterior of a specific key as a corner plot + + Parameters + ---------- + posterior : 2d np.array + Samples of the posterior. + par_names : list of strings + List of the parameter names. + key : string + Output key that this posterior belongs to. + + Returns + ------- + figPosterior : corner.corner + Plot of the posterior. + + """ + + # Initialization + newpath = (r'Outputs_SeqPosteriorComparison/posterior') + os.makedirs(newpath, exist_ok=True) + + bound_tuples = self.ExpDesign.bound_tuples + n_params = len(par_names) + font_size = 40 + if n_params == 2: + + figPosterior, ax = plt.subplots(figsize=(15, 15)) + + sns.kdeplot(x=posterior[:, 0], y=posterior[:, 1], + fill=True, ax=ax, cmap=plt.cm.jet, + clip=bound_tuples) + # Axis labels + plt.xlabel(par_names[0], fontsize=font_size) + plt.ylabel(par_names[1], fontsize=font_size) + + # Set axis limit + plt.xlim(bound_tuples[0]) + plt.ylim(bound_tuples[1]) + + # Increase font size + plt.xticks(fontsize=font_size) + plt.yticks(fontsize=font_size) + + # Switch off the grids + plt.grid(False) + + else: + import corner + figPosterior = corner.corner(posterior, labels=par_names, + title_fmt='.2e', show_titles=True, + title_kwargs={"fontsize": 12}) + + figPosterior.savefig(f'./{newpath}/{key}.pdf', bbox_inches='tight') + plt.close() + + # Save the posterior as .npy + np.save(f'./{newpath}/{key}.npy', posterior) + + return figPosterior + + + # ------------------------------------------------------------------------- + def _BME_Calculator(self, obs_data, sigma2Dict, rmse=None): + """ + This function computes the Bayesian model evidence (BME) via Monte + Carlo integration. + + Parameters + ---------- + obs_data : dict of 1d np arrays + Observed data. + sigma2Dict : pandas dataframe, matches obs_data + Estimated uncertainty for the observed data. + rmse : dict of floats, optional + RMSE values for each output-key. The dafault is None. + + Returns + ------- + (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + """ + # Initializations + if hasattr(self, 'valid_likelihoods'): + valid_likelihoods = self.valid_likelihoods + else: + valid_likelihoods = [] + valid_likelihoods = np.array(valid_likelihoods) + + post_snapshot = self.ExpDesign.post_snapshot + if post_snapshot or valid_likelihoods.shape[0] != 0: + newpath = (r'Outputs_SeqPosteriorComparison/likelihood_vs_ref') + os.makedirs(newpath, exist_ok=True) + + SamplingMethod = 'random' + MCsize = 10000 + ESS = 0 + + # Estimation of the integral via Monte Varlo integration + while (ESS > MCsize) or (ESS < 1): + + # Generate samples for Monte Carlo simulation + X_MC = self.ExpDesign.generate_samples( + MCsize, SamplingMethod + ) + + # Monte Carlo simulation for the candidate design + Y_MC, std_MC = self.MetaModel.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and + # simulation results via PCE with candidate design) + Likelihoods = self._normpdf( + Y_MC, std_MC, obs_data, sigma2Dict, rmse + ) + + # Check the Effective Sample Size (1000<ESS<MCsize) + ESS = 1 / np.sum(np.square(Likelihoods/np.sum(Likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if (ESS > MCsize) or (ESS < 1): + print(f'ESS={ESS} MC size should be larger.') + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + X_Posterior = X_MC[accepted] + + # ------------------------------------------------------------ + # --- Kullback-Leibler Divergence & Information Entropy ------ + # ------------------------------------------------------------ + # Prior-based estimation of BME + logBME = np.log(np.nanmean(Likelihoods)) + + # TODO: Correction factor + # log_weight = self.__corr_factor_BME(obs_data, sigma2Dict, logBME) + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean(np.log(Likelihoods[accepted])) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean( + np.log(self.ExpDesign.JDist.pdf(X_Posterior.T)) + ) + + # Calculate Kullback-Leibler Divergence + # KLD = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + KLD = postExpLikelihoods - logBME + + # Information Entropy based on Entropy paper Eq. 38 + infEntropy = logBME - postExpPrior - postExpLikelihoods + + # If post_snapshot is True, plot likelihood vs refrence + if post_snapshot or valid_likelihoods: + # Hellinger distance + ref_like = np.log(valid_likelihoods[valid_likelihoods > 0]) + est_like = np.log(Likelihoods[Likelihoods > 0]) + distHellinger = hellinger_distance(ref_like, est_like) + + idx = len([name for name in os.listdir(newpath) if 'Likelihoods_' + in name and os.path.isfile(os.path.join(newpath, name))]) + + fig, ax = plt.subplots() + try: + sns.kdeplot(np.log(valid_likelihoods[valid_likelihoods > 0]), + shade=True, color="g", label='Ref. Likelihood') + sns.kdeplot(np.log(Likelihoods[Likelihoods > 0]), shade=True, + color="b", label='Likelihood with PCE') + except: + pass + + text = f"Hellinger Dist.={distHellinger:.3f}\n logBME={logBME:.3f}" + "\n DKL={KLD:.3f}" + + plt.text(0.05, 0.75, text, bbox=dict(facecolor='wheat', + edgecolor='black', + boxstyle='round,pad=1'), + transform=ax.transAxes) + + fig.savefig(f'./{newpath}/Likelihoods_{idx}.pdf', + bbox_inches='tight') + plt.close() + + else: + distHellinger = 0.0 + + # Bayesian inference with Emulator only for 2D problem + if post_snapshot and self.MetaModel.n_params == 2 and not idx % 5: + from bayesvalidrox.bayes_inference.bayes_inference import BayesInference + from bayesvalidrox.bayes_inference.discrepancy import Discrepancy + import pandas as pd + BayesOpts = BayesInference(self) + BayesOpts.emulator = True + BayesOpts.plot_post_pred = False + + # Select the inference method + import emcee + BayesOpts.inference_method = "MCMC" + # Set the MCMC parameters passed to self.mcmc_params + BayesOpts.mcmc_params = { + 'n_steps': 1e5, + 'n_walkers': 30, + 'moves': emcee.moves.KDEMove(), + 'verbose': False + } + + # ----- Define the discrepancy model ------- + # TODO: check with Farid if this first line is how it should be + BayesOpts.measured_data = obs_data + obs_data = pd.DataFrame(obs_data, columns=self.out_names) + BayesOpts.measurement_error = obs_data + # TODO: shouldn't the uncertainty be sigma2Dict instead of obs_data? + + # # -- (Option B) -- + DiscrepancyOpts = Discrepancy('') + DiscrepancyOpts.type = 'Gaussian' + DiscrepancyOpts.parameters = obs_data**2 + BayesOpts.Discrepancy = DiscrepancyOpts + # Start the calibration/inference + Bayes_PCE = BayesOpts.create_inference() + X_Posterior = Bayes_PCE.posterior_df.values + + return (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + # ------------------------------------------------------------------------- + def _validError(self): + """ + Evaluate the metamodel on the validation samples and calculate the + error against the corresponding model runs + + Returns + ------- + rms_error : dict + RMSE for each validation run. + valid_error : dict + Normed (?)RMSE for each validation run. + + """ + # Extract the original model with the generated samples + valid_model_runs = self.ExpDesign.valid_model_runs + + # Run the PCE model with the generated samples + valid_PCE_runs, _ = self.MetaModel.eval_metamodel(samples=self.ExpDesign.valid_samples) + + rms_error = {} + valid_error = {} + # Loop over the keys and compute RMSE error. + for key in self.out_names: + rms_error[key] = mean_squared_error( + valid_model_runs[key], valid_PCE_runs[key], + multioutput='raw_values', + sample_weight=None, + squared=False) + # Validation error + valid_error[key] = (rms_error[key]**2) + valid_error[key] /= np.var(valid_model_runs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Updated Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(rms_error[key], + valid_error[key])))) + + return rms_error, valid_error + + # ------------------------------------------------------------------------- + def _error_Mean_Std(self): + """ + Calculates the error in the overall mean and std approximation of the + surrogate against the mc-reference provided to the model. + This can only be applied to metamodels of polynomial type + + Returns + ------- + RMSE_Mean : float + RMSE of the means + RMSE_std : float + RMSE of the standard deviations + + """ + # Compute the mean and std based on the MetaModel + pce_means, pce_stds = self.MetaModel._compute_pce_moments() + + # Compute the root mean squared error + for output in self.out_names: + + # Compute the error between mean and std of MetaModel and OrigModel + RMSE_Mean = mean_squared_error( + self.Model.mc_reference['mean'], pce_means[output], squared=False + ) + RMSE_std = mean_squared_error( + self.Model.mc_reference['std'], pce_stds[output], squared=False + ) + + return RMSE_Mean, RMSE_std diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/eval_rec_rule.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/eval_rec_rule.py new file mode 100644 index 000000000..b583c7eb2 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/eval_rec_rule.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" + + +Based on the implementation in UQLab [1]. + +References: +1. S. Marelli, and B. Sudret, UQLab: A framework for uncertainty quantification +in Matlab, Proc. 2nd Int. Conf. on Vulnerability, Risk Analysis and Management +(ICVRAM2014), Liverpool, United Kingdom, 2014, 2554-2563. + +2. S. Marelli, N. Lüthen, B. Sudret, UQLab user manual – Polynomial chaos +expansions, Report # UQLab-V1.4-104, Chair of Risk, Safety and Uncertainty +Quantification, ETH Zurich, Switzerland, 2021. + +Author: Farid Mohammadi, M.Sc. +E-Mail: farid.mohammadi@iws.uni-stuttgart.de +Department of Hydromechanics and Modelling of Hydrosystems (LH2) +Institute for Modelling Hydraulic and Environmental Systems (IWS), University +of Stuttgart, www.iws.uni-stuttgart.de/lh2/ +Pfaffenwaldring 61 +70569 Stuttgart + +Created on Fri Jan 14 2022 +""" +import numpy as np +from numpy.polynomial.polynomial import polyval + + +def poly_rec_coeffs(n_max, poly_type, params=None): + """ + Computes the recurrence coefficients for classical Wiener-Askey orthogonal + polynomials. + + Parameters + ---------- + n_max : int + Maximum polynomial degree. + poly_type : string + Polynomial type. + params : list, optional + Parameters required for `laguerre` poly type. The default is None. + + Returns + ------- + AB : dict + The 3 term recursive coefficients and the applicable ranges. + + """ + + if poly_type == 'legendre': + + def an(n): + return np.zeros((n+1, 1)) + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = np.sqrt(1./(4-i**-2)) + return sq_bn + + bounds = [-1, 1] + + elif poly_type == 'hermite': + + def an(n): + return np.zeros((n+1, 1)) + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = np.sqrt(i) + return sq_bn + + bounds = [-np.inf, np.inf] + + elif poly_type == 'laguerre': + + def an(n): + a = np.zeros((n+1, 1)) + for i in range(1, n+1): + a[i] = 2*n + params[1] + return a + + def sqrt_bn(n): + sq_bn = np.zeros((n+1, 1)) + sq_bn[0, 0] = 1 + for i in range(1, n+1): + sq_bn[i, 0] = -np.sqrt(i * (i+params[1]-1)) + return sq_bn + + bounds = [0, np.inf] + + AB = {'alpha_beta': np.concatenate((an(n_max), sqrt_bn(n_max)), axis=1), + 'bounds': bounds} + + return AB + + +def eval_rec_rule(x, max_deg, poly_type): + """ + Evaluates the polynomial that corresponds to the Jacobi matrix defined + from the AB. + + Parameters + ---------- + x : array (n_samples) + Points where the polynomials are evaluated. + max_deg : int + Maximum degree. + poly_type : string + Polynomial type. + + Returns + ------- + values : array of shape (n_samples, max_deg+1) + Polynomials corresponding to the Jacobi matrix. + + """ + AB = poly_rec_coeffs(max_deg, poly_type) + AB = AB['alpha_beta'] + + values = np.zeros((len(x), AB.shape[0]+1)) + values[:, 1] = 1 / AB[0, 1] + + for k in range(AB.shape[0]-1): + values[:, k+2] = np.multiply((x - AB[k, 0]), values[:, k+1]) - \ + np.multiply(values[:, k], AB[k, 1]) + values[:, k+2] = np.divide(values[:, k+2], AB[k+1, 1]) + return values[:, 1:] + + +def eval_rec_rule_arbitrary(x, max_deg, poly_coeffs): + """ + Evaluates the polynomial at sample array x. + + Parameters + ---------- + x : array (n_samples) + Points where the polynomials are evaluated. + max_deg : int + Maximum degree. + poly_coeffs : dict + Polynomial coefficients computed based on moments. + + Returns + ------- + values : array of shape (n_samples, max_deg+1) + Univariate Polynomials evaluated at samples. + + """ + values = np.zeros((len(x), max_deg+1)) + + for deg in range(max_deg+1): + values[:, deg] = polyval(x, poly_coeffs[deg]).T + + return values + + +def eval_univ_basis(x, max_deg, poly_types, apoly_coeffs=None): + """ + Evaluates univariate regressors along input directions. + + Parameters + ---------- + x : array of shape (n_samples, n_params) + Training samples. + max_deg : int + Maximum polynomial degree. + poly_types : list of strings + List of polynomial types for all parameters. + apoly_coeffs : dict , optional + Polynomial coefficients computed based on moments. The default is None. + + Returns + ------- + univ_vals : array of shape (n_samples, n_params, max_deg+1) + Univariate polynomials for all degrees and parameters evaluated at x. + + """ + # Initilize the output array + n_samples, n_params = x.shape + univ_vals = np.zeros((n_samples, n_params, max_deg+1)) + + for i in range(n_params): + + if poly_types[i] == 'arbitrary': + polycoeffs = apoly_coeffs[f'p_{i+1}'] + univ_vals[:, i] = eval_rec_rule_arbitrary(x[:, i], max_deg, + polycoeffs) + else: + univ_vals[:, i] = eval_rec_rule(x[:, i], max_deg, poly_types[i]) + + return univ_vals diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exp_designs.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exp_designs.py new file mode 100644 index 000000000..665ee4fc3 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exp_designs.py @@ -0,0 +1,493 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import math +import itertools +import chaospy +import scipy.stats as st +from tqdm import tqdm +import h5py +import os + +from .apoly_construction import apoly_construction +from .input_space import InputSpace + +# ------------------------------------------------------------------------- +def check_ranges(theta, ranges): + """ + This function checks if theta lies in the given ranges. + + Parameters + ---------- + theta : array + Proposed parameter set. + ranges : nested list + List of the praremeter ranges. + + Returns + ------- + c : bool + If it lies in the given range, it return True else False. + + """ + c = True + # traverse in the list1 + for i, bounds in enumerate(ranges): + x = theta[i] + # condition check + if x < bounds[0] or x > bounds[1]: + c = False + return c + return c + + +class ExpDesigns(InputSpace): + """ + This class generates samples from the prescribed marginals for the model + parameters using the `Input` object. + + Attributes + ---------- + Input : obj + Input object containing the parameter marginals, i.e. name, + distribution type and distribution parameters or available raw data. + meta_Model_type : str + Type of the meta_Model_type. + sampling_method : str + Name of the sampling method for the experimental design. The following + sampling method are supported: + + * random + * latin_hypercube + * sobol + * halton + * hammersley + * chebyshev(FT) + * grid(FT) + * user + hdf5_file : str + Name of the hdf5 file that contains the experimental design. + n_new_samples : int + Number of (initial) training points. + n_max_samples : int + Number of maximum training points. + mod_LOO_threshold : float + The modified leave-one-out cross validation threshold where the + sequential design stops. + tradeoff_scheme : str + Trade-off scheme to assign weights to the exploration and exploitation + scores in the sequential design. + n_canddidate : int + Number of candidate training sets to calculate the scores for. + explore_method : str + Type of the exploration method for the sequential design. The following + methods are supported: + + * Voronoi + * random + * latin_hypercube + * LOOCV + * dual annealing + exploit_method : str + Type of the exploitation method for the sequential design. The + following methods are supported: + + * BayesOptDesign + * BayesActDesign + * VarOptDesign + * alphabetic + * Space-filling + util_func : str or list + The utility function to be specified for the `exploit_method`. For the + available utility functions see Note section. + n_cand_groups : int + Number of candidate groups. Each group of candidate training sets will + be evaulated separately in parallel. + n_replication : int + Number of replications. Only for comparison. The default is 1. + post_snapshot : int + Whether to plot the posterior in the sequential design. The default is + `True`. + step_snapshot : int + The number of steps to plot the posterior in the sequential design. The + default is 1. + max_a_post : list or array + Maximum a posteriori of the posterior distribution, if known. The + default is `[]`. + adapt_verbose : bool + Whether to plot the model response vs that of metamodel for the new + trining point in the sequential design. + + Note + ---------- + The following utiliy functions for the **exploitation** methods are + supported: + + #### BayesOptDesign (when data is available) + - DKL (Kullback-Leibler Divergence) + - DPP (D-Posterior-percision) + - APP (A-Posterior-percision) + + #### VarBasedOptDesign -> when data is not available + - Entropy (Entropy/MMSE/active learning) + - EIGF (Expected Improvement for Global fit) + - LOOCV (Leave-one-out Cross Validation) + + #### alphabetic + - D-Opt (D-Optimality) + - A-Opt (A-Optimality) + - K-Opt (K-Optimality) + """ + + def __init__(self, Input, meta_Model_type='pce', + sampling_method='random', hdf5_file=None, + n_new_samples=1, n_max_samples=None, mod_LOO_threshold=1e-16, + tradeoff_scheme=None, n_canddidate=1, explore_method='random', + exploit_method='Space-filling', util_func='Space-filling', + n_cand_groups=4, n_replication=1, post_snapshot=False, + step_snapshot=1, max_a_post=[], adapt_verbose=False, max_func_itr=1): + + self.InputObj = Input + self.meta_Model_type = meta_Model_type + self.sampling_method = sampling_method + self.hdf5_file = hdf5_file + self.n_new_samples = n_new_samples + self.n_max_samples = n_max_samples + self.mod_LOO_threshold = mod_LOO_threshold + self.explore_method = explore_method + self.exploit_method = exploit_method + self.util_func = util_func + self.tradeoff_scheme = tradeoff_scheme + self.n_canddidate = n_canddidate + self.n_cand_groups = n_cand_groups + self.n_replication = n_replication + self.post_snapshot = post_snapshot + self.step_snapshot = step_snapshot + self.max_a_post = max_a_post + self.adapt_verbose = adapt_verbose + self.max_func_itr = max_func_itr + + # Other + self.apce = None + self.ndim = None + + # Init + self.check_valid_inputs() + + # ------------------------------------------------------------------------- + def generate_samples(self, n_samples, sampling_method='random', + transform=False): + """ + Generates samples with given sampling method + + Parameters + ---------- + n_samples : int + Number of requested samples. + sampling_method : str, optional + Sampling method. The default is `'random'`. + transform : bool, optional + Transformation via an isoprobabilistic transformation method. The + default is `False`. + + Returns + ------- + samples: array of shape (n_samples, n_params) + Generated samples from defined model input object. + + """ + try: + samples = chaospy.generate_samples( + int(n_samples), domain=self.origJDist, rule=sampling_method + ) + except: + samples = self.random_sampler(int(n_samples)).T + + return samples.T + + + + # ------------------------------------------------------------------------- + def generate_ED(self, n_samples, transform=False, + max_pce_deg=None): + """ + Generates experimental designs (training set) with the given method. + + Parameters + ---------- + n_samples : int + Number of requested training points. + sampling_method : str, optional + Sampling method. The default is `'random'`. + transform : bool, optional + Isoprobabilistic transformation. The default is `False`. + max_pce_deg : int, optional + Maximum PCE polynomial degree. The default is `None`. + + Returns + ------- + None + + """ + if n_samples <0: + raise ValueError('A negative number of samples cannot be created. Please provide positive n_samples') + n_samples = int(n_samples) + + if not hasattr(self, 'n_init_samples'): + self.n_init_samples = n_samples + + # Generate the samples based on requested method + self.init_param_space(max_pce_deg) + + sampling_method = self.sampling_method + # Pass user-defined samples as ED + if sampling_method == 'user': + if not hasattr(self, 'X'): + raise AttributeError('User-defined sampling cannot proceed as no samples provided. Please add them to this class as attribute X') + if not self.X.ndim == 2: + raise AttributeError('The provided samples shuld have 2 dimensions') + samples = self.X + self.n_samples = len(samples) + + # Sample the distribution of parameters + elif self.input_data_given: + # Case II: Input values are directly given by the user. + + if sampling_method == 'random': + samples = self.random_sampler(n_samples) + + elif sampling_method == 'PCM' or \ + sampling_method == 'LSCM': + samples = self.pcm_sampler(n_samples, max_pce_deg) + + else: + # Create ExpDesign in the actual space using chaospy + try: + samples = chaospy.generate_samples(n_samples, + domain=self.JDist, + rule=sampling_method).T + except: + samples = self.JDist.resample(n_samples).T + + elif not self.input_data_given: + # Case I = User passed known distributions + samples = chaospy.generate_samples(n_samples, domain=self.JDist, + rule=sampling_method).T + + # Transform samples to the original space + if transform: + self.init_param_space(max_pce_deg) + tr_samples = self.transform( + samples, + method=sampling_method + ) + if sampling_method == 'user' or not self.apce: + self.X = samples + self.X_tr = tr_samples + #return samples, tr_samples + else: + self.X = tr_samples + self.X_tr = samples + #return tr_samples, samples # TODO: why is this swapped here? + else: + self.X = samples + self.X_tr = None + + def read_from_file(self, out_names): + """ + Reads in the ExpDesign from a provided h5py file and saves the results. + + Parameters + ---------- + out_names : list of strings + The keys that are in the outputs (y) saved in the provided file. + + Returns + ------- + None. + + """ + if self.hdf5_file == None: + raise AttributeError('ExpDesign cannot be read in, please provide hdf5 file first') + + # Read hdf5 file + f = h5py.File(self.hdf5_file, 'r+') + + # Read EDX and pass it to ExpDesign object + try: + self.X = np.array(f["EDX/New_init_"]) + except KeyError: + self.X = np.array(f["EDX/init_"]) + + # Update number of initial samples + self.n_init_samples = self.X.shape[0] + + # Read EDX and pass it to ExpDesign object + self.Y = {} + + # Extract x values + try: + self.Y["x_values"] = dict() + for varIdx, var in enumerate(out_names): + x = np.array(f[f"x_values/{var}"]) + self.Y["x_values"][var] = x + except KeyError: + self.Y["x_values"] = np.array(f["x_values"]) + + # Store the output + for varIdx, var in enumerate(out_names): + try: + y = np.array(f[f"EDY/{var}/New_init_"]) + except KeyError: + y = np.array(f[f"EDY/{var}/init_"]) + self.Y[var] = y + f.close() + print(f'Experimental Design is read in from file {self.hdf5_file}') + print('') + + + + # ------------------------------------------------------------------------- + def random_sampler(self, n_samples, max_deg = None): + """ + Samples the given raw data randomly. + + Parameters + ---------- + n_samples : int + Number of requested samples. + + max_deg : int, optional + Maximum degree. The default is `None`. + This will be used to run init_param_space, if it has not been done + until now. + + Returns + ------- + samples: array of shape (n_samples, n_params) + The sampling locations in the input space. + + """ + if not hasattr(self, 'raw_data'): + self.init_param_space(max_deg) + else: + if np.array(self.raw_data).ndim !=2: + raise AttributeError('The given raw data for sampling should have two dimensions') + samples = np.zeros((n_samples, self.ndim)) + sample_size = self.raw_data.shape[1] + + # Use a combination of raw data + if n_samples < sample_size: + for pa_idx in range(self.ndim): + # draw random indices + rand_idx = np.random.randint(0, sample_size, n_samples) + # store the raw data with given random indices + samples[:, pa_idx] = self.raw_data[pa_idx, rand_idx] + else: + try: + samples = self.JDist.resample(int(n_samples)).T + except AttributeError: + samples = self.JDist.sample(int(n_samples)).T + # Check if all samples are in the bound_tuples + for idx, param_set in enumerate(samples): + if not check_ranges(param_set, self.bound_tuples): + try: + proposed_sample = chaospy.generate_samples( + 1, domain=self.JDist, rule='random').T[0] + except: + proposed_sample = self.JDist.resample(1).T[0] + while not check_ranges(proposed_sample, + self.bound_tuples): + try: + proposed_sample = chaospy.generate_samples( + 1, domain=self.JDist, rule='random').T[0] + except: + proposed_sample = self.JDist.resample(1).T[0] + samples[idx] = proposed_sample + + return samples + + # ------------------------------------------------------------------------- + def pcm_sampler(self, n_samples, max_deg): + """ + Generates collocation points based on the root of the polynomial + degrees. + + Parameters + ---------- + n_samples : int + Number of requested samples. + max_deg : int + Maximum degree defined by user. Will also be used to run + init_param_space if that has not been done beforehand. + + Returns + ------- + opt_col_points: array of shape (n_samples, n_params) + Collocation points. + + """ + + if not hasattr(self, 'raw_data'): + self.init_param_space(max_deg) + + raw_data = self.raw_data + + # Guess the closest degree to self.n_samples + def M_uptoMax(deg): + result = [] + for d in range(1, deg+1): + result.append(math.factorial(self.ndim+d) // + (math.factorial(self.ndim) * math.factorial(d))) + return np.array(result) + #print(M_uptoMax(max_deg)) + #print(np.where(M_uptoMax(max_deg) > n_samples)[0]) + + guess_Deg = np.where(M_uptoMax(max_deg) > n_samples)[0][0] + + c_points = np.zeros((guess_Deg+1, self.ndim)) + + def PolynomialPa(parIdx): + return apoly_construction(self.raw_data[parIdx], max_deg) + + for i in range(self.ndim): + poly_coeffs = PolynomialPa(i)[guess_Deg+1][::-1] + c_points[:, i] = np.trim_zeros(np.roots(poly_coeffs)) + + # Construction of optimal integration points + Prod = itertools.product(np.arange(1, guess_Deg+2), repeat=self.ndim) + sort_dig_unique_combos = np.array(list(filter(lambda x: x, Prod))) + + # Ranking relatively mean + Temp = np.empty(shape=[0, guess_Deg+1]) + for j in range(self.ndim): + s = abs(c_points[:, j]-np.mean(raw_data[j])) + Temp = np.append(Temp, [s], axis=0) + temp = Temp.T + + index_CP = np.sort(temp, axis=0) + sort_cpoints = np.empty((0, guess_Deg+1)) + + for j in range(self.ndim): + #print(index_CP[:, j]) + sort_cp = c_points[index_CP[:, j], j] + sort_cpoints = np.vstack((sort_cpoints, sort_cp)) + + # Mapping of Combination to Cpoint Combination + sort_unique_combos = np.empty(shape=[0, self.ndim]) + for i in range(len(sort_dig_unique_combos)): + sort_un_comb = [] + for j in range(self.ndim): + SortUC = sort_cpoints[j, sort_dig_unique_combos[i, j]-1] + sort_un_comb.append(SortUC) + sort_uni_comb = np.asarray(sort_un_comb) + sort_unique_combos = np.vstack((sort_unique_combos, sort_uni_comb)) + + # Output the collocation points + if self.sampling_method.lower() == 'lscm': + opt_col_points = sort_unique_combos + else: + opt_col_points = sort_unique_combos[0:self.n_samples] + + return opt_col_points diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exploration.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exploration.py new file mode 100644 index 000000000..e18537207 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/exploration.py @@ -0,0 +1,364 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +from scipy.spatial import distance + + +class Exploration: + """ + Created based on the Surrogate Modeling Toolbox (SUMO) [1]. + + [1] Gorissen, D., Couckuyt, I., Demeester, P., Dhaene, T. and Crombecq, K., + 2010. A surrogate modeling and adaptive sampling toolbox for computer + based design. Journal of machine learning research.-Cambridge, Mass., + 11, pp.2051-2055. sumo@sumo.intec.ugent.be - http://sumo.intec.ugent.be + + Attributes + ---------- + ExpDesign : obj + ExpDesign object. + n_candidate : int + Number of candidate samples. + mc_criterion : str + Selection crieterion. The default is `'mc-intersite-proj-th'`. Another + option is `'mc-intersite-proj'`. + w : int + Number of random points in the domain for each sample of the + training set. + """ + + def __init__(self, ExpDesign, n_candidate, + mc_criterion='mc-intersite-proj-th'): + self.ExpDesign = ExpDesign + self.n_candidate = n_candidate + self.mc_criterion = mc_criterion + self.w = 100 + + def get_exploration_samples(self): + """ + This function generates candidates to be selected as new design and + their associated exploration scores. + + Returns + ------- + all_candidates : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + explore_method = self.ExpDesign.explore_method + + print("\n") + print(f' The {explore_method}-Method is selected as the exploration ' + 'method.') + print("\n") + + if explore_method == 'Voronoi': + # Generate samples using the Voronoi method + all_candidates, exploration_scores = self.get_vornoi_samples() + else: + # Generate samples using the MC method + all_candidates, exploration_scores = self.get_mc_samples() + + return all_candidates, exploration_scores + + # ------------------------------------------------------------------------- + def get_vornoi_samples(self): + """ + This function generates samples based on voronoi cells and their + corresponding scores + + Returns + ------- + new_samples : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + + mc_criterion = self.mc_criterion + n_candidate = self.n_candidate + # Get the Old ExpDesign #samples + old_ED_X = self.ExpDesign.X + ndim = old_ED_X.shape[1] + + # calculate error #averageErrors + error_voronoi, all_candidates = self.approximate_voronoi( + self.w, old_ED_X + ) + + # Pick the best candidate point in the voronoi cell + # for each best sample + selected_samples = np.empty((0, ndim)) + bad_samples = [] + + for index in range(len(error_voronoi)): + + # get candidate new samples from voronoi tesselation + candidates = self.closest_points[index] + + # get total number of candidates + n_new_samples = candidates.shape[0] + + # still no candidate samples around this one, skip it! + if n_new_samples == 0: + print('The following sample has been skipped because there ' + 'were no candidate samples around it...') + print(old_ED_X[index]) + bad_samples.append(index) + continue + + # find candidate that is farthest away from any existing sample + max_min_distance = 0 + best_candidate = 0 + min_intersite_dist = np.zeros((n_new_samples)) + min_projected_dist = np.zeros((n_new_samples)) + + for j in range(n_new_samples): + + new_samples = np.vstack((old_ED_X, selected_samples)) + + # find min distorted distance from all other samples + euclidean_dist = self._build_dist_matrix_point( + new_samples, candidates[j], do_sqrt=True) + min_euclidean_dist = np.min(euclidean_dist) + min_intersite_dist[j] = min_euclidean_dist + + # Check if this is the maximum minimum distance from all other + # samples + if min_euclidean_dist >= max_min_distance: + max_min_distance = min_euclidean_dist + best_candidate = j + + # Projected distance + projected_dist = distance.cdist( + new_samples, [candidates[j]], 'chebyshev') + min_projected_dist[j] = np.min(projected_dist) + + if mc_criterion == 'mc-intersite-proj': + weight_euclidean_dist = 0.5 * ((n_new_samples+1)**(1/ndim) - 1) + weight_projected_dist = 0.5 * (n_new_samples+1) + total_dist_scores = weight_euclidean_dist * min_intersite_dist + total_dist_scores += weight_projected_dist * min_projected_dist + + elif mc_criterion == 'mc-intersite-proj-th': + alpha = 0.5 # chosen (tradeoff) + d_min = 2 * alpha / n_new_samples + if any(min_projected_dist < d_min): + candidates = np.delete( + candidates, [min_projected_dist < d_min], axis=0 + ) + total_dist_scores = np.delete( + min_intersite_dist, [min_projected_dist < d_min], + axis=0 + ) + else: + total_dist_scores = min_intersite_dist + else: + raise NameError( + 'The MC-Criterion you requested is not available.' + ) + + # Add the best candidate to the list of new samples + best_candidate = np.argsort(total_dist_scores)[::-1][:n_candidate] + selected_samples = np.vstack( + (selected_samples, candidates[best_candidate]) + ) + + self.new_samples = selected_samples + self.exploration_scores = np.delete(error_voronoi, bad_samples, axis=0) + + return self.new_samples, self.exploration_scores + + # ------------------------------------------------------------------------- + def get_mc_samples(self, all_candidates=None): + """ + This function generates random samples based on Global Monte Carlo + methods and their corresponding scores, based on [1]. + + [1] Crombecq, K., Laermans, E. and Dhaene, T., 2011. Efficient + space-filling and non-collapsing sequential design strategies for + simulation-based modeling. European Journal of Operational Research + , 214(3), pp.683-696. + DOI: https://doi.org/10.1016/j.ejor.2011.05.032 + + Implemented methods to compute scores: + 1) mc-intersite-proj + 2) mc-intersite-proj-th + + Arguments + --------- + all_candidates : array, optional + Samples to compute the scores for. The default is `None`. In this + case, samples will be generated by defined model input marginals. + + Returns + ------- + new_samples : array of shape (n_candidate, n_params) + A list of samples. + exploration_scores: arrays of shape (n_candidate) + Exploration scores. + """ + explore_method = self.ExpDesign.explore_method + mc_criterion = self.mc_criterion + if all_candidates is None: + n_candidate = self.n_candidate + else: + n_candidate = all_candidates.shape[0] + + # Get the Old ExpDesign #samples + old_ED_X = self.ExpDesign.X + ndim = old_ED_X.shape[1] + + # ----- Compute the number of random points ----- + if all_candidates is None: + # Generate MC Samples + all_candidates = self.ExpDesign.generate_samples( + self.n_candidate, explore_method + ) + self.all_candidates = all_candidates + + # initialization + min_intersite_dist = np.zeros((n_candidate)) + min_projected_dist = np.zeros((n_candidate)) + + for i, candidate in enumerate(all_candidates): + + # find candidate that is farthest away from any existing sample + maxMinDistance = 0 + + # find min distorted distance from all other samples + euclidean_dist = self._build_dist_matrix_point( + old_ED_X, candidate, do_sqrt=True + ) + min_euclidean_dist = np.min(euclidean_dist) + min_intersite_dist[i] = min_euclidean_dist + + # Check if this is the maximum minimum distance from all other + # samples + if min_euclidean_dist >= maxMinDistance: + maxMinDistance = min_euclidean_dist + + # Projected distance + projected_dist = self._build_dist_matrix_point( + old_ED_X, candidate, 'chebyshev' + ) + min_projected_dist[i] = np.min(projected_dist) + + if mc_criterion == 'mc-intersite-proj': + weight_euclidean_dist = ((n_candidate+1)**(1/ndim) - 1) * 0.5 + weight_projected_dist = (n_candidate+1) * 0.5 + total_dist_scores = weight_euclidean_dist * min_intersite_dist + total_dist_scores += weight_projected_dist * min_projected_dist + + elif mc_criterion == 'mc-intersite-proj-th': + alpha = 0.5 # chosen (tradeoff) + d_min = 2 * alpha / n_candidate + if any(min_projected_dist < d_min): + all_candidates = np.delete( + all_candidates, [min_projected_dist < d_min], axis=0 + ) + total_dist_scores = np.delete( + min_intersite_dist, [min_projected_dist < d_min], axis=0 + ) + else: + total_dist_scores = min_intersite_dist + else: + raise NameError('The MC-Criterion you requested is not available.') + + self.new_samples = all_candidates + self.exploration_scores = total_dist_scores + self.exploration_scores /= np.nansum(total_dist_scores) + + return self.new_samples, self.exploration_scores + + # ------------------------------------------------------------------------- + def approximate_voronoi(self, w, samples): + """ + An approximate (monte carlo) version of Matlab's voronoi command. + + Arguments + --------- + samples : array + Old experimental design to be used as center points for voronoi + cells. + + Returns + ------- + areas : array + An approximation of the voronoi cells' areas. + all_candidates: list of arrays + A list of samples in each voronoi cell. + """ + n_samples = samples.shape[0] + ndim = samples.shape[1] + + # Compute the number of random points + n_points = w * samples.shape[0] + # Generate w random points in the domain for each sample + points = self.ExpDesign.generate_samples(n_points, 'random') + self.all_candidates = points + + # Calculate the nearest sample to each point + self.areas = np.zeros((n_samples)) + self.closest_points = [np.empty((0, ndim)) for i in range(n_samples)] + + # Compute the minimum distance from all the samples of old_ED_X for + # each test point + for idx in range(n_points): + # calculate the minimum distance + distances = self._build_dist_matrix_point( + samples, points[idx], do_sqrt=True + ) + closest_sample = np.argmin(distances) + + # Add to the voronoi list of the closest sample + self.areas[closest_sample] = self.areas[closest_sample] + 1 + prev_closest_points = self.closest_points[closest_sample] + self.closest_points[closest_sample] = np.vstack( + (prev_closest_points, points[idx]) + ) + + # Divide by the amount of points to get the estimated volume of each + # voronoi cell + self.areas /= n_points + + self.perc = np.max(self.areas * 100) + + self.errors = self.areas + + return self.areas, self.all_candidates + + # ------------------------------------------------------------------------- + def _build_dist_matrix_point(self, samples, point, method='euclidean', + do_sqrt=False): + """ + Calculates the intersite distance of all points in samples from point. + + Parameters + ---------- + samples : array of shape (n_samples, n_params) + The old experimental design. + point : array + A candidate point. + method : str + Distance method. + do_sqrt : bool, optional + Whether to return distances or squared distances. The default is + `False`. + + Returns + ------- + distances : array + Distances. + + """ + distances = distance.cdist(samples, np.array([point]), method) + + # do square root? + if do_sqrt: + return distances + else: + return distances**2 + diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/glexindex.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/glexindex.py new file mode 100644 index 000000000..90877331e --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/glexindex.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Multi indices for monomial exponents. +Credit: Jonathan Feinberg +https://github.com/jonathf/numpoly/blob/master/numpoly/utils/glexindex.py +""" + +import numpy +import numpy.typing + + +def glexindex(start, stop=None, dimensions=1, cross_truncation=1., + graded=False, reverse=False): + """ + Generate graded lexicographical multi-indices for the monomial exponents. + Args: + start (Union[int, numpy.ndarray]): + The lower order of the indices. If array of int, counts as lower + bound for each axis. + stop (Union[int, numpy.ndarray, None]): + The maximum shape included. If omitted: stop <- start; start <- 0 + If int is provided, set as largest total order. If array of int, + set as upper bound for each axis. + dimensions (int): + The number of dimensions in the expansion. + cross_truncation (float, Tuple[float, float]): + Use hyperbolic cross truncation scheme to reduce the number of + terms in expansion. If two values are provided, first is low bound + truncation, while the latter upper bound. If only one value, upper + bound is assumed. + graded (bool): + Graded sorting, meaning the indices are always sorted by the index + sum. E.g. ``(2, 2, 2)`` has a sum of 6, and will therefore be + consider larger than both ``(3, 1, 1)`` and ``(1, 1, 3)``. + reverse (bool): + Reversed lexicographical sorting meaning that ``(1, 3)`` is + considered smaller than ``(3, 1)``, instead of the opposite. + Returns: + list: + Order list of indices. + Examples: + >>> numpoly.glexindex(4).tolist() + [[0], [1], [2], [3]] + >>> numpoly.glexindex(2, dimensions=2).tolist() + [[0, 0], [1, 0], [0, 1]] + >>> numpoly.glexindex(start=2, stop=3, dimensions=2).tolist() + [[2, 0], [1, 1], [0, 2]] + >>> numpoly.glexindex([1, 2, 3]).tolist() + [[0, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 2]] + >>> numpoly.glexindex([1, 2, 3], cross_truncation=numpy.inf).tolist() + [[0, 0, 0], [0, 1, 0], [0, 0, 1], [0, 1, 1], [0, 0, 2], [0, 1, 2]] + """ + if stop is None: + start, stop = 0, start + start = numpy.array(start, dtype=int).flatten() + stop = numpy.array(stop, dtype=int).flatten() + start, stop, _ = numpy.broadcast_arrays(start, stop, numpy.empty(dimensions)) + + cross_truncation = cross_truncation*numpy.ones(2) + + # Moved here from _glexindex + bound = stop.max() + dimensions = len(start) + start = numpy.clip(start, a_min=0, a_max=None) + dtype = numpy.uint8 if bound < 256 else numpy.uint16 + range_ = numpy.arange(bound, dtype=dtype) + indices = range_[:, numpy.newaxis] + + for idx in range(dimensions-1): + + # Truncate at each step to keep memory usage low + if idx: + indices = indices[cross_truncate(indices, bound-1, cross_truncation[1])] + + # Repeats the current set of indices. + # e.g. [0,1,2] -> [0,1,2,0,1,2,...,0,1,2] + indices = numpy.tile(indices, (bound, 1)) + + # Stretches ranges over the new dimension. + # e.g. [0,1,2] -> [0,0,...,0,1,1,...,1,2,2,...,2] + front = range_.repeat(len(indices)//bound)[:, numpy.newaxis] + + # Puts them two together. + indices = numpy.column_stack((front, indices)) + + # Complete the truncation scheme + if dimensions == 1: + indices = indices[(indices >= start) & (indices < bound)] + else: + lower = cross_truncate(indices, start-1, cross_truncation[0]) + upper = cross_truncate(indices, stop-1, cross_truncation[1]) + indices = indices[lower ^ upper] + + indices = numpy.array(indices, dtype=int).reshape(-1, dimensions) + if indices.size: + # moved here from glexsort + keys = indices.T + keys_ = numpy.atleast_2d(keys) + if reverse: + keys_ = keys_[::-1] + + indices_sort = numpy.array(numpy.lexsort(keys_)) + if graded: + indices_sort = indices_sort[numpy.argsort( + numpy.sum(keys_[:, indices_sort], axis=0))].T + + indices = indices[indices_sort] + return indices + +def cross_truncate(indices, bound, norm): + r""" + Truncate of indices using L_p norm. + .. math: + L_p(x) = \sum_i |x_i/b_i|^p ^{1/p} \leq 1 + where :math:`b_i` are bounds that each :math:`x_i` should follow. + Args: + indices (Sequence[int]): + Indices to be truncated. + bound (int, Sequence[int]): + The bound function for witch the indices can not be larger than. + norm (float, Sequence[float]): + The `p` in the `L_p`-norm. Support includes both `L_0` and `L_inf`. + Returns: + Boolean indices to ``indices`` with True for each index where the + truncation criteria holds. + Examples: + >>> indices = numpy.array(numpy.mgrid[:10, :10]).reshape(2, -1).T + >>> indices[cross_truncate(indices, 2, norm=0)].T + array([[0, 0, 0, 1, 2], + [0, 1, 2, 0, 0]]) + >>> indices[cross_truncate(indices, 2, norm=1)].T + array([[0, 0, 0, 1, 1, 2], + [0, 1, 2, 0, 1, 0]]) + >>> indices[cross_truncate(indices, [0, 1], norm=1)].T + array([[0, 0], + [0, 1]]) + """ + assert norm >= 0, "negative L_p norm not allowed" + bound = numpy.asfarray(bound).flatten()*numpy.ones(indices.shape[1]) + + if numpy.any(bound < 0): + return numpy.zeros((len(indices),), dtype=bool) + + if numpy.any(bound == 0): + out = numpy.all(indices[:, bound == 0] == 0, axis=-1) + if numpy.any(bound): + out &= cross_truncate(indices[:, bound != 0], bound[bound != 0], norm=norm) + return out + + if norm == 0: + out = numpy.sum(indices > 0, axis=-1) <= 1 + out[numpy.any(indices > bound, axis=-1)] = False + elif norm == numpy.inf: + out = numpy.max(indices/bound, axis=-1) <= 1 + else: + out = numpy.sum((indices/bound)**norm, axis=-1)**(1./norm) <= 1 + + assert numpy.all(out[numpy.all(indices == 0, axis=-1)]) + + return out diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/input_space.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/input_space.py new file mode 100644 index 000000000..3160ba2d0 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/input_space.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import chaospy +import scipy.stats as st + + +class InputSpace: + """ + This class generates the input space for the metamodel from the + distributions provided using the `Input` object. + + Attributes + ---------- + Input : obj + Input object containing the parameter marginals, i.e. name, + distribution type and distribution parameters or available raw data. + meta_Model_type : str + Type of the meta_Model_type. + + """ + + def __init__(self, Input, meta_Model_type='pce'): + self.InputObj = Input + self.meta_Model_type = meta_Model_type + + # Other + self.apce = None + self.ndim = None + + # Init + self.check_valid_inputs() + + + def check_valid_inputs(self)-> None: + """ + Check if the given InputObj is valid to use for further calculations: + Has some Marginals + Marginals have valid priors + All Marginals given as the same type (samples vs dist) + + Returns + ------- + None + + """ + Inputs = self.InputObj + self.ndim = len(Inputs.Marginals) + + # Check if PCE or aPCE metamodel is selected. + # TODO: test also for 'pce'?? + if self.meta_Model_type.lower() == 'apce': + self.apce = True + else: + self.apce = False + + # check if marginals given + if not self.ndim >=1: + raise AssertionError('Cannot build distributions if no marginals are given') + + # check that each marginal is valid + for marginals in Inputs.Marginals: + if len(marginals.input_data) == 0: + if marginals.dist_type == None: + raise AssertionError('Not all marginals were provided priors') + break + if np.array(marginals.input_data).shape[0] and (marginals.dist_type != None): + raise AssertionError('Both samples and distribution type are given. Please choose only one.') + break + + # Check if input is given as dist or input_data. + self.input_data_given = -1 + for marg in Inputs.Marginals: + #print(self.input_data_given) + size = np.array(marg.input_data).shape[0] + #print(f'Size: {size}') + if size and abs(self.input_data_given) !=1: + self.input_data_given = 2 + break + if (not size) and self.input_data_given > 0: + self.input_data_given = 2 + break + if not size: + self.input_data_given = 0 + if size: + self.input_data_given = 1 + + if self.input_data_given == 2: + raise AssertionError('Distributions cannot be built as the priors have different types') + + + # Get the bounds if input_data are directly defined by user: + if self.input_data_given: + for i in range(self.ndim): + low_bound = np.min(Inputs.Marginals[i].input_data) + up_bound = np.max(Inputs.Marginals[i].input_data) + Inputs.Marginals[i].parameters = [low_bound, up_bound] + + + + # ------------------------------------------------------------------------- + def init_param_space(self, max_deg=None): + """ + Initializes parameter space. + + Parameters + ---------- + max_deg : int, optional + Maximum degree. The default is `None`. + + Creates + ------- + raw_data : array of shape (n_params, n_samples) + Raw data. + bound_tuples : list of tuples + A list containing lower and upper bounds of parameters. + + """ + # Recheck all before running! + self.check_valid_inputs() + + Inputs = self.InputObj + ndim = self.ndim + rosenblatt_flag = Inputs.Rosenblatt + mc_size = 50000 + + # Save parameter names + self.par_names = [] + for parIdx in range(ndim): + self.par_names.append(Inputs.Marginals[parIdx].name) + + # Create a multivariate probability distribution + # TODO: change this to make max_deg obligatory? at least in some specific cases? + if max_deg is not None: + JDist, poly_types = self.build_polytypes(rosenblatt=rosenblatt_flag) + self.JDist, self.poly_types = JDist, poly_types + + if self.input_data_given: + self.MCSize = len(Inputs.Marginals[0].input_data) + self.raw_data = np.zeros((ndim, self.MCSize)) + + for parIdx in range(ndim): + # Save parameter names + try: + self.raw_data[parIdx] = np.array( + Inputs.Marginals[parIdx].input_data) + except: + self.raw_data[parIdx] = self.JDist[parIdx].sample(mc_size) + + else: + # Generate random samples based on parameter distributions + self.raw_data = chaospy.generate_samples(mc_size, + domain=self.JDist) + + # Extract moments + for parIdx in range(ndim): + mu = np.mean(self.raw_data[parIdx]) + std = np.std(self.raw_data[parIdx]) + self.InputObj.Marginals[parIdx].moments = [mu, std] + + # Generate the bounds based on given inputs for marginals + bound_tuples = [] + for i in range(ndim): + if Inputs.Marginals[i].dist_type == 'unif': + low_bound = Inputs.Marginals[i].parameters[0] + up_bound = Inputs.Marginals[i].parameters[1] + else: + low_bound = np.min(self.raw_data[i]) + up_bound = np.max(self.raw_data[i]) + + bound_tuples.append((low_bound, up_bound)) + + self.bound_tuples = tuple(bound_tuples) + + # ------------------------------------------------------------------------- + def build_polytypes(self, rosenblatt): + """ + Creates the polynomial types to be passed to univ_basis_vals method of + the MetaModel object. + + Parameters + ---------- + rosenblatt : bool + Rosenblatt transformation flag. + + Returns + ------- + orig_space_dist : object + A chaospy JDist object or a gaussian_kde object. + poly_types : list + List of polynomial types for the parameters. + + """ + Inputs = self.InputObj + + all_data = [] + all_dist_types = [] + orig_joints = [] + poly_types = [] + + for parIdx in range(self.ndim): + + if Inputs.Marginals[parIdx].dist_type is None: + data = Inputs.Marginals[parIdx].input_data + all_data.append(data) + dist_type = None + else: + dist_type = Inputs.Marginals[parIdx].dist_type + params = Inputs.Marginals[parIdx].parameters + + if rosenblatt: + polytype = 'hermite' + dist = chaospy.Normal() + + elif dist_type is None: + polytype = 'arbitrary' + dist = None + + elif 'unif' in dist_type.lower(): + polytype = 'legendre' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Uniform(lower=params[0], upper=params[1]) + + elif 'norm' in dist_type.lower() and \ + 'log' not in dist_type.lower(): + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + polytype = 'hermite' + dist = chaospy.Normal(mu=params[0], sigma=params[1]) + + elif 'gamma' in dist_type.lower(): + polytype = 'laguerre' + if not np.array(params).shape[0]>=3: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Gamma(shape=params[0], + scale=params[1], + shift=params[2]) + + elif 'beta' in dist_type.lower(): + if not np.array(params).shape[0]>=4: + raise AssertionError('Distribution has too few parameters!') + polytype = 'jacobi' + dist = chaospy.Beta(alpha=params[0], beta=params[1], + lower=params[2], upper=params[3]) + + elif 'lognorm' in dist_type.lower(): + polytype = 'hermite' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + mu = np.log(params[0]**2/np.sqrt(params[0]**2 + params[1]**2)) + sigma = np.sqrt(np.log(1 + params[1]**2 / params[0]**2)) + dist = chaospy.LogNormal(mu, sigma) + # dist = chaospy.LogNormal(mu=params[0], sigma=params[1]) + + elif 'expon' in dist_type.lower(): + polytype = 'exponential' + if not np.array(params).shape[0]>=2: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Exponential(scale=params[0], shift=params[1]) + + elif 'weibull' in dist_type.lower(): + polytype = 'weibull' + if not np.array(params).shape[0]>=3: + raise AssertionError('Distribution has too few parameters!') + dist = chaospy.Weibull(shape=params[0], scale=params[1], + shift=params[2]) + + else: + message = (f"DistType {dist_type} for parameter" + f"{parIdx+1} is not available.") + raise ValueError(message) + + if self.input_data_given or self.apce: + polytype = 'arbitrary' + + # Store dists and poly_types + orig_joints.append(dist) + poly_types.append(polytype) + all_dist_types.append(dist_type) + + # Prepare final output to return + if None in all_dist_types: + # Naive approach: Fit a gaussian kernel to the provided data + Data = np.asarray(all_data) + try: + orig_space_dist = st.gaussian_kde(Data) + except: + raise ValueError('The samples provided to the Marginals should be 1D only') + self.prior_space = orig_space_dist + else: + orig_space_dist = chaospy.J(*orig_joints) + try: + self.prior_space = st.gaussian_kde(orig_space_dist.sample(10000)) + except: + raise ValueError('Parameter values are not valid, please set differently') + + return orig_space_dist, poly_types + + # ------------------------------------------------------------------------- + def transform(self, X, params=None, method=None): + """ + Transforms the samples via either a Rosenblatt or an isoprobabilistic + transformation. + + Parameters + ---------- + X : array of shape (n_samples,n_params) + Samples to be transformed. + method : string + If transformation method is 'user' transform X, else just pass X. + + Returns + ------- + tr_X: array of shape (n_samples,n_params) + Transformed samples. + + """ + # Check for built JDist + if not hasattr(self, 'JDist'): + raise AttributeError('Call function init_param_space first to create JDist') + + # Check if X is 2d + if X.ndim != 2: + raise AttributeError('X should have two dimensions') + + # Check if size of X matches Marginals + if X.shape[1]!= self.ndim: + raise AttributeError('The second dimension of X should be the same size as the number of marginals in the InputObj') + + if self.InputObj.Rosenblatt: + self.origJDist, _ = self.build_polytypes(False) + if method == 'user': + tr_X = self.JDist.inv(self.origJDist.fwd(X.T)).T + else: + # Inverse to original spcace -- generate sample ED + tr_X = self.origJDist.inv(self.JDist.fwd(X.T)).T + else: + # Transform samples via an isoprobabilistic transformation + n_samples, n_params = X.shape + Inputs = self.InputObj + origJDist = self.JDist + poly_types = self.poly_types + + disttypes = [] + for par_i in range(n_params): + disttypes.append(Inputs.Marginals[par_i].dist_type) + + # Pass non-transformed X, if arbitrary PCE is selected. + if None in disttypes or self.input_data_given or self.apce: + return X + + cdfx = np.zeros((X.shape)) + tr_X = np.zeros((X.shape)) + + for par_i in range(n_params): + + # Extract the parameters of the original space + disttype = disttypes[par_i] + if disttype is not None: + dist = origJDist[par_i] + else: + dist = None + polytype = poly_types[par_i] + cdf = np.vectorize(lambda x: dist.cdf(x)) + + # Extract the parameters of the transformation space based on + # polyType + if polytype == 'legendre' or disttype == 'uniform': + # Generate Y_Dists based + params_Y = [-1, 1] + dist_Y = st.uniform(loc=params_Y[0], + scale=params_Y[1]-params_Y[0]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + elif polytype == 'hermite' or disttype == 'norm': + params_Y = [0, 1] + dist_Y = st.norm(loc=params_Y[0], scale=params_Y[1]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + elif polytype == 'laguerre' or disttype == 'gamma': + if params == None: + raise AttributeError('Additional parameters have to be set for the gamma distribution!') + params_Y = [1, params[1]] + dist_Y = st.gamma(loc=params_Y[0], scale=params_Y[1]) + inv_cdf = np.vectorize(lambda x: dist_Y.ppf(x)) + + # Compute CDF_x(X) + cdfx[:, par_i] = cdf(X[:, par_i]) + + # Compute invCDF_y(cdfx) + tr_X[:, par_i] = inv_cdf(cdfx[:, par_i]) + + return tr_X diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/inputs.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/inputs.py new file mode 100644 index 000000000..783e82b05 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/inputs.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +class Input: + """ + A class to define the uncertain input parameters. + + Attributes + ---------- + Marginals : obj + Marginal objects. See `inputs.Marginal`. + Rosenblatt : bool + If Rossenblatt transformation is required for the dependent input + parameters. + + Examples + ------- + Marginals can be defined as following: + + >>> Inputs.add_marginals() + >>> Inputs.Marginals[0].name = 'X_1' + >>> Inputs.Marginals[0].dist_type = 'uniform' + >>> Inputs.Marginals[0].parameters = [-5, 5] + + If there is no common data is avaliable, the input data can be given + as following: + + >>> Inputs.add_marginals() + >>> Inputs.Marginals[0].name = 'X_1' + >>> Inputs.Marginals[0].input_data = input_data + """ + poly_coeffs_flag = True + + def __init__(self): + self.Marginals = [] + self.Rosenblatt = False + + def add_marginals(self): + """ + Adds a new Marginal object to the input object. + + Returns + ------- + None. + + """ + self.Marginals.append(Marginal()) + + +# Nested class +class Marginal: + """ + An object containing the specifications of the marginals for each uncertain + parameter. + + Attributes + ---------- + name : string + Name of the parameter. The default is `'$x_1$'`. + dist_type : string + Name of the distribution. The default is `None`. + parameters : list + List of the parameters corresponding to the distribution type. The + default is `None`. + input_data : array + Available input data. The default is `[]`. + moments : list + List of the moments. + """ + + def __init__(self): + self.name = '$x_1$' + self.dist_type = None + self.parameters = None + self.input_data = [] + self.moments = None diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py new file mode 100644 index 000000000..96ef9c1d5 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Jul 15 14:08:59 2022 + +@author: farid +""" +import numpy as np +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +from sklearn.utils import check_X_y + + +def corr(x, y): + return abs(x.dot(y))/np.sqrt((x**2).sum()) + + +class OrthogonalMatchingPursuit(LinearModel, RegressorMixin): + ''' + Regression with Orthogonal Matching Pursuit [1]. + + Parameters + ---------- + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + References + ---------- + [1] Pati, Y., Rezaiifar, R., Krishnaprasad, P. (1993). Orthogonal matching + pursuit: recursive function approximation with application to wavelet + decomposition. Proceedings of 27th Asilomar Conference on Signals, + Systems and Computers, 40-44. + ''' + + def __init__(self, fit_intercept=True, normalize=False, copy_X=True, + verbose=False): + self.fit_intercept = fit_intercept + self.normalize = normalize + self.copy_X = copy_X + self.verbose = verbose + + def _preprocess_data(self, X, y): + """Center and scale data. + Centers data to have mean zero along axis 0. If fit_intercept=False or + if the X is a sparse matrix, no centering is done, but normalization + can still be applied. The function returns the statistics necessary to + reconstruct the input data, which are X_offset, y_offset, X_scale, such + that the output + X = (X - X_offset) / X_scale + X_scale is the L2 norm of X - X_offset. + """ + + if self.copy_X: + X = X.copy(order='K') + + y = np.asarray(y, dtype=X.dtype) + + if self.fit_intercept: + X_offset = np.average(X, axis=0) + X -= X_offset + if self.normalize: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + std = np.sqrt(np.sum(X**2, axis=0)/(len(X)-1)) + X_scale[std != 0] = std[std != 0] + X /= X_scale + else: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + y_offset = np.mean(y) + y = y - y_offset + else: + X_offset = np.zeros(X.shape[1], dtype=X.dtype) + X_scale = np.ones(X.shape[1], dtype=X.dtype) + if y.ndim == 1: + y_offset = X.dtype.type(0) + else: + y_offset = np.zeros(y.shape[1], dtype=X.dtype) + + return X, y, X_offset, y_offset, X_scale + + def fit(self, X, y): + ''' + Fits Regression with Orthogonal Matching Pursuit Algorithm. + + Parameters + ----------- + X: {array-like, sparse matrix} of size (n_samples, n_features) + Training data, matrix of explanatory variables + + y: array-like of size [n_samples, n_features] + Target values + + Returns + ------- + self : object + Returns self. + ''' + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._preprocess_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # Normalize columns of Psi, so that each column has norm = 1 + norm_X = np.linalg.norm(X, axis=0) + X_norm = X/norm_X + + # Initialize residual vector to full model response and normalize + R = y + norm_y = np.sqrt(np.dot(y, y)) + r = y/norm_y + + # Check for constant regressors + const_indices = np.where(~np.diff(X, axis=0).any(axis=0))[0] + bool_const = not const_indices + + # Start regression using OPM algorithm + precision = 0 # Set precision criterion to precision of program + early_stop = True + cond_early = True # Initialize condition for early stop + ind = [] + iindx = [] # index of selected columns + indtot = np.arange(n_features) # Full index set for remaining columns + kmax = min(n_samples, n_features) # Maximum number of iterations + LOO = np.PINF * np.ones(kmax) # Store LOO error at each iteration + LOOmin = np.PINF # Initialize minimum value of LOO + coeff = np.zeros((n_features, kmax)) + count = 0 + k = 0.1 # Percentage of iteration history for early stop + + # Begin iteration over regressors set (Matrix X) + while (np.linalg.norm(R) > precision) and (count <= kmax-1) and \ + ((cond_early or early_stop) ^ ~cond_early): + + # Update index set of columns yet to select + if count != 0: + indtot = np.delete(indtot, iindx) + + # Find column of X that is most correlated with residual + h = abs(np.dot(r, X_norm)) + iindx = np.argmax(h[indtot]) + indx = indtot[iindx] + + # initialize with the constant regressor, if it exists in the basis + if (count == 0) and bool_const: + # overwrite values for iindx and indx + iindx = const_indices[0] + indx = indtot[iindx] + + # Invert the information matrix at the first iteration, later only + # update its value on the basis of the previously inverted one, + if count == 0: + M = 1 / np.dot(X[:, indx], X[:, indx]) + else: + x = np.dot(X[:, ind].T, X[:, indx]) + r = np.dot(X[:, indx], X[:, indx]) + M = self.blockwise_inverse(M, x, x.T, r) + + # Add newly found index to the selected indexes set + ind.append(indx) + + # Select regressors subset (Projection subspace) + Xpro = X[:, ind] + + # Obtain coefficient by performing OLS + TT = np.dot(y, Xpro) + beta = np.dot(M, TT) + coeff[ind, count] = beta + + # Compute LOO error + LOO[count] = self.loo_error(Xpro, M, y, beta) + + # Compute new residual due to new projection + R = y - np.dot(Xpro, beta) + + # Normalize residual + norm_R = np.sqrt(np.dot(R, R)) + r = R / norm_R + + # Update counters and early-stop criterions + countinf = max(0, int(count-k*kmax)) + LOOmin = min(LOOmin, LOO[count]) + + if count == 0: + cond_early = (LOO[0] <= LOOmin) + else: + cond_early = (min(LOO[countinf:count+1]) <= LOOmin) + + if self.verbose: + print(f'Iteration: {count+1}, mod. LOOCV error : ' + f'{LOO[count]:.2e}') + + # Update counter + count += 1 + + # Select projection with smallest cross-validation error + countmin = np.argmin(LOO[:-1]) + self.coef_ = coeff[:, countmin] + self.active = coeff[:, countmin] != 0.0 + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self, X): + ''' + Computes predictive distribution for test set. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + ''' + + y_hat = np.dot(X, self.coef_) + self.intercept_ + + return y_hat + + def loo_error(self, psi, inv_inf_matrix, y, coeffs): + """ + Calculates the corrected LOO error for regression on regressor + matrix `psi` that generated the coefficients based on [1] and [2]. + + [1] Blatman, G., 2009. Adaptive sparse polynomial chaos expansions for + uncertainty propagation and sensitivity analysis (Doctoral + dissertation, Clermont-Ferrand 2). + + [2] Blatman, G. and Sudret, B., 2011. Adaptive sparse polynomial chaos + expansion based on least angle regression. Journal of computational + Physics, 230(6), pp.2345-2367. + + Parameters + ---------- + psi : array of shape (n_samples, n_feature) + Orthogonal bases evaluated at the samples. + inv_inf_matrix : array + Inverse of the information matrix. + y : array of shape (n_samples, ) + Targets. + coeffs : array + Computed regresssor cofficients. + + Returns + ------- + loo_error : float + Modified LOOCV error. + + """ + + # NrEvaluation (Size of experimental design) + N, P = psi.shape + + # h factor (the full matrix is not calculated explicitly, + # only the trace is, to save memory) + PsiM = np.dot(psi, inv_inf_matrix) + + h = np.sum(np.multiply(PsiM, psi), axis=1, dtype=np.longdouble) + + # ------ Calculate Error Loocv for each measurement point ---- + # Residuals + residual = np.dot(psi, coeffs) - y + + # Variance + varY = np.var(y) + + if varY == 0: + norm_emp_error = 0 + loo_error = 0 + else: + norm_emp_error = np.mean(residual**2)/varY + + loo_error = np.mean(np.square(residual / (1-h))) / varY + + # if there are NaNs, just return an infinite LOO error (this + # happens, e.g., when a strongly underdetermined problem is solved) + if np.isnan(loo_error): + loo_error = np.inf + + # Corrected Error for over-determined system + tr_M = np.trace(np.atleast_2d(inv_inf_matrix)) + if tr_M < 0 or abs(tr_M) > 1e6: + tr_M = np.trace(np.linalg.pinv(np.dot(psi.T, psi))) + + # Over-determined system of Equation + if N > P: + T_factor = N/(N-P) * (1 + tr_M) + + # Under-determined system of Equation + else: + T_factor = np.inf + + loo_error *= T_factor + + return loo_error + + def blockwise_inverse(self, Ainv, B, C, D): + """ + non-singular square matrix M defined as M = [[A B]; [C D]] . + B, C and D can have any dimension, provided their combination defines + a square matrix M. + + Parameters + ---------- + Ainv : float or array + inverse of the square-submatrix A. + B : float or array + Information matrix with all new regressor. + C : float or array + Transpose of B. + D : float or array + Information matrix with all selected regressors. + + Returns + ------- + M : array + Inverse of the information matrix. + + """ + if np.isscalar(D): + # Inverse of D + Dinv = 1/D + # Schur complement + SCinv = 1/(D - np.dot(C, np.dot(Ainv, B[:, None])))[0] + else: + # Inverse of D + Dinv = np.linalg.solve(D, np.eye(D.shape)) + # Schur complement + SCinv = np.linalg.solve((D - C*Ainv*B), np.eye(D.shape)) + + T1 = np.dot(Ainv, np.dot(B[:, None], SCinv)) + T2 = np.dot(C, Ainv) + + # Assemble the inverse matrix + M = np.vstack(( + np.hstack((Ainv+T1*T2, -T1)), + np.hstack((-(SCinv)*T2, SCinv)) + )) + return M diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_ard.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_ard.py new file mode 100644 index 000000000..e6883a3ed --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_ard.py @@ -0,0 +1,475 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Mar 24 19:41:45 2020 + +@author: farid +""" +import numpy as np +from scipy.linalg import solve_triangular +from numpy.linalg import LinAlgError +from sklearn.base import RegressorMixin +from sklearn.linear_model._base import LinearModel +import warnings +from sklearn.utils import check_X_y +from scipy.linalg import pinvh + + +def update_precisions(Q,S,q,s,A,active,tol,n_samples,clf_bias): + ''' + Selects one feature to be added/recomputed/deleted to model based on + effect it will have on value of log marginal likelihood. + ''' + # initialise vector holding changes in log marginal likelihood + deltaL = np.zeros(Q.shape[0]) + + # identify features that can be added , recomputed and deleted in model + theta = q**2 - s + add = (theta > 0) * (active == False) + recompute = (theta > 0) * (active == True) + delete = ~(add + recompute) + + # compute sparsity & quality parameters corresponding to features in + # three groups identified above + Qadd,Sadd = Q[add], S[add] + Qrec,Srec,Arec = Q[recompute], S[recompute], A[recompute] + Qdel,Sdel,Adel = Q[delete], S[delete], A[delete] + + # compute new alpha's (precision parameters) for features that are + # currently in model and will be recomputed + Anew = s[recompute]**2/ ( theta[recompute] + np.finfo(np.float32).eps) + delta_alpha = (1./Anew - 1./Arec) + + # compute change in log marginal likelihood + deltaL[add] = ( Qadd**2 - Sadd ) / Sadd + np.log(Sadd/Qadd**2 ) + deltaL[recompute] = Qrec**2 / (Srec + 1. / delta_alpha) - np.log(1 + Srec*delta_alpha) + deltaL[delete] = Qdel**2 / (Sdel - Adel) - np.log(1 - Sdel / Adel) + deltaL = deltaL / n_samples + + # find feature which caused largest change in likelihood + feature_index = np.argmax(deltaL) + + # no deletions or additions + same_features = np.sum( theta[~recompute] > 0) == 0 + + # changes in precision for features already in model is below threshold + no_delta = np.sum( abs( Anew - Arec ) > tol ) == 0 + # if same_features: print(abs( Anew - Arec )) + # print("same_features = {} no_delta = {}".format(same_features,no_delta)) + # check convergence: if no features to add or delete and small change in + # precision for current features then terminate + converged = False + if same_features and no_delta: + converged = True + return [A,converged] + + # if not converged update precision parameter of weights and return + if theta[feature_index] > 0: + A[feature_index] = s[feature_index]**2 / theta[feature_index] + if active[feature_index] == False: + active[feature_index] = True + else: + # at least two active features + if active[feature_index] == True and np.sum(active) >= 2: + # do not remove bias term in classification + # (in regression it is factored in through centering) + if not (feature_index == 0 and clf_bias): + active[feature_index] = False + A[feature_index] = np.PINF + + return [A,converged] + + +class RegressionFastARD(LinearModel, RegressorMixin): + ''' + Regression with Automatic Relevance Determination (Fast Version uses + Sparse Bayesian Learning) + https://github.com/AmazaspShumik/sklearn-bayes/blob/master/skbayes/rvm_ard_models/fast_rvm.py + + Parameters + ---------- + n_iter: int, optional (DEFAULT = 100) + Maximum number of iterations + + start: list, optional (DEFAULT = None) + Initial selected features. + + tol: float, optional (DEFAULT = 1e-3) + If absolute change in precision parameter for weights is below threshold + algorithm terminates. + + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + compute_score : bool, default=False + If True, compute the log marginal likelihood at each iteration of the + optimization. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + alpha_ : float + estimated precision of the noise + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + lambda_ : array, shape = (n_features) + estimated precisions of the coefficients + + sigma_ : array, shape = (n_features, n_features) + estimated covariance matrix of the weights, computed only + for non-zero coefficients + + scores_ : array-like of shape (n_iter_+1,) + If computed_score is True, value of the log marginal likelihood (to be + maximized) at each iteration of the optimization. + + References + ---------- + [1] Fast marginal likelihood maximisation for sparse Bayesian models + (Tipping & Faul 2003) (http://www.miketipping.com/papers/met-fastsbl.pdf) + [2] Analysis of sparse Bayesian learning (Tipping & Faul 2001) + (http://www.miketipping.com/abstracts.htm#Faul:NIPS01) + ''' + + def __init__(self, n_iter=300, start=None, tol=1e-3, fit_intercept=True, + normalize=False, copy_X=True, compute_score=False, verbose=False): + self.n_iter = n_iter + self.start = start + self.tol = tol + self.scores_ = list() + self.fit_intercept = fit_intercept + self.normalize = normalize + self.copy_X = copy_X + self.compute_score = compute_score + self.verbose = verbose + + def _preprocess_data(self, X, y): + """Center and scale data. + Centers data to have mean zero along axis 0. If fit_intercept=False or + if the X is a sparse matrix, no centering is done, but normalization + can still be applied. The function returns the statistics necessary to + reconstruct the input data, which are X_offset, y_offset, X_scale, such + that the output + X = (X - X_offset) / X_scale + X_scale is the L2 norm of X - X_offset. + """ + + if self.copy_X: + X = X.copy(order='K') + + y = np.asarray(y, dtype=X.dtype) + + if self.fit_intercept: + X_offset = np.average(X, axis=0) + X -= X_offset + if self.normalize: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + std = np.sqrt(np.sum(X**2, axis=0)/(len(X)-1)) + X_scale[std != 0] = std[std != 0] + X /= X_scale + else: + X_scale = np.ones(X.shape[1], dtype=X.dtype) + y_offset = np.mean(y) + y = y - y_offset + else: + X_offset = np.zeros(X.shape[1], dtype=X.dtype) + X_scale = np.ones(X.shape[1], dtype=X.dtype) + if y.ndim == 1: + y_offset = X.dtype.type(0) + else: + y_offset = np.zeros(y.shape[1], dtype=X.dtype) + + return X, y, X_offset, y_offset, X_scale + + def fit(self, X, y): + ''' + Fits ARD Regression with Sequential Sparse Bayes Algorithm. + + Parameters + ----------- + X: {array-like, sparse matrix} of size (n_samples, n_features) + Training data, matrix of explanatory variables + + y: array-like of size [n_samples, n_features] + Target values + + Returns + ------- + self : object + Returns self. + ''' + X, y = check_X_y(X, y, dtype=np.float64, y_numeric=True) + n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._preprocess_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # precompute X'*Y , X'*X for faster iterations & allocate memory for + # sparsity & quality vectors + XY = np.dot(X.T, y) + XX = np.dot(X.T, X) + XXd = np.diag(XX) + + # initialise precision of noise & and coefficients + var_y = np.var(y) + + # check that variance is non zero !!! + if var_y == 0: + beta = 1e-2 + self.var_y = True + else: + beta = 1. / np.var(y) + self.var_y = False + + A = np.PINF * np.ones(n_features) + active = np.zeros(n_features, dtype=np.bool) + + if self.start is not None and not hasattr(self, 'active_'): + start = self.start + # start from a given start basis vector + proj = XY**2 / XXd + active[start] = True + A[start] = XXd[start]/(proj[start] - var_y) + + else: + # in case of almost perfect multicollinearity between some features + # start from feature 0 + if np.sum(XXd - X_mean**2 < np.finfo(np.float32).eps) > 0: + A[0] = np.finfo(np.float16).eps + active[0] = True + + else: + # start from a single basis vector with largest projection on + # targets + proj = XY**2 / XXd + start = np.argmax(proj) + active[start] = True + A[start] = XXd[start]/(proj[start] - var_y + + np.finfo(np.float32).eps) + + warning_flag = 0 + scores_ = [] + for i in range(self.n_iter): + # Handle variance zero + if self.var_y: + A[0] = y_mean + active[0] = True + converged = True + break + + XXa = XX[active, :][:, active] + XYa = XY[active] + Aa = A[active] + + # mean & covariance of posterior distribution + Mn, Ri, cholesky = self._posterior_dist(Aa, beta, XXa, XYa) + if cholesky: + Sdiag = np.sum(Ri**2, 0) + else: + Sdiag = np.copy(np.diag(Ri)) + warning_flag += 1 + + # raise warning in case cholesky fails + if warning_flag == 1: + warnings.warn(("Cholesky decomposition failed! Algorithm uses " + "pinvh, which is significantly slower. If you " + "use RVR it is advised to change parameters of " + "the kernel!")) + + # compute quality & sparsity parameters + s, q, S, Q = self._sparsity_quality(XX, XXd, XY, XYa, Aa, Ri, + active, beta, cholesky) + + # update precision parameter for noise distribution + rss = np.sum((y - np.dot(X[:, active], Mn))**2) + + # if near perfect fit , then terminate + if (rss / n_samples/var_y) < self.tol: + warnings.warn('Early termination due to near perfect fit') + converged = True + break + beta = n_samples - np.sum(active) + np.sum(Aa * Sdiag) + beta /= rss + # beta /= (rss + np.finfo(np.float32).eps) + + # update precision parameters of coefficients + A, converged = update_precisions(Q, S, q, s, A, active, self.tol, + n_samples, False) + + if self.compute_score: + scores_.append(self.log_marginal_like(XXa, XYa, Aa, beta)) + + if self.verbose: + print(('Iteration: {0}, number of features ' + 'in the model: {1}').format(i, np.sum(active))) + + if converged or i == self.n_iter - 1: + if converged and self.verbose: + print('Algorithm converged!') + break + + # after last update of alpha & beta update parameters + # of posterior distribution + XXa, XYa, Aa = XX[active, :][:, active], XY[active], A[active] + Mn, Sn, cholesky = self._posterior_dist(Aa, beta, XXa, XYa, True) + self.coef_ = np.zeros(n_features) + self.coef_[active] = Mn + self.sigma_ = Sn + self.active_ = active + self.lambda_ = A + self.alpha_ = beta + self.converged = converged + if self.compute_score: + self.scores_ = np.array(scores_) + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + return self + + def log_marginal_like(self, XXa, XYa, Aa, beta): + """Computes the log of the marginal likelihood.""" + N, M = XXa.shape + A = np.diag(Aa) + + Mn, sigma_, cholesky = self._posterior_dist(Aa, beta, XXa, XYa, + full_covar=True) + + C = sigma_ + np.dot(np.dot(XXa.T, np.linalg.pinv(A)), XXa) + + score = np.dot(np.dot(XYa.T, np.linalg.pinv(C)), XYa) +\ + np.log(np.linalg.det(C)) + N * np.log(2 * np.pi) + + return -0.5 * score + + def predict(self, X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance based on + Ref.[1] Section 3.3.2. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + References + ---------- + [1] Bishop, C. M. (2006). Pattern recognition and machine learning. + springer. + ''' + + y_hat = np.dot(X, self.coef_) + self.intercept_ + + if return_std: + # Handle the zero variance case + if self.var_y: + return y_hat, np.zeros_like(y_hat) + + if self.normalize: + X -= self._x_mean_[self.active_] + X /= self._x_std[self.active_] + var_hat = 1./self.alpha_ + var_hat += np.sum(X.dot(self.sigma_) * X, axis=1) + std_hat = np.sqrt(var_hat) + return y_hat, std_hat + else: + return y_hat + + def _posterior_dist(self, A, beta, XX, XY, full_covar=False): + ''' + Calculates mean and covariance matrix of posterior distribution + of coefficients. + ''' + # compute precision matrix for active features + Sinv = beta * XX + np.fill_diagonal(Sinv, np.diag(Sinv) + A) + cholesky = True + + # try cholesky, if it fails go back to pinvh + try: + # find posterior mean : R*R.T*mean = beta*X.T*Y + # solve(R*z = beta*X.T*Y) =>find z=> solve(R.T*mean = z)=>find mean + R = np.linalg.cholesky(Sinv) + Z = solve_triangular(R, beta*XY, check_finite=True, lower=True) + Mn = solve_triangular(R.T, Z, check_finite=True, lower=False) + + # invert lower triangular matrix from cholesky decomposition + Ri = solve_triangular(R, np.eye(A.shape[0]), check_finite=False, + lower=True) + if full_covar: + Sn = np.dot(Ri.T, Ri) + return Mn, Sn, cholesky + else: + return Mn, Ri, cholesky + except LinAlgError: + cholesky = False + Sn = pinvh(Sinv) + Mn = beta*np.dot(Sinv, XY) + return Mn, Sn, cholesky + + def _sparsity_quality(self, XX, XXd, XY, XYa, Aa, Ri, active, beta, cholesky): + ''' + Calculates sparsity and quality parameters for each feature + + Theoretical Note: + ----------------- + Here we used Woodbury Identity for inverting covariance matrix + of target distribution + C = 1/beta + 1/alpha * X' * X + C^-1 = beta - beta^2 * X * Sn * X' + ''' + bxy = beta*XY + bxx = beta*XXd + if cholesky: + # here Ri is inverse of lower triangular matrix obtained from + # cholesky decomp + xxr = np.dot(XX[:, active], Ri.T) + rxy = np.dot(Ri, XYa) + S = bxx - beta**2 * np.sum(xxr**2, axis=1) + Q = bxy - beta**2 * np.dot(xxr, rxy) + else: + # here Ri is covariance matrix + XXa = XX[:, active] + XS = np.dot(XXa, Ri) + S = bxx - beta**2 * np.sum(XS*XXa, 1) + Q = bxy - beta**2 * np.dot(XS, XYa) + # Use following: + # (EQ 1) q = A*Q/(A - S) ; s = A*S/(A-S) + # so if A = np.PINF q = Q, s = S + qi = np.copy(Q) + si = np.copy(S) + # If A is not np.PINF, then it should be 'active' feature => use (EQ 1) + Qa, Sa = Q[active], S[active] + qi[active] = Aa * Qa / (Aa - Sa) + si[active] = Aa * Sa / (Aa - Sa) + + return [si, qi, S, Q] diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_laplace.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_laplace.py new file mode 100644 index 000000000..7fdcb5cf6 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/reg_fast_laplace.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import numpy as np +from sklearn.utils import as_float_array +from sklearn.model_selection import KFold + + +class RegressionFastLaplace(): + ''' + Sparse regression with Bayesian Compressive Sensing as described in Alg. 1 + (Fast Laplace) of Ref.[1], which updated formulas from [2]. + + sigma2: noise precision (sigma^2) + nu fixed to 0 + + uqlab/lib/uq_regression/BCS/uq_bsc.m + + Parameters + ---------- + n_iter: int, optional (DEFAULT = 1000) + Maximum number of iterations + + tol: float, optional (DEFAULT = 1e-7) + If absolute change in precision parameter for weights is below + threshold algorithm terminates. + + fit_intercept : boolean, optional (DEFAULT = True) + whether to calculate the intercept for this model. If set + to false, no intercept will be used in calculations + (e.g. data is expected to be already centered). + + copy_X : boolean, optional (DEFAULT = True) + If True, X will be copied; else, it may be overwritten. + + verbose : boolean, optional (DEFAULT = FALSE) + Verbose mode when fitting the model + + Attributes + ---------- + coef_ : array, shape = (n_features) + Coefficients of the regression model (mean of posterior distribution) + + alpha_ : float + estimated precision of the noise + + active_ : array, dtype = np.bool, shape = (n_features) + True for non-zero coefficients, False otherwise + + lambda_ : array, shape = (n_features) + estimated precisions of the coefficients + + sigma_ : array, shape = (n_features, n_features) + estimated covariance matrix of the weights, computed only + for non-zero coefficients + + References + ---------- + [1] Babacan, S. D., Molina, R., & Katsaggelos, A. K. (2009). Bayesian + compressive sensing using Laplace priors. IEEE Transactions on image + processing, 19(1), 53-63. + [2] Fast marginal likelihood maximisation for sparse Bayesian models + (Tipping & Faul 2003). + (http://www.miketipping.com/papers/met-fastsbl.pdf) + ''' + + def __init__(self, n_iter=1000, n_Kfold=10, tol=1e-7, fit_intercept=False, + bias_term=True, copy_X=True, verbose=False): + self.n_iter = n_iter + self.n_Kfold = n_Kfold + self.tol = tol + self.fit_intercept = fit_intercept + self.bias_term = bias_term + self.copy_X = copy_X + self.verbose = verbose + + def _center_data(self, X, y): + ''' Centers data''' + X = as_float_array(X, copy = self.copy_X) + + # normalisation should be done in preprocessing! + X_std = np.ones(X.shape[1], dtype=X.dtype) + if self.fit_intercept: + X_mean = np.average(X, axis=0) + y_mean = np.average(y, axis=0) + X -= X_mean + y -= y_mean + else: + X_mean = np.zeros(X.shape[1], dtype=X.dtype) + y_mean = 0. if y.ndim == 1 else np.zeros(y.shape[1], dtype=X.dtype) + return X, y, X_mean, y_mean, X_std + + def fit(self, X, y): + + k_fold = KFold(n_splits=self.n_Kfold) + + varY = np.var(y, ddof=1) if np.var(y, ddof=1) != 0 else 1.0 + sigma2s = len(y)*varY*(10**np.linspace(-16, -1, self.n_Kfold)) + + errors = np.zeros((len(sigma2s), self.n_Kfold)) + for s, sigma2 in enumerate(sigma2s): + for k, (train, test) in enumerate(k_fold.split(X, y)): + self.fit_(X[train], y[train], sigma2) + errors[s, k] = np.linalg.norm( + y[test] - self.predict(X[test]) + )**2/len(test) + + KfCVerror = np.sum(errors, axis=1)/self.n_Kfold/varY + i_minCV = np.argmin(KfCVerror) + + self.kfoldCVerror = np.min(KfCVerror) + + return self.fit_(X, y, sigma2s[i_minCV]) + + def fit_(self, X, y, sigma2): + + N, P = X.shape + # n_samples, n_features = X.shape + + X, y, X_mean, y_mean, X_std = self._center_data(X, y) + self._x_mean_ = X_mean + self._y_mean = y_mean + self._x_std = X_std + + # check that variance is non zero !!! + if np.var(y) == 0: + self.var_y = True + else: + self.var_y = False + beta = 1./sigma2 + + # precompute X'*Y , X'*X for faster iterations & allocate memory for + # sparsity & quality vectors X=Psi + PsiTY = np.dot(X.T, y) + PsiTPsi = np.dot(X.T, X) + XXd = np.diag(PsiTPsi) + + # initialize with constant regressor, or if that one does not exist, + # with the one that has the largest correlation with Y + ind_global_to_local = np.zeros(P, dtype=np.int32) + + # identify constant regressors + constidx = np.where(~np.diff(X, axis=0).all(axis=0))[0] + + if self.bias_term and constidx.size != 0: + ind_start = constidx[0] + ind_global_to_local[ind_start] = True + else: + # start from a single basis vector with largest projection on + # targets + proj = np.divide(np.square(PsiTY), XXd) + ind_start = np.argmax(proj) + ind_global_to_local[ind_start] = True + + num_active = 1 + active_indices = [ind_start] + deleted_indices = [] + bcs_path = [ind_start] + gamma = np.zeros(P) + # for the initial value of gamma(ind_start), use the RVM formula + # gamma = (q^2 - s) / (s^2) + # and the fact that initially s = S = beta*Psi_i'*Psi_i and q = Q = + # beta*Psi_i'*Y + gamma[ind_start] = np.square(PsiTY[ind_start]) + gamma[ind_start] -= sigma2 * PsiTPsi[ind_start, ind_start] + gamma[ind_start] /= np.square(PsiTPsi[ind_start, ind_start]) + + Sigma = 1. / (beta * PsiTPsi[ind_start, ind_start] + + 1./gamma[ind_start]) + + mu = Sigma * PsiTY[ind_start] * beta + tmp1 = beta * PsiTPsi[ind_start] + S = beta * np.diag(PsiTPsi).T - Sigma * np.square(tmp1) + Q = beta * PsiTY.T - mu*(tmp1) + + tmp2 = np.ones(P) # alternative computation for the initial s,q + q0tilde = PsiTY[ind_start] + s0tilde = PsiTPsi[ind_start, ind_start] + tmp2[ind_start] = s0tilde / (q0tilde**2) / beta + s = np.divide(S, tmp2) + q = np.divide(Q, tmp2) + Lambda = 2*(num_active - 1) / np.sum(gamma) + + Delta_L_max = [] + for i in range(self.n_iter): + # Handle variance zero + if self.var_y: + mu = np.mean(y) + break + + if self.verbose: + print(' lambda = {0:.6e}\n'.format(Lambda)) + + # Calculate the potential updated value of each gamma[i] + if Lambda == 0.0: # RVM + gamma_potential = np.multiply(( + (q**2 - s) > Lambda), + np.divide(q**2 - s, s**2) + ) + else: + a = Lambda * s**2 + b = s**2 + 2*Lambda*s + c = Lambda + s - q**2 + gamma_potential = np.multiply( + (c < 0), np.divide( + -b + np.sqrt(b**2 - 4*np.multiply(a, c)), 2*a) + ) + + l_gamma = - np.log(np.absolute(1 + np.multiply(gamma, s))) + l_gamma += np.divide(np.multiply(q**2, gamma), + (1 + np.multiply(gamma, s))) + l_gamma -= Lambda*gamma # omitted the factor 1/2 + + # Contribution of each updated gamma(i) to L(gamma) + l_gamma_potential = - np.log( + np.absolute(1 + np.multiply(gamma_potential, s)) + ) + l_gamma_potential += np.divide( + np.multiply(q**2, gamma_potential), + (1 + np.multiply(gamma_potential, s)) + ) + # omitted the factor 1/2 + l_gamma_potential -= Lambda*gamma_potential + + # Check how L(gamma) would change if we replaced gamma(i) by the + # updated gamma_potential(i), for each i separately + Delta_L_potential = l_gamma_potential - l_gamma + + # deleted indices should not be chosen again + if len(deleted_indices) != 0: + values = -np.inf * np.ones(len(deleted_indices)) + Delta_L_potential[deleted_indices] = values + + Delta_L_max.append(np.nanmax(Delta_L_potential)) + ind_L_max = np.nanargmax(Delta_L_potential) + + # in case there is only 1 regressor in the model and it would now + # be deleted + if len(active_indices) == 1 and ind_L_max == active_indices[0] \ + and gamma_potential[ind_L_max] == 0.0: + Delta_L_potential[ind_L_max] = -np.inf + Delta_L_max[i] = np.max(Delta_L_potential) + ind_L_max = np.argmax(Delta_L_potential) + + # If L did not change significantly anymore, break + if Delta_L_max[i] <= 0.0 or\ + (i > 0 and all(np.absolute(Delta_L_max[i-1:]) + < sum(Delta_L_max)*self.tol)) or \ + (i > 0 and all(np.diff(bcs_path)[i-1:] == 0.0)): + if self.verbose: + print('Increase in L: {0:.6e} (eta = {1:.3e})\ + -- break\n'.format(Delta_L_max[i], self.tol)) + break + + # Print information + if self.verbose: + print(' Delta L = {0:.6e} \n'.format(Delta_L_max[i])) + + what_changed = int(gamma[ind_L_max] == 0.0) + what_changed -= int(gamma_potential[ind_L_max] == 0.0) + + # Print information + if self.verbose: + if what_changed < 0: + print(f'{i+1} - Remove regressor #{ind_L_max+1}..\n') + elif what_changed == 0: + print(f'{i+1} - Recompute regressor #{ind_L_max+1}..\n') + else: + print(f'{i+1} - Add regressor #{ind_L_max+1}..\n') + + # --- Update all quantities ---- + if what_changed == 1: + # adding a regressor + + # update gamma + gamma[ind_L_max] = gamma_potential[ind_L_max] + + Sigma_ii = 1.0 / (1.0/gamma[ind_L_max] + S[ind_L_max]) + try: + x_i = np.matmul( + Sigma, PsiTPsi[active_indices, ind_L_max].reshape(-1, 1) + ) + except ValueError: + x_i = Sigma * PsiTPsi[active_indices, ind_L_max] + tmp_1 = - (beta * Sigma_ii) * x_i + Sigma = np.vstack( + (np.hstack(((beta**2 * Sigma_ii) * np.dot(x_i, x_i.T) + + Sigma, tmp_1)), np.append(tmp_1.T, Sigma_ii)) + ) + mu_i = Sigma_ii * Q[ind_L_max] + mu = np.vstack((mu - (beta * mu_i) * x_i, mu_i)) + + tmp2_1 = PsiTPsi[:, ind_L_max] - beta * np.squeeze( + np.matmul(PsiTPsi[:, active_indices], x_i) + ) + if i == 0: + tmp2_1[0] /= 2 + tmp2 = beta * tmp2_1.T + S = S - Sigma_ii * np.square(tmp2) + Q = Q - mu_i * tmp2 + + num_active += 1 + ind_global_to_local[ind_L_max] = num_active + active_indices.append(ind_L_max) + bcs_path.append(ind_L_max) + + elif what_changed == 0: + # recomputation + # zero if regressor has not been chosen yet + if not ind_global_to_local[ind_L_max]: + raise Exception('Cannot recompute index{0} -- not yet\ + part of the model!'.format(ind_L_max)) + Sigma = np.atleast_2d(Sigma) + mu = np.atleast_2d(mu) + gamma_i_new = gamma_potential[ind_L_max] + gamma_i_old = gamma[ind_L_max] + # update gamma + gamma[ind_L_max] = gamma_potential[ind_L_max] + + # index of regressor in Sigma + local_ind = ind_global_to_local[ind_L_max]-1 + + kappa_i = (1.0/gamma_i_new - 1.0/gamma_i_old) + kappa_i = 1.0 / kappa_i + kappa_i += Sigma[local_ind, local_ind] + kappa_i = 1 / kappa_i + Sigma_i_col = Sigma[:, local_ind] + + Sigma = Sigma - kappa_i * (Sigma_i_col * Sigma_i_col.T) + mu_i = mu[local_ind] + mu = mu - (kappa_i * mu_i) * Sigma_i_col[:, None] + + tmp1 = beta * np.dot( + Sigma_i_col.reshape(1, -1), PsiTPsi[active_indices])[0] + S = S + kappa_i * np.square(tmp1) + Q = Q + (kappa_i * mu_i) * tmp1 + + # no change in active_indices or ind_global_to_local + bcs_path.append(ind_L_max + 0.1) + + elif what_changed == -1: + gamma[ind_L_max] = 0 + + # index of regressor in Sigma + local_ind = ind_global_to_local[ind_L_max]-1 + + Sigma_ii_inv = 1. / Sigma[local_ind, local_ind] + Sigma_i_col = Sigma[:, local_ind] + + Sigma = Sigma - Sigma_ii_inv * (Sigma_i_col * Sigma_i_col.T) + + Sigma = np.delete( + np.delete(Sigma, local_ind, axis=0), local_ind, axis=1) + + mu = mu - (mu[local_ind] * Sigma_ii_inv) * Sigma_i_col[:, None] + mu = np.delete(mu, local_ind, axis=0) + + tmp1 = beta * np.dot(Sigma_i_col, PsiTPsi[active_indices]) + S = S + Sigma_ii_inv * np.square(tmp1) + Q = Q + (mu_i * Sigma_ii_inv) * tmp1 + + num_active -= 1 + ind_global_to_local[ind_L_max] = 0.0 + v = ind_global_to_local[ind_global_to_local > local_ind] - 1 + ind_global_to_local[ind_global_to_local > local_ind] = v + del active_indices[local_ind] + deleted_indices.append(ind_L_max) + # and therefore ineligible + bcs_path.append(-ind_L_max) + + # same for all three cases + tmp3 = 1 - np.multiply(gamma, S) + s = np.divide(S, tmp3) + q = np.divide(Q, tmp3) + + # Update lambda + Lambda = 2*(num_active - 1) / np.sum(gamma) + + # Prepare the result object + self.coef_ = np.zeros(P) + self.coef_[active_indices] = np.squeeze(mu) + self.sigma_ = Sigma + self.active_ = active_indices + self.gamma = gamma + self.Lambda = Lambda + self.beta = beta + self.bcs_path = bcs_path + + # set intercept_ + if self.fit_intercept: + self.coef_ = self.coef_ / X_std + self.intercept_ = y_mean - np.dot(X_mean, self.coef_.T) + else: + self.intercept_ = 0. + + return self + + def predict(self, X, return_std=False): + ''' + Computes predictive distribution for test set. + Predictive distribution for each data point is one dimensional + Gaussian and therefore is characterised by mean and variance based on + Ref.[1] Section 3.3.2. + + Parameters + ----------- + X: {array-like, sparse} (n_samples_test, n_features) + Test data, matrix of explanatory variables + + Returns + ------- + : list of length two [y_hat, var_hat] + + y_hat: numpy array of size (n_samples_test,) + Estimated values of targets on test set (i.e. mean of + predictive distribution) + + var_hat: numpy array of size (n_samples_test,) + Variance of predictive distribution + + References + ---------- + [1] Bishop, C. M. (2006). Pattern recognition and machine learning. + springer. + ''' + y_hat = np.dot(X, self.coef_) + self.intercept_ + + if return_std: + # Handle the zero variance case + if self.var_y: + return y_hat, np.zeros_like(y_hat) + + var_hat = 1./self.beta + var_hat += np.sum(X.dot(self.sigma_) * X, axis=1) + std_hat = np.sqrt(var_hat) + return y_hat, std_hat + else: + return y_hat + +# l2norm = 0.0 +# for idx in range(10): +# sigma2 = np.genfromtxt('./test/sigma2_{0}.csv'.format(idx+1), delimiter=',') +# Psi_train = np.genfromtxt('./test/Psi_train_{0}.csv'.format(idx+1), delimiter=',') +# Y_train = np.genfromtxt('./test/Y_train_{0}.csv'.format(idx+1)) +# Psi_test = np.genfromtxt('./test/Psi_test_{0}.csv'.format(idx+1), delimiter=',') +# Y_test = np.genfromtxt('./test/Y_test_{0}.csv'.format(idx+1)) + +# clf = RegressionFastLaplace(verbose=True) +# clf.fit_(Psi_train, Y_train, sigma2) +# coeffs_fold = np.genfromtxt('./test/coeffs_fold_{0}.csv'.format(idx+1)) +# print("coeffs error: {0:.4g}".format(np.linalg.norm(clf.coef_ - coeffs_fold))) +# l2norm += np.linalg.norm(Y_test - clf.predict(Psi_test))**2/len(Y_test) +# print("l2norm error: {0:.4g}".format(l2norm)) diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/sequential_design.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/sequential_design.py new file mode 100644 index 000000000..e1feb7317 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/sequential_design.py @@ -0,0 +1,2187 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 28 09:21:18 2022 + +@author: farid +""" +import numpy as np +from scipy import stats, signal, linalg, sparse +from scipy.spatial import distance +from copy import deepcopy, copy +from tqdm import tqdm +import scipy.optimize as opt +from sklearn.metrics import mean_squared_error +import multiprocessing +import matplotlib.pyplot as plt +import sys +import os +import gc +import seaborn as sns +from joblib import Parallel, delayed +#import resource +from .exploration import Exploration + + +class SeqDesign(): + """ Sequential experimental design + This class provieds method for trainig the meta-model in an iterative + manners. + The main method to execute the task is `train_seq_design`, which + recieves a model object and returns the trained metamodel. + """ + + # ------------------------------------------------------------------------- + def train_seq_design(self, MetaModel): + """ + Starts the adaptive sequential design for refining the surrogate model + by selecting training points in a sequential manner. + + Parameters + ---------- + Model : object + An object containing all model specifications. + + Returns + ------- + MetaModel : object + Meta model object. + + """ + # MetaModel = self + Model = MetaModel.ModelObj + self.MetaModel = MetaModel + self.Model = Model + + # Initialization + MetaModel.SeqModifiedLOO = {} + MetaModel.seqValidError = {} + MetaModel.SeqBME = {} + MetaModel.SeqKLD = {} + MetaModel.SeqDistHellinger = {} + MetaModel.seqRMSEMean = {} + MetaModel.seqRMSEStd = {} + MetaModel.seqMinDist = [] + pce = True if MetaModel.meta_model_type.lower() != 'gpe' else False + mc_ref = True if bool(Model.mc_reference) else False + if mc_ref: + Model.read_mc_reference() + + if not hasattr(MetaModel, 'valid_likelihoods'): + MetaModel.valid_samples = [] + MetaModel.valid_model_runs = [] + MetaModel.valid_likelihoods = [] + + # Get the parameters + max_n_samples = MetaModel.ExpDesign.n_max_samples + mod_LOO_threshold = MetaModel.ExpDesign.mod_LOO_threshold + n_canddidate = MetaModel.ExpDesign.n_canddidate + post_snapshot = MetaModel.ExpDesign.post_snapshot + n_replication = MetaModel.ExpDesign.n_replication + util_func = MetaModel.ExpDesign.util_func + output_name = Model.Output.names + validError = None + # Handle if only one UtilityFunctions is provided + if not isinstance(util_func, list): + util_func = [MetaModel.ExpDesign.util_func] + + # Read observations or MCReference + if len(Model.observations) != 0 or Model.meas_file is not None: + self.observations = Model.read_observation() + obs_data = self.observations + else: + obs_data = [] + TotalSigma2 = {} + # ---------- Initial MetaModel ---------- + initMetaModel = deepcopy(MetaModel) + + # Validation error if validation set is provided. + if len(MetaModel.valid_model_runs) != 0: + init_rmse, init_valid_error = self.__validError(initMetaModel) + init_valid_error = list(init_valid_error.values()) + else: + init_rmse = None + + # Check if discrepancy is provided + if len(obs_data) != 0 and hasattr(MetaModel, 'Discrepancy'): + TotalSigma2 = MetaModel.Discrepancy.parameters + + # Calculate the initial BME + out = self.__BME_Calculator( + initMetaModel, obs_data, TotalSigma2, init_rmse) + init_BME, init_KLD, init_post, init_likes, init_dist_hellinger = out + print(f"\nInitial BME: {init_BME:.2f}") + print(f"Initial KLD: {init_KLD:.2f}") + + # Posterior snapshot (initial) + if post_snapshot: + parNames = MetaModel.ExpDesign.par_names + print('Posterior snapshot (initial) is being plotted...') + self.__posteriorPlot(init_post, parNames, 'SeqPosterior_init') + + # Check the convergence of the Mean & Std + if mc_ref and pce: + init_rmse_mean, init_rmse_std = self.__error_Mean_Std() + print(f"Initial Mean and Std error: {init_rmse_mean}," + f" {init_rmse_std}") + + # Read the initial experimental design + Xinit = initMetaModel.ExpDesign.X + init_n_samples = len(MetaModel.ExpDesign.X) + initYprev = initMetaModel.ModelOutputDict + initLCerror = initMetaModel.LCerror + n_itrs = max_n_samples - init_n_samples + + # Read the initial ModifiedLOO + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = initMetaModel.ExpDesign.Y[out_name] + Scores_all.append(list( + initMetaModel.score_dict['b_1'][out_name].values())) + if MetaModel.dim_red_method.lower() == 'pca': + pca = MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + + Scores = [item for sublist in Scores_all for item in sublist] + weights = [item for sublist in varExpDesignY for item in sublist] + init_mod_LOO = [np.average([1-score for score in Scores], + weights=weights)] + + prevMetaModel_dict = {} + # Replicate the sequential design + for repIdx in range(n_replication): + print(f'\n>>>> Replication: {repIdx+1}<<<<') + + # To avoid changes ub original aPCE object + MetaModel.ExpDesign.X = Xinit + MetaModel.ExpDesign.Y = initYprev + MetaModel.LCerror = initLCerror + + for util_f in util_func: + print(f'\n>>>> Utility Function: {util_f} <<<<') + # To avoid changes ub original aPCE object + MetaModel.ExpDesign.X = Xinit + MetaModel.ExpDesign.Y = initYprev + MetaModel.LCerror = initLCerror + + # Set the experimental design + Xprev = Xinit + total_n_samples = init_n_samples + Yprev = initYprev + + Xfull = [] + Yfull = [] + + # Store the initial ModifiedLOO + if pce: + print("\nInitial ModifiedLOO:", init_mod_LOO) + SeqModifiedLOO = np.array(init_mod_LOO) + + if len(MetaModel.valid_model_runs) != 0: + SeqValidError = np.array(init_valid_error) + + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.array([init_BME]) + SeqKLD = np.array([init_KLD]) + SeqDistHellinger = np.array([init_dist_hellinger]) + + if mc_ref and pce: + seqRMSEMean = np.array([init_rmse_mean]) + seqRMSEStd = np.array([init_rmse_std]) + + # ------- Start Sequential Experimental Design ------- + postcnt = 1 + for itr_no in range(1, n_itrs+1): + print(f'\n>>>> Iteration number {itr_no} <<<<') + + # Save the metamodel prediction before updating + prevMetaModel_dict[itr_no] = deepcopy(MetaModel) + if itr_no > 1: + pc_model = prevMetaModel_dict[itr_no-1] + self._y_hat_prev, _ = pc_model.eval_metamodel( + samples=Xfull[-1].reshape(1, -1)) + + # Optimal Bayesian Design + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + MetaModel.ExpDesignFlag = 'sequential' + Xnew, updatedPrior = self.opt_SeqDesign(TotalSigma2, + n_canddidate, + util_f) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + S = np.min(distance.cdist(Xinit, Xnew, 'euclidean')) + MetaModel.seqMinDist.append(S) + print(f"\nmin Dist from OldExpDesign: {S:2f}") + print("\n") + + # Evaluate the full model response at the new sample + Ynew, _ = Model.run_model_parallel( + Xnew, prevRun_No=total_n_samples + ) + total_n_samples += Xnew.shape[0] + # ------ Plot the surrogate model vs Origninal Model ------ + if hasattr(MetaModel, 'adapt_verbose') and \ + MetaModel.adapt_verbose: + from .adaptPlot import adaptPlot + y_hat, std_hat = MetaModel.eval_metamodel(samples=Xnew) + adaptPlot(MetaModel, Ynew, y_hat, std_hat, plotED=False) + + # -------- Retrain the surrogate model ------- + # Extend new experimental design + Xfull = np.vstack((Xprev, Xnew)) + + # Updating experimental design Y + for out_name in output_name: + Yfull = np.vstack((Yprev[out_name], Ynew[out_name])) + MetaModel.ModelOutputDict[out_name] = Yfull + + # Pass new design to the metamodel object + MetaModel.ExpDesign.sampling_method = 'user' + MetaModel.ExpDesign.X = Xfull + MetaModel.ExpDesign.Y = MetaModel.ModelOutputDict + + # Save the Experimental Design for next iteration + Xprev = Xfull + Yprev = MetaModel.ModelOutputDict + + # Pass the new prior as the input + MetaModel.input_obj.poly_coeffs_flag = False + if updatedPrior is not None: + MetaModel.input_obj.poly_coeffs_flag = True + print("updatedPrior:", updatedPrior.shape) + # Arbitrary polynomial chaos + for i in range(updatedPrior.shape[1]): + MetaModel.input_obj.Marginals[i].dist_type = None + x = updatedPrior[:, i] + MetaModel.input_obj.Marginals[i].raw_data = x + + # Train the surrogate model for new ExpDesign + MetaModel.train_norm_design(parallel=False) + m_3 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + + # -------- Evaluate the retrained surrogate model ------- + # Extract Modified LOO from Output + if pce: + Scores_all, varExpDesignY = [], [] + for out_name in output_name: + y = MetaModel.ExpDesign.Y[out_name] + Scores_all.append(list( + MetaModel.score_dict['b_1'][out_name].values())) + if MetaModel.dim_red_method.lower() == 'pca': + pca = MetaModel.pca['b_1'][out_name] + components = pca.transform(y) + varExpDesignY.append(np.var(components, + axis=0)) + else: + varExpDesignY.append(np.var(y, axis=0)) + Scores = [item for sublist in Scores_all for item + in sublist] + weights = [item for sublist in varExpDesignY for item + in sublist] + ModifiedLOO = [np.average( + [1-score for score in Scores], weights=weights)] + + print('\n') + print(f"Updated ModifiedLOO {util_f}:\n", ModifiedLOO) + print('\n') + + # Compute the validation error + if len(MetaModel.valid_model_runs) != 0: + rmse, validError = self.__validError(MetaModel) + ValidError = list(validError.values()) + else: + rmse = None + + # Store updated ModifiedLOO + if pce: + SeqModifiedLOO = np.vstack( + (SeqModifiedLOO, ModifiedLOO)) + if len(MetaModel.valid_model_runs) != 0: + SeqValidError = np.vstack( + (SeqValidError, ValidError)) + m_4 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + # -------- Caclulation of BME as accuracy metric ------- + # Check if data is provided + if len(obs_data) != 0: + # Calculate the initial BME + out = self.__BME_Calculator(MetaModel, obs_data, + TotalSigma2, rmse) + BME, KLD, Posterior, likes, DistHellinger = out + print('\n') + print(f"Updated BME: {BME:.2f}") + print(f"Updated KLD: {KLD:.2f}") + print('\n') + + # Plot some snapshots of the posterior + step_snapshot = MetaModel.ExpDesign.step_snapshot + if post_snapshot and postcnt % step_snapshot == 0: + parNames = MetaModel.ExpDesign.par_names + print('Posterior snapshot is being plotted...') + self.__posteriorPlot(Posterior, parNames, + f'SeqPosterior_{postcnt}') + postcnt += 1 + m_5 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + + # Check the convergence of the Mean&Std + if mc_ref and pce: + print('\n') + RMSE_Mean, RMSE_std = self.__error_Mean_Std() + print(f"Updated Mean and Std error: {RMSE_Mean:.2f}, " + f"{RMSE_std:.2f}") + print('\n') + + # Store the updated BME & KLD + # Check if data is provided + if len(obs_data) != 0: + SeqBME = np.vstack((SeqBME, BME)) + SeqKLD = np.vstack((SeqKLD, KLD)) + SeqDistHellinger = np.vstack((SeqDistHellinger, + DistHellinger)) + if mc_ref and pce: + seqRMSEMean = np.vstack((seqRMSEMean, RMSE_Mean)) + seqRMSEStd = np.vstack((seqRMSEStd, RMSE_std)) + + if pce and any(LOO < mod_LOO_threshold + for LOO in ModifiedLOO): + break + + print(f"Memory itr {itr_no}: I: {m_2-m_1:.2f} MB") + print(f"Memory itr {itr_no}: II: {m_3-m_2:.2f} MB") + print(f"Memory itr {itr_no}: III: {m_4-m_3:.2f} MB") + print(f"Memory itr {itr_no}: IV: {m_5-m_4:.2f} MB") + m_6 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"Memory itr {itr_no}: total: {m_6:.2f} MB") + + # Clean up + if len(obs_data) != 0: + del out + gc.collect() + print() + print('-'*50) + print() + + # Store updated ModifiedLOO and BME in dictonary + strKey = f'{util_f}_rep_{repIdx+1}' + if pce: + MetaModel.SeqModifiedLOO[strKey] = SeqModifiedLOO + if len(MetaModel.valid_model_runs) != 0: + MetaModel.seqValidError[strKey] = SeqValidError + + # Check if data is provided + if len(obs_data) != 0: + MetaModel.SeqBME[strKey] = SeqBME + MetaModel.SeqKLD[strKey] = SeqKLD + if len(MetaModel.valid_likelihoods) != 0: + MetaModel.SeqDistHellinger[strKey] = SeqDistHellinger + if mc_ref and pce: + MetaModel.seqRMSEMean[strKey] = seqRMSEMean + MetaModel.seqRMSEStd[strKey] = seqRMSEStd + + return MetaModel + + # ------------------------------------------------------------------------- + def util_VarBasedDesign(self, X_can, index, util_func='Entropy'): + """ + Computes the exploitation scores based on: + active learning MacKay(ALM) and active learning Cohn (ALC) + Paper: Sequential Design with Mutual Information for Computer + Experiments (MICE): Emulation of a Tsunami Model by Beck and Guillas + (2016) + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + index : int + Model output index. + UtilMethod : string, optional + Exploitation utility function. The default is 'Entropy'. + + Returns + ------- + float + Score. + + """ + MetaModel = self.MetaModel + ED_X = MetaModel.ExpDesign.X + out_dict_y = MetaModel.ExpDesign.Y + out_names = MetaModel.ModelObj.Output.names + + # Run the Metamodel for the candidate + X_can = X_can.reshape(1, -1) + Y_PC_can, std_PC_can = MetaModel.eval_metamodel(samples=X_can) + + if util_func.lower() == 'alm': + # ----- Entropy/MMSE/active learning MacKay(ALM) ----- + # Compute perdiction variance of the old model + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + varPCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + varPCE[KeyIdx] = np.max(canPredVar[key], axis=1) + score = np.max(varPCE, axis=0) + + elif util_func.lower() == 'eigf': + # ----- Expected Improvement for Global fit ----- + # Find closest EDX to the candidate + distances = distance.cdist(ED_X, X_can, 'euclidean') + index = np.argmin(distances) + + # Compute perdiction error and variance of the old model + predError = {key: Y_PC_can[key] for key in out_names} + canPredVar = {key: std_PC_can[key]**2 for key in out_names} + + # Compute perdiction error and variance of the old model + # Eq (5) from Liu et al.(2018) + EIGF_PCE = np.zeros((len(out_names), X_can.shape[0])) + for KeyIdx, key in enumerate(out_names): + residual = predError[key] - out_dict_y[key][int(index)] + var = canPredVar[key] + EIGF_PCE[KeyIdx] = np.max(residual**2 + var, axis=1) + score = np.max(EIGF_PCE, axis=0) + + return -1 * score # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def util_BayesianActiveDesign(self, X_can, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian active design criterion (var). + + It is based on the following paper: + Oladyshkin, Sergey, Farid Mohammadi, Ilja Kroeker, and Wolfgang Nowak. + "Bayesian3 active learning for the gaussian process emulator using + information theory." Entropy 22, no. 8 (2020): 890. + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + BAL design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # Evaluate the PCE metamodels at that location ??? + Y_mean_can, Y_std_can = self.MetaModel.eval_metamodel( + samples=np.array([X_can]) + ) + + # Get the data + obs_data = self.observations + n_obs = self.Model.n_obs + # TODO: Analytical DKL + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + + # priorMean, priorSigma2, Obs = np.empty((0)),np.empty((0)),np.empty((0)) + + # for key in list(Y_mean_can): + # # concatenate the measurement error + # Obs = np.hstack((Obs,ObservationData[key])) + + # # concatenate the mean and variance of prior predictive + # means, stds = Y_mean_can[key][0], Y_std_can[key][0] + # priorMean = np.hstack((priorSigma2,means)) + # priorSigma2 = np.hstack((priorSigma2,stds**2)) + + # # Covariance Matrix of prior + # covPrior = np.zeros((priorSigma2.shape[0], priorSigma2.shape[0]), float) + # np.fill_diagonal(covPrior, priorSigma2) + + # # Covariance Matrix of Likelihood + # covLikelihood = np.zeros((sigma2Dict.shape[0], sigma2Dict.shape[0]), float) + # np.fill_diagonal(covLikelihood, sigma2Dict) + + # # Calculate moments of the posterior (Analytical derivation) + # n = priorSigma2.shape[0] + # covPost = np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))),covLikelihood/n) + + # meanPost = np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))) , Obs) + \ + # np.dot(np.dot(covPrior,np.linalg.inv(covPrior+(covLikelihood/n))), + # priorMean/n) + # # Compute DKL from prior to posterior + # term1 = np.trace(np.dot(np.linalg.inv(covPrior),covPost)) + # deltaMean = priorMean-meanPost + # term2 = np.dot(np.dot(deltaMean,np.linalg.inv(covPrior)),deltaMean[:,None]) + # term3 = np.log(np.linalg.det(covPrior)/np.linalg.det(covPost)) + # DKL = 0.5 * (term1 + term2 - n + term3)[0] + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = 20000 + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Sample a distribution for a normal dist + # with Y_mean_can as the mean and Y_std_can as std. + Y_MC, std_MC = {}, {} + logPriorLikelihoods = np.zeros((MCsize)) + for key in list(Y_mean_can): + means, stds = Y_mean_can[key][0], Y_std_can[key][0] + # cov = np.zeros((means.shape[0], means.shape[0]), float) + # np.fill_diagonal(cov, stds**2) + + Y_MC[key] = np.zeros((MCsize, n_obs)) + logsamples = np.zeros((MCsize, n_obs)) + for i in range(n_obs): + NormalDensity = stats.norm(means[i], stds[i]) + Y_MC[key][:, i] = NormalDensity.rvs(MCsize) + logsamples[:, i] = NormalDensity.logpdf(Y_MC[key][:, i]) + + logPriorLikelihoods = np.sum(logsamples, axis=1) + std_MC[key] = np.zeros((MCsize, means.shape[0])) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self.__normpdf(Y_MC, std_MC, obs_data, sigma2Dict) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.nansum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + # Utility function Eq.2 in Ref. (2) + # Posterior covariance matrix after observing data y + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # TODO: Calculate the correction factor for BME + # BMECorrFactor = self.BME_Corr_Weight(PCE_SparseBayes_can, + # ObservationData, sigma2Dict) + # BME += BMECorrFactor + # Haun et al implementation + # U_J_d = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + U_J_d = postExpLikelihoods - logBME + + # Marginal log likelihood + elif var == 'BME': + U_J_d = logBME + + # Entropy-based information gain + elif var == 'infEntropy': + logBME = np.log(np.nanmean(likelihoods)) + infEntropy = logBME - postExpPrior - postExpLikelihoods + U_J_d = infEntropy * -1 # -1 for minimization + + # Bayesian information criterion + elif var == 'BIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxL = np.nanmax(likelihoods) + U_J_d = -2 * np.log(maxL) + np.log(n_obs) * nModelParams + + # Akaike information criterion + elif var == 'AIC': + coeffs = self.MetaModel.coeffs_dict.values() + nModelParams = max(len(v) for val in coeffs for v in val.values()) + maxlogL = np.log(np.nanmax(likelihoods)) + AIC = -2 * maxlogL + 2 * nModelParams + # 2 * nModelParams * (nModelParams+1) / (n_obs-nModelParams-1) + penTerm = 0 + U_J_d = 1*(AIC + penTerm) + + # Deviance information criterion + elif var == 'DIC': + # D_theta_bar = np.mean(-2 * Likelihoods) + N_star_p = 0.5 * np.var(np.log(likelihoods[likelihoods != 0])) + Likelihoods_theta_mean = self.__normpdf( + Y_mean_can, Y_std_can, obs_data, sigma2Dict + ) + DIC = -2 * np.log(Likelihoods_theta_mean) + 2 * N_star_p + + U_J_d = DIC + + else: + print('The algorithm you requested has not been implemented yet!') + + # Handle inf and NaN (replace by zero) + if np.isnan(U_J_d) or U_J_d == -np.inf or U_J_d == np.inf: + U_J_d = 0.0 + + # Clear memory + del likelihoods + del Y_MC + del std_MC + gc.collect(generation=2) + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def update_metamodel(self, MetaModel, output, y_hat_can, univ_p_val, index, + new_pca=False): + BasisIndices = MetaModel.basis_dict[output]["y_"+str(index+1)] + clf_poly = MetaModel.clf_poly[output]["y_"+str(index+1)] + Mn = clf_poly.coef_ + Sn = clf_poly.sigma_ + beta = clf_poly.alpha_ + active = clf_poly.active_ + Psi = self.MetaModel.create_psi(BasisIndices, univ_p_val) + + Sn_new_inv = np.linalg.inv(Sn) + Sn_new_inv += beta * np.dot(Psi[:, active].T, Psi[:, active]) + Sn_new = np.linalg.inv(Sn_new_inv) + + Mn_new = np.dot(Sn_new_inv, Mn[active]).reshape(-1, 1) + Mn_new += beta * np.dot(Psi[:, active].T, y_hat_can) + Mn_new = np.dot(Sn_new, Mn_new).flatten() + + # Compute the old and new moments of PCEs + mean_old = Mn[0] + mean_new = Mn_new[0] + std_old = np.sqrt(np.sum(np.square(Mn[1:]))) + std_new = np.sqrt(np.sum(np.square(Mn_new[1:]))) + + # Back transformation if PCA is selected. + if MetaModel.dim_red_method.lower() == 'pca': + old_pca = MetaModel.pca[output] + mean_old = old_pca.mean_[index] + mean_old += np.sum(mean_old * old_pca.components_[:, index]) + std_old = np.sqrt(np.sum(std_old**2 * + old_pca.components_[:, index]**2)) + mean_new = new_pca.mean_[index] + mean_new += np.sum(mean_new * new_pca.components_[:, index]) + std_new = np.sqrt(np.sum(std_new**2 * + new_pca.components_[:, index]**2)) + # print(f"mean_old: {mean_old:.2f} mean_new: {mean_new:.2f}") + # print(f"std_old: {std_old:.2f} std_new: {std_new:.2f}") + # Store the old and new moments of PCEs + results = { + 'mean_old': mean_old, + 'mean_new': mean_new, + 'std_old': std_old, + 'std_new': std_new + } + return results + + # ------------------------------------------------------------------------- + def util_BayesianDesign_old(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + Model = self.Model + MetaModel = deepcopy(self.MetaModel) + old_EDY = MetaModel.ExpDesign.Y + + # Evaluate the PCE metamodels using the candidate design + Y_PC_can, Y_std_can = self.MetaModel.eval_metamodel( + samples=np.array([X_can]) + ) + + # Generate y from posterior predictive + m_size = 100 + y_hat_samples = {} + for idx, key in enumerate(Model.Output.names): + means, stds = Y_PC_can[key][0], Y_std_can[key][0] + y_hat_samples[key] = np.random.multivariate_normal( + means, np.diag(stds), m_size) + + # Create the SparseBayes-based PCE metamodel: + MetaModel.input_obj.poly_coeffs_flag = False + univ_p_val = self.MetaModel.univ_basis_vals(X_can) + G_n_m_all = np.zeros((m_size, len(Model.Output.names), Model.n_obs)) + + for i in range(m_size): + for idx, key in enumerate(Model.Output.names): + if MetaModel.dim_red_method.lower() == 'pca': + # Equal number of components + new_outputs = np.vstack( + (old_EDY[key], y_hat_samples[key][i]) + ) + new_pca, _ = MetaModel.pca_transformation(new_outputs) + target = new_pca.transform( + y_hat_samples[key][i].reshape(1, -1) + )[0] + else: + new_pca, target = False, y_hat_samples[key][i] + + for j in range(len(target)): + + # Update surrogate + result = self.update_metamodel( + MetaModel, key, target[j], univ_p_val, j, new_pca) + + # Compute Expected Information Gain (Eq. 39) + G_n_m = np.log(result['std_old']/result['std_new']) - 1./2 + G_n_m += result['std_new']**2 / (2*result['std_old']**2) + G_n_m += (result['mean_new'] - result['mean_old'])**2 /\ + (2*result['std_old']**2) + + G_n_m_all[i, idx, j] = G_n_m + + U_J_d = G_n_m_all.mean(axis=(1, 2)).mean() + return -1 * U_J_d + + # ------------------------------------------------------------------------- + def util_BayesianDesign(self, X_can, X_MC, sigma2Dict, var='DKL'): + """ + Computes scores based on Bayesian sequential design criterion (var). + + Parameters + ---------- + X_can : array of shape (n_samples, n_params) + Candidate samples. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + var : string, optional + Bayesian design criterion. The default is 'DKL'. + + Returns + ------- + float + Score. + + """ + + # To avoid changes ub original aPCE object + Model = self.Model + MetaModel = deepcopy(self.MetaModel) + out_names = MetaModel.ModelObj.Output.names + if X_can.ndim == 1: + X_can = X_can.reshape(1, -1) + + # Compute the mean and std based on the MetaModel + # pce_means, pce_stds = self._compute_pce_moments(MetaModel) + if var == 'ALC': + Y_MC, Y_MC_std = MetaModel.eval_metamodel(samples=X_MC) + + # Old Experimental design + oldExpDesignX = MetaModel.ExpDesign.X + oldExpDesignY = MetaModel.ExpDesign.Y + + # Evaluate the PCE metamodels at that location ??? + Y_PC_can, Y_std_can = MetaModel.eval_metamodel(samples=X_can) + + # Add all suggestion as new ExpDesign + NewExpDesignX = np.vstack((oldExpDesignX, X_can)) + + NewExpDesignY = {} + for key in oldExpDesignY.keys(): + try: + NewExpDesignY[key] = np.vstack((oldExpDesignY[key], + Y_PC_can[key])) + except: + NewExpDesignY[key] = oldExpDesignY[key] + + MetaModel.ExpDesign.sampling_method = 'user' + MetaModel.ExpDesign.X = NewExpDesignX + MetaModel.ExpDesign.Y = NewExpDesignY + + # Train the model for the observed data using x_can + MetaModel.input_obj.poly_coeffs_flag = False + MetaModel.train_norm_design(parallel=False) + PCE_Model_can = MetaModel + + if var.lower() == 'mi': + # Mutual information based on Krause et al + # Adapted from Beck & Guillas (MICE) paper + _, std_PC_can = PCE_Model_can.eval_metamodel(samples=X_can) + std_can = {key: std_PC_can[key] for key in out_names} + + std_old = {key: Y_std_can[key] for key in out_names} + + varPCE = np.zeros((len(out_names))) + for i, key in enumerate(out_names): + varPCE[i] = np.mean(std_old[key]**2/std_can[key]**2) + score = np.mean(varPCE) + + return -1 * score + + elif var.lower() == 'alc': + # Active learning based on Gramyc and Lee + # Adaptive design and analysis of supercomputer experiments Techno- + # metrics, 51 (2009), pp. 130–145. + + # Evaluate the MetaModel at the given samples + Y_MC_can, Y_MC_std_can = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Compute the score + score = [] + for i, key in enumerate(out_names): + pce_var = Y_MC_std_can[key]**2 + pce_var_can = Y_MC_std[key]**2 + score.append(np.mean(pce_var-pce_var_can, axis=0)) + score = np.mean(score) + + return -1 * score + + # ---------- Inner MC simulation for computing Utility Value ---------- + # Estimation of the integral via Monte Varlo integration + MCsize = X_MC.shape[0] + ESS = 0 + + while ((ESS > MCsize) or (ESS < 1)): + + # Enriching Monte Carlo samples if need be + if ESS != 0: + X_MC = self.MetaModel.ExpDesign.generate_samples( + MCsize, 'random' + ) + + # Evaluate the MetaModel at the given samples + Y_MC, std_MC = PCE_Model_can.eval_metamodel(samples=X_MC) + + # Likelihood computation (Comparison of data and simulation + # results via PCE with candidate design) + likelihoods = self.__normpdf( + Y_MC, std_MC, self.observations, sigma2Dict + ) + + # Check the Effective Sample Size (1<ESS<MCsize) + ESS = 1 / np.sum(np.square(likelihoods/np.sum(likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if ((ESS > MCsize) or (ESS < 1)): + print("--- increasing MC size---") + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (likelihoods/np.max(likelihoods)) >= unif + + # -------------------- Utility functions -------------------- + # Utility function Eq.2 in Ref. (2) + # Kullback-Leibler Divergence (Sergey's paper) + if var == 'DKL': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods, dtype=np.float128)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Haun et al implementation + U_J_d = np.mean(np.log(likelihoods[likelihoods != 0]) - logBME) + + # U_J_d = np.sum(G_n_m_all) + # Ryan et al (2014) implementation + # importanceWeights = Likelihoods[Likelihoods!=0]/np.sum(Likelihoods[Likelihoods!=0]) + # U_J_d = np.mean(importanceWeights*np.log(Likelihoods[Likelihoods!=0])) - logBME + + # U_J_d = postExpLikelihoods - logBME + + # Marginal likelihood + elif var == 'BME': + + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + U_J_d = logBME + + # Bayes risk likelihood + elif var == 'BayesRisk': + + U_J_d = -1 * np.var(likelihoods) + + # Entropy-based information gain + elif var == 'infEntropy': + # Prior-based estimation of BME + logBME = np.log(np.nanmean(likelihoods)) + + # Posterior-based expectation of likelihoods + postLikelihoods = likelihoods[accepted] / np.nansum(likelihoods[accepted]) + postExpLikelihoods = np.mean(np.log(postLikelihoods)) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean(logPriorLikelihoods[accepted]) + + infEntropy = logBME - postExpPrior - postExpLikelihoods + + U_J_d = infEntropy * -1 # -1 for minimization + + # D-Posterior-precision + elif var == 'DPP': + X_Posterior = X_MC[accepted] + # covariance of the posterior parameters + U_J_d = -np.log(np.linalg.det(np.cov(X_Posterior))) + + # A-Posterior-precision + elif var == 'APP': + X_Posterior = X_MC[accepted] + # trace of the posterior parameters + U_J_d = -np.log(np.trace(np.cov(X_Posterior))) + + else: + print('The algorithm you requested has not been implemented yet!') + + # Clear memory + del likelihoods + del Y_MC + del std_MC + gc.collect(generation=2) + + return -1 * U_J_d # -1 is for minimization instead of maximization + + # ------------------------------------------------------------------------- + def subdomain(self, Bounds, n_new_samples): + """ + Divides a domain defined by Bounds into sub domains. + + Parameters + ---------- + Bounds : list of tuples + List of lower and upper bounds. + n_new_samples : TYPE + DESCRIPTION. + + Returns + ------- + Subdomains : TYPE + DESCRIPTION. + + """ + n_params = self.MetaModel.n_params + n_subdomains = n_new_samples + 1 + LinSpace = np.zeros((n_params, n_subdomains)) + + for i in range(n_params): + LinSpace[i] = np.linspace(start=Bounds[i][0], stop=Bounds[i][1], + num=n_subdomains) + Subdomains = [] + for k in range(n_subdomains-1): + mylist = [] + for i in range(n_params): + mylist.append((LinSpace[i, k+0], LinSpace[i, k+1])) + Subdomains.append(tuple(mylist)) + + return Subdomains + + # ------------------------------------------------------------------------- + def run_util_func(self, method, candidates, index, sigma2Dict=None, + var=None, X_MC=None): + """ + Runs the utility function based on the given method. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + candidates : array of shape (n_samples, n_params) + All candidate parameter sets. + index : int + ExpDesign index. + sigma2Dict : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + var : string, optional + Utility function. The default is None. + X_MC : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + index : TYPE + DESCRIPTION. + List + Scores. + + """ + + if method.lower() == 'varoptdesign': + # U_J_d = self.util_VarBasedDesign(candidates, index, var) + U_J_d = np.zeros((candidates.shape[0])) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="varoptdesign"): + U_J_d[idx] = self.util_VarBasedDesign(X_can, index, var) + + elif method.lower() == 'bayesactdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianActiveDesign(X_can, sigma2Dict, + var) + elif method.lower() == 'bayesoptdesign': + NCandidate = candidates.shape[0] + U_J_d = np.zeros((NCandidate)) + for idx, X_can in tqdm(enumerate(candidates), ascii=True, + desc="OptBayesianDesign"): + U_J_d[idx] = self.util_BayesianDesign(X_can, X_MC, sigma2Dict, + var) + return (index, -1 * U_J_d) + + # ------------------------------------------------------------------------- + def dual_annealing(self, method, Bounds, sigma2Dict, var, Run_No, + verbose=False): + """ + Exploration algorithim to find the optimum parameter space. + + Parameters + ---------- + method : string + Exploitation method: `VarOptDesign`, `BayesActDesign` and + `BayesOptDesign`. + Bounds : list of tuples + List of lower and upper boundaries of parameters. + sigma2Dict : dict + A dictionary containing the measurement errors (sigma^2). + Run_No : int + Run number. + verbose : bool, optional + Print out a summary. The default is False. + + Returns + ------- + Run_No : int + Run number. + array + Optimial candidate. + + """ + + Model = self.Model + max_func_itr = self.MetaModel.ExpDesign.max_func_itr + + if method == 'VarOptDesign': + Res_Global = opt.dual_annealing(self.util_VarBasedDesign, + bounds=Bounds, + args=(Model, var), + maxfun=max_func_itr) + + elif method == 'BayesOptDesign': + Res_Global = opt.dual_annealing(self.util_BayesianDesign, + bounds=Bounds, + args=(Model, sigma2Dict, var), + maxfun=max_func_itr) + + if verbose: + print(f"Global minimum: xmin = {Res_Global.x}, " + f"f(xmin) = {Res_Global.fun:.6f}, nfev = {Res_Global.nfev}") + + return (Run_No, Res_Global.x) + + # ------------------------------------------------------------------------- + def tradoff_weights(self, tradeoff_scheme, old_EDX, old_EDY): + """ + Calculates weights for exploration scores based on the requested + scheme: `None`, `equal`, `epsilon-decreasing` and `adaptive`. + + `None`: No exploration. + `equal`: Same weights for exploration and exploitation scores. + `epsilon-decreasing`: Start with more exploration and increase the + influence of exploitation along the way with a exponential decay + function + `adaptive`: An adaptive method based on: + Liu, Haitao, Jianfei Cai, and Yew-Soon Ong. "An adaptive sampling + approach for Kriging metamodeling by maximizing expected prediction + error." Computers & Chemical Engineering 106 (2017): 171-182. + + Parameters + ---------- + tradeoff_scheme : string + Trade-off scheme for exloration and exploitation scores. + old_EDX : array (n_samples, n_params) + Old experimental design (training points). + old_EDY : dict + Old model responses (targets). + + Returns + ------- + exploration_weight : float + Exploration weight. + exploitation_weight: float + Exploitation weight. + + """ + if tradeoff_scheme is None: + exploration_weight = 0 + + elif tradeoff_scheme == 'equal': + exploration_weight = 0.5 + + elif tradeoff_scheme == 'epsilon-decreasing': + # epsilon-decreasing scheme + # Start with more exploration and increase the influence of + # exploitation along the way with a exponential decay function + initNSamples = self.MetaModel.ExpDesign.n_init_samples + n_max_samples = self.MetaModel.ExpDesign.n_max_samples + + itrNumber = (self.MetaModel.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.MetaModel.ExpDesign.n_new_samples + + tau2 = -(n_max_samples-initNSamples-1) / np.log(1e-8) + exploration_weight = signal.exponential(n_max_samples-initNSamples, + 0, tau2, False)[itrNumber] + + elif tradeoff_scheme == 'adaptive': + + # Extract itrNumber + initNSamples = self.MetaModel.ExpDesign.n_init_samples + n_max_samples = self.MetaModel.ExpDesign.n_max_samples + itrNumber = (self.MetaModel.ExpDesign.X.shape[0] - initNSamples) + itrNumber //= self.MetaModel.ExpDesign.n_new_samples + + if itrNumber == 0: + exploration_weight = 0.5 + else: + # New adaptive trade-off according to Liu et al. (2017) + # Mean squared error for last design point + last_EDX = old_EDX[-1].reshape(1, -1) + lastPCEY, _ = self.MetaModel.eval_metamodel(samples=last_EDX) + pce_y = np.array(list(lastPCEY.values()))[:, 0] + y = np.array(list(old_EDY.values()))[:, -1, :] + mseError = mean_squared_error(pce_y, y) + + # Mean squared CV - error for last design point + pce_y_prev = np.array(list(self._y_hat_prev.values()))[:, 0] + mseCVError = mean_squared_error(pce_y_prev, y) + + exploration_weight = min([0.5*mseError/mseCVError, 1]) + + # Exploitation weight + exploitation_weight = 1 - exploration_weight + + return exploration_weight, exploitation_weight + + # ------------------------------------------------------------------------- + def opt_SeqDesign(self, sigma2, n_candidates=5, var='DKL'): + """ + Runs optimal sequential design. + + Parameters + ---------- + sigma2 : dict, optional + A dictionary containing the measurement errors (sigma^2). The + default is None. + n_candidates : int, optional + Number of candidate samples. The default is 5. + var : string, optional + Utility function. The default is None. + + Raises + ------ + NameError + Wrong utility function. + + Returns + ------- + Xnew : array (n_samples, n_params) + Selected new training point(s). + """ + + # Initialization + MetaModel = self.MetaModel + Bounds = MetaModel.bound_tuples + n_new_samples = MetaModel.ExpDesign.n_new_samples + explore_method = MetaModel.ExpDesign.explore_method + exploit_method = MetaModel.ExpDesign.exploit_method + n_cand_groups = MetaModel.ExpDesign.n_cand_groups + tradeoff_scheme = MetaModel.ExpDesign.tradeoff_scheme + + old_EDX = MetaModel.ExpDesign.X + old_EDY = MetaModel.ExpDesign.Y.copy() + ndim = MetaModel.ExpDesign.X.shape[1] + OutputNames = MetaModel.ModelObj.Output.names + + # ----------------------------------------- + # ----------- CUSTOMIZED METHODS ---------- + # ----------------------------------------- + # Utility function exploit_method provided by user + if exploit_method.lower() == 'user': + + Xnew, filteredSamples = MetaModel.ExpDesign.ExploitFunction(self) + + print("\n") + print("\nXnew:\n", Xnew) + + return Xnew, filteredSamples + + # ----------------------------------------- + # ---------- EXPLORATION METHODS ---------- + # ----------------------------------------- + if explore_method == 'dual annealing': + # ------- EXPLORATION: OPTIMIZATION ------- + import time + start_time = time.time() + + # Divide the domain to subdomains + args = [] + subdomains = self.subdomain(Bounds, n_new_samples) + for i in range(n_new_samples): + args.append((exploit_method, subdomains[i], sigma2, var, i)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + + # With Pool.starmap_async() + results = pool.starmap_async(self.dual_annealing, args).get() + + # Close the pool + pool.close() + + Xnew = np.array([results[i][1] for i in range(n_new_samples)]) + + print("\nXnew:\n", Xnew) + + elapsed_time = time.time() - start_time + print("\n") + print(f"Elapsed_time: {round(elapsed_time,2)} sec.") + print('-'*20) + + elif explore_method == 'LOOCV': + # ----------------------------------------------------------------- + # TODO: LOOCV model construnction based on Feng et al. (2020) + # 'LOOCV': + # Initilize the ExploitScore array + + # Generate random samples + allCandidates = MetaModel.ExpDesign.generate_samples(n_candidates, + 'random') + + # Construct error model based on LCerror + errorModel = MetaModel.create_ModelError(old_EDX, self.LCerror) + self.errorModel.append(copy(errorModel)) + + # Evaluate the error models for allCandidates + eLCAllCands, _ = errorModel.eval_errormodel(allCandidates) + # Select the maximum as the representative error + eLCAllCands = np.dstack(eLCAllCands.values()) + eLCAllCandidates = np.max(eLCAllCands, axis=1)[:, 0] + + # Normalize the error w.r.t the maximum error + scoreExploration = eLCAllCandidates / np.sum(eLCAllCandidates) + + else: + # ------- EXPLORATION: SPACE-FILLING DESIGN ------- + # Generate candidate samples from Exploration class + explore = Exploration(MetaModel, n_candidates) + explore.w = 100 # * ndim #500 + # Select criterion (mc-intersite-proj-th, mc-intersite-proj) + explore.mc_criterion = 'mc-intersite-proj' + allCandidates, scoreExploration = explore.get_exploration_samples() + + # Temp: ---- Plot all candidates ----- + if ndim == 2: + def plotter(points, allCandidates, Method, + scoreExploration=None): + if Method == 'Voronoi': + from scipy.spatial import Voronoi, voronoi_plot_2d + vor = Voronoi(points) + fig = voronoi_plot_2d(vor) + ax1 = fig.axes[0] + else: + fig = plt.figure() + ax1 = fig.add_subplot(111) + ax1.scatter(points[:, 0], points[:, 1], s=10, c='r', + marker="s", label='Old Design Points') + ax1.scatter(allCandidates[:, 0], allCandidates[:, 1], s=10, + c='b', marker="o", label='Design candidates') + for i in range(points.shape[0]): + txt = 'p'+str(i+1) + ax1.annotate(txt, (points[i, 0], points[i, 1])) + if scoreExploration is not None: + for i in range(allCandidates.shape[0]): + txt = str(round(scoreExploration[i], 5)) + ax1.annotate(txt, (allCandidates[i, 0], + allCandidates[i, 1])) + + plt.xlim(self.bound_tuples[0]) + plt.ylim(self.bound_tuples[1]) + # plt.show() + plt.legend(loc='upper left') + + # ----------------------------------------- + # --------- EXPLOITATION METHODS ---------- + # ----------------------------------------- + if exploit_method == 'BayesOptDesign' or\ + exploit_method == 'BayesActDesign': + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\n Exploration weight={explore_w:0.3f} " + f"Exploitation weight={exploit_w:0.3f}\n") + + # ------- EXPLOITATION: BayesOptDesign & ActiveLearning ------- + if explore_w != 1.0: + + # Create a sample pool for rejection sampling + MCsize = 15000 + X_MC = MetaModel.ExpDesign.generate_samples(MCsize, 'random') + candidates = MetaModel.ExpDesign.generate_samples( + MetaModel.ExpDesign.max_func_itr, 'latin_hypercube') + + # Split the candidates in groups for multiprocessing + split_cand = np.array_split( + candidates, n_cand_groups, axis=0 + ) + + results = Parallel(n_jobs=-1, backend='threading')( + delayed(self.run_util_func)( + exploit_method, split_cand[i], i, sigma2, var, X_MC) + for i in range(n_cand_groups)) + # out = map(self.run_util_func, + # [exploit_method]*n_cand_groups, + # split_cand, + # range(n_cand_groups), + # [sigma2] * n_cand_groups, + # [var] * n_cand_groups, + # [X_MC] * n_cand_groups + # ) + # results = list(out) + + # Retrieve the results and append them + U_J_d = np.concatenate([results[NofE][1] for NofE in + range(n_cand_groups)]) + + # Check if all scores are inf + if np.isinf(U_J_d).all() or np.isnan(U_J_d).all(): + U_J_d = np.ones(len(U_J_d)) + + # Get the expected value (mean) of the Utility score + # for each cell + if explore_method == 'Voronoi': + U_J_d = np.mean(U_J_d.reshape(-1, n_candidates), axis=1) + + # create surrogate model for U_J_d + from sklearn.preprocessing import MinMaxScaler + # Take care of inf entries + good_indices = [i for i, arr in enumerate(U_J_d) + if np.isfinite(arr).all()] + scaler = MinMaxScaler() + X_S = scaler.fit_transform(candidates[good_indices]) + gp = MetaModel.gaussian_process_emulator( + X_S, U_J_d[good_indices], autoSelect=True + ) + U_J_d = gp.predict(scaler.transform(allCandidates)) + + # Normalize U_J_d + norm_U_J_d = U_J_d / np.sum(U_J_d) + print("norm_U_J_d:\n", norm_U_J_d) + else: + norm_U_J_d = np.zeros((len(scoreExploration))) + + # ------- Calculate Total score ------- + # ------- Trade off between EXPLORATION & EXPLOITATION ------- + # Total score + totalScore = exploit_w * norm_U_J_d + totalScore += explore_w * scoreExploration + + # temp: Plot + # dim = self.ExpDesign.X.shape[1] + # if dim == 2: + # plotter(self.ExpDesign.X, allCandidates, explore_method) + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + # select the requested number of samples + if explore_method == 'Voronoi': + Xnew = np.zeros((n_new_samples, ndim)) + for i, idx in enumerate(bestIdx): + X_can = explore.closestPoints[idx] + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + else: + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + elif exploit_method == 'VarOptDesign': + # ------- EXPLOITATION: VarOptDesign ------- + UtilMethod = var + + # ------- Calculate Exoploration weight ------- + # Compute exploration weight based on trade off scheme + explore_w, exploit_w = self.tradoff_weights(tradeoff_scheme, + old_EDX, + old_EDY) + print(f"\nweightExploration={explore_w:0.3f} " + f"weightExploitation={exploit_w:0.3f}") + + # Generate candidate samples from Exploration class + nMeasurement = old_EDY[OutputNames[0]].shape[1] + + # Find sensitive region + if UtilMethod == 'LOOCV': + LCerror = MetaModel.LCerror + allModifiedLOO = np.zeros((len(old_EDX), len(OutputNames), + nMeasurement)) + for y_idx, y_key in enumerate(OutputNames): + for idx, key in enumerate(LCerror[y_key].keys()): + allModifiedLOO[:, y_idx, idx] = abs( + LCerror[y_key][key]) + + ExploitScore = np.max(np.max(allModifiedLOO, axis=1), axis=1) + + elif UtilMethod in ['EIGF', 'ALM']: + # ----- All other in ['EIGF', 'ALM'] ----- + # Initilize the ExploitScore array + ExploitScore = np.zeros((len(old_EDX), len(OutputNames))) + + # Split the candidates in groups for multiprocessing + if explore_method != 'Voronoi': + split_cand = np.array_split(allCandidates, + n_cand_groups, + axis=0) + goodSampleIdx = range(n_cand_groups) + else: + # Find indices of the Vornoi cells with samples + goodSampleIdx = [] + for idx in range(len(explore.closest_points)): + if len(explore.closest_points[idx]) != 0: + goodSampleIdx.append(idx) + split_cand = explore.closest_points + + # Split the candidates in groups for multiprocessing + args = [] + for index in goodSampleIdx: + args.append((exploit_method, split_cand[index], index, + sigma2, var)) + + # Multiprocessing + pool = multiprocessing.Pool(multiprocessing.cpu_count()) + # With Pool.starmap_async() + results = pool.starmap_async(self.run_util_func, args).get() + + # Close the pool + pool.close() + # out = map(self.run_util_func, + # [exploit_method]*len(goodSampleIdx), + # split_cand, + # range(len(goodSampleIdx)), + # [sigma2] * len(goodSampleIdx), + # [var] * len(goodSampleIdx) + # ) + # results = list(out) + + # Retrieve the results and append them + if explore_method == 'Voronoi': + ExploitScore = [np.mean(results[k][1]) for k in + range(len(goodSampleIdx))] + else: + ExploitScore = np.concatenate( + [results[k][1] for k in range(len(goodSampleIdx))]) + + else: + raise NameError('The requested utility function is not ' + 'available.') + + # print("ExploitScore:\n", ExploitScore) + + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + # Total score + # Normalize U_J_d + ExploitScore = ExploitScore / np.sum(ExploitScore) + totalScore = exploit_w * ExploitScore + totalScore += explore_w * scoreExploration + + temp = totalScore.copy() + sorted_idxtotalScore = np.argsort(temp, axis=0)[::-1] + bestIdx = sorted_idxtotalScore[:n_new_samples] + + Xnew = np.zeros((n_new_samples, ndim)) + if explore_method != 'Voronoi': + Xnew = allCandidates[bestIdx] + else: + for i, idx in enumerate(bestIdx.flatten()): + X_can = explore.closest_points[idx] + # plotter(self.ExpDesign.X, X_can, explore_method, + # scoreExploration=None) + + # Calculate the maxmin score for the region of interest + newSamples, maxminScore = explore.get_mc_samples(X_can) + + # select the requested number of samples + Xnew[i] = newSamples[np.argmax(maxminScore)] + + elif exploit_method == 'alphabetic': + # ------- EXPLOITATION: ALPHABETIC ------- + Xnew = self.util_AlphOptDesign(allCandidates, var) + + elif exploit_method == 'Space-filling': + # ------- EXPLOITATION: SPACE-FILLING ------- + totalScore = scoreExploration + + # ------- Select the best candidate ------- + # find an optimal point subset to add to the initial design by + # maximization of the utility score and taking care of NaN values + temp = totalScore.copy() + temp[np.isnan(totalScore)] = -np.inf + sorted_idxtotalScore = np.argsort(temp)[::-1] + + # select the requested number of samples + Xnew = allCandidates[sorted_idxtotalScore[:n_new_samples]] + + else: + raise NameError('The requested design method is not available.') + + print("\n") + print("\nRun No. {}:".format(old_EDX.shape[0]+1)) + print("Xnew:\n", Xnew) + gc.collect() + + return Xnew, None + + # ------------------------------------------------------------------------- + def util_AlphOptDesign(self, candidates, var='D-Opt'): + """ + Enriches the Experimental design with the requested alphabetic + criterion based on exploring the space with number of sampling points. + + Ref: Hadigol, M., & Doostan, A. (2018). Least squares polynomial chaos + expansion: A review of sampling strategies., Computer Methods in + Applied Mechanics and Engineering, 332, 382-407. + + Arguments + --------- + NCandidate : int + Number of candidate points to be searched + + var : string + Alphabetic optimality criterion + + Returns + ------- + X_new : array of shape (1, n_params) + The new sampling location in the input space. + """ + MetaModelOrig = self + Model = self.Model + n_new_samples = MetaModelOrig.ExpDesign.n_new_samples + NCandidate = candidates.shape[0] + + # TODO: Loop over outputs + OutputName = Model.Output.names[0] + + # To avoid changes ub original aPCE object + MetaModel = deepcopy(MetaModelOrig) + + # Old Experimental design + oldExpDesignX = MetaModel.ExpDesign.X + + # TODO: Only one psi can be selected. + # Suggestion: Go for the one with the highest LOO error + Scores = list(MetaModel.score_dict[OutputName].values()) + ModifiedLOO = [1-score for score in Scores] + outIdx = np.argmax(ModifiedLOO) + + # Initialize Phi to save the criterion's values + Phi = np.zeros((NCandidate)) + + BasisIndices = MetaModelOrig.basis_dict[OutputName]["y_"+str(outIdx+1)] + P = len(BasisIndices) + + # ------ Old Psi ------------ + univ_p_val = MetaModelOrig.univ_basis_vals(oldExpDesignX) + Psi = MetaModelOrig.create_psi(BasisIndices, univ_p_val) + + # ------ New candidates (Psi_c) ------------ + # Assemble Psi_c + univ_p_val_c = self.univ_basis_vals(candidates) + Psi_c = self.create_psi(BasisIndices, univ_p_val_c) + + for idx in range(NCandidate): + + # Include the new row to the original Psi + Psi_cand = np.vstack((Psi, Psi_c[idx])) + + # Information matrix + PsiTPsi = np.dot(Psi_cand.T, Psi_cand) + M = PsiTPsi / (len(oldExpDesignX)+1) + + if np.linalg.cond(PsiTPsi) > 1e-12 \ + and np.linalg.cond(PsiTPsi) < 1 / sys.float_info.epsilon: + # faster + invM = linalg.solve(M, sparse.eye(PsiTPsi.shape[0]).toarray()) + else: + # stabler + invM = np.linalg.pinv(M) + + # ---------- Calculate optimality criterion ---------- + # Optimality criteria according to Section 4.5.1 in Ref. + + # D-Opt + if var == 'D-Opt': + Phi[idx] = (np.linalg.det(invM)) ** (1/P) + + # A-Opt + elif var == 'A-Opt': + Phi[idx] = np.trace(invM) + + # K-Opt + elif var == 'K-Opt': + Phi[idx] = np.linalg.cond(M) + + else: + raise Exception('The optimality criterion you requested has ' + 'not been implemented yet!') + + # find an optimal point subset to add to the initial design + # by minimization of the Phi + sorted_idxtotalScore = np.argsort(Phi) + + # select the requested number of samples + Xnew = candidates[sorted_idxtotalScore[:n_new_samples]] + + return Xnew + + # ------------------------------------------------------------------------- + def __normpdf(self, y_hat_pce, std_pce, obs_data, total_sigma2s, + rmse=None): + + Model = self.Model + likelihoods = 1.0 + + # Loop over the outputs + for idx, out in enumerate(Model.Output.names): + + # (Meta)Model Output + nsamples, nout = y_hat_pce[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout].values + + # Surrogate error if valid dataset is given. + if rmse is not None: + tot_sigma2s += rmse[out]**2 + + likelihoods *= stats.multivariate_normal.pdf( + y_hat_pce[out], data, np.diag(tot_sigma2s), + allow_singular=True) + self.Likelihoods = likelihoods + + return likelihoods + + # ------------------------------------------------------------------------- + def __corr_factor_BME(self, obs_data, total_sigma2s, logBME): + """ + Calculates the correction factor for BMEs. + """ + MetaModel = self.MetaModel + samples = MetaModel.ExpDesign.X # valid_samples + model_outputs = MetaModel.ExpDesign.Y # valid_model_runs + Model = MetaModel.ModelObj + n_samples = samples.shape[0] + + # Extract the requested model outputs for likelihood calulation + output_names = Model.Output.names + + # TODO: Evaluate MetaModel on the experimental design and ValidSet + OutputRS, stdOutputRS = MetaModel.eval_metamodel(samples=samples) + + logLik_data = np.zeros((n_samples)) + logLik_model = np.zeros((n_samples)) + # Loop over the outputs + for idx, out in enumerate(output_names): + + # (Meta)Model Output + nsamples, nout = model_outputs[out].shape + + # Prepare data and remove NaN + try: + data = obs_data[out].values[~np.isnan(obs_data[out])] + except AttributeError: + data = obs_data[out][~np.isnan(obs_data[out])] + + # Prepare sigma2s + non_nan_indices = ~np.isnan(total_sigma2s[out]) + tot_sigma2s = total_sigma2s[out][non_nan_indices][:nout] + + # Covariance Matrix + covMatrix_data = np.diag(tot_sigma2s) + + for i, sample in enumerate(samples): + + # Simulation run + y_m = model_outputs[out][i] + + # Surrogate prediction + y_m_hat = OutputRS[out][i] + + # CovMatrix with the surrogate error + # covMatrix = np.diag(stdOutputRS[out][i]**2) + covMatrix = np.diag((y_m-y_m_hat)**2) + covMatrix = np.diag( + np.mean((model_outputs[out]-OutputRS[out]), axis=0)**2 + ) + + # Compute likelilhood output vs data + logLik_data[i] += self.__logpdf( + y_m_hat, data, covMatrix_data + ) + + # Compute likelilhood output vs surrogate + logLik_model[i] += self.__logpdf(y_m_hat, y_m, covMatrix) + + # Weight + logLik_data -= logBME + weights = np.exp(logLik_model+logLik_data) + + return np.log(np.mean(weights)) + + # ------------------------------------------------------------------------- + def __logpdf(self, x, mean, cov): + """ + computes the likelihood based on a multivariate normal distribution. + + Parameters + ---------- + x : TYPE + DESCRIPTION. + mean : array_like + Observation data. + cov : 2d array + Covariance matrix of the distribution. + + Returns + ------- + log_lik : float + Log likelihood. + + """ + n = len(mean) + L = linalg.cholesky(cov, lower=True) + beta = np.sum(np.log(np.diag(L))) + dev = x - mean + alpha = dev.dot(linalg.cho_solve((L, True), dev)) + log_lik = -0.5 * alpha - beta - n / 2. * np.log(2 * np.pi) + + return log_lik + + # ------------------------------------------------------------------------- + def __posteriorPlot(self, posterior, par_names, key): + + # Initialization + newpath = (r'Outputs_SeqPosteriorComparison/posterior') + os.makedirs(newpath, exist_ok=True) + + bound_tuples = self.MetaModel.bound_tuples + n_params = len(par_names) + font_size = 40 + if n_params == 2: + + figPosterior, ax = plt.subplots(figsize=(15, 15)) + + sns.kdeplot(x=posterior[:, 0], y=posterior[:, 1], + fill=True, ax=ax, cmap=plt.cm.jet, + clip=bound_tuples) + # Axis labels + plt.xlabel(par_names[0], fontsize=font_size) + plt.ylabel(par_names[1], fontsize=font_size) + + # Set axis limit + plt.xlim(bound_tuples[0]) + plt.ylim(bound_tuples[1]) + + # Increase font size + plt.xticks(fontsize=font_size) + plt.yticks(fontsize=font_size) + + # Switch off the grids + plt.grid(False) + + else: + import corner + figPosterior = corner.corner(posterior, labels=par_names, + title_fmt='.2e', show_titles=True, + title_kwargs={"fontsize": 12}) + + figPosterior.savefig(f'./{newpath}/{key}.pdf', bbox_inches='tight') + plt.close() + + # Save the posterior as .npy + np.save(f'./{newpath}/{key}.npy', posterior) + + return figPosterior + + # ------------------------------------------------------------------------- + def __hellinger_distance(self, P, Q): + """ + Hellinger distance between two continuous distributions. + + The maximum distance 1 is achieved when P assigns probability zero to + every set to which Q assigns a positive probability, and vice versa. + 0 (identical) and 1 (maximally different) + + Parameters + ---------- + P : array + Reference likelihood. + Q : array + Estimated likelihood. + + Returns + ------- + float + Hellinger distance of two distributions. + + """ + mu1 = P.mean() + Sigma1 = np.std(P) + + mu2 = Q.mean() + Sigma2 = np.std(Q) + + term1 = np.sqrt(2*Sigma1*Sigma2 / (Sigma1**2 + Sigma2**2)) + + term2 = np.exp(-.25 * (mu1 - mu2)**2 / (Sigma1**2 + Sigma2**2)) + + H_squared = 1 - term1 * term2 + + return np.sqrt(H_squared) + + # ------------------------------------------------------------------------- + def __BME_Calculator(self, MetaModel, obs_data, sigma2Dict, rmse=None): + """ + This function computes the Bayesian model evidence (BME) via Monte + Carlo integration. + + """ + # Initializations + valid_likelihoods = MetaModel.valid_likelihoods + + post_snapshot = MetaModel.ExpDesign.post_snapshot + if post_snapshot or len(valid_likelihoods) != 0: + newpath = (r'Outputs_SeqPosteriorComparison/likelihood_vs_ref') + os.makedirs(newpath, exist_ok=True) + + SamplingMethod = 'random' + MCsize = 10000 + ESS = 0 + + # Estimation of the integral via Monte Varlo integration + while (ESS > MCsize) or (ESS < 1): + + # Generate samples for Monte Carlo simulation + X_MC = MetaModel.ExpDesign.generate_samples( + MCsize, SamplingMethod + ) + + # Monte Carlo simulation for the candidate design + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + Y_MC, std_MC = MetaModel.eval_metamodel(samples=X_MC) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"\nMemory eval_metamodel in BME: {m_2-m_1:.2f} MB") + + # Likelihood computation (Comparison of data and + # simulation results via PCE with candidate design) + Likelihoods = self.__normpdf( + Y_MC, std_MC, obs_data, sigma2Dict, rmse + ) + + # Check the Effective Sample Size (1000<ESS<MCsize) + ESS = 1 / np.sum(np.square(Likelihoods/np.sum(Likelihoods))) + + # Enlarge sample size if it doesn't fulfill the criteria + if (ESS > MCsize) or (ESS < 1): + print(f'ESS={ESS} MC size should be larger.') + MCsize *= 10 + ESS = 0 + + # Rejection Step + # Random numbers between 0 and 1 + unif = np.random.rand(1, MCsize)[0] + + # Reject the poorly performed prior + accepted = (Likelihoods/np.max(Likelihoods)) >= unif + X_Posterior = X_MC[accepted] + + # ------------------------------------------------------------ + # --- Kullback-Leibler Divergence & Information Entropy ------ + # ------------------------------------------------------------ + # Prior-based estimation of BME + logBME = np.log(np.nanmean(Likelihoods)) + + # TODO: Correction factor + # log_weight = self.__corr_factor_BME(obs_data, sigma2Dict, logBME) + + # Posterior-based expectation of likelihoods + postExpLikelihoods = np.mean(np.log(Likelihoods[accepted])) + + # Posterior-based expectation of prior densities + postExpPrior = np.mean( + np.log(MetaModel.ExpDesign.JDist.pdf(X_Posterior.T)) + ) + + # Calculate Kullback-Leibler Divergence + # KLD = np.mean(np.log(Likelihoods[Likelihoods!=0])- logBME) + KLD = postExpLikelihoods - logBME + + # Information Entropy based on Entropy paper Eq. 38 + infEntropy = logBME - postExpPrior - postExpLikelihoods + + # If post_snapshot is True, plot likelihood vs refrence + if post_snapshot or len(valid_likelihoods) != 0: + # Hellinger distance + ref_like = np.log(valid_likelihoods[valid_likelihoods > 0]) + est_like = np.log(Likelihoods[Likelihoods > 0]) + distHellinger = self.__hellinger_distance(ref_like, est_like) + + idx = len([name for name in os.listdir(newpath) if 'Likelihoods_' + in name and os.path.isfile(os.path.join(newpath, name))]) + fig, ax = plt.subplots() + try: + sns.kdeplot(np.log(valid_likelihoods[valid_likelihoods > 0]), + shade=True, color="g", label='Ref. Likelihood') + sns.kdeplot(np.log(Likelihoods[Likelihoods > 0]), shade=True, + color="b", label='Likelihood with PCE') + except: + pass + + text = f"Hellinger Dist.={distHellinger:.3f}\n logBME={logBME:.3f}" + "\n DKL={KLD:.3f}" + + plt.text(0.05, 0.75, text, bbox=dict(facecolor='wheat', + edgecolor='black', + boxstyle='round,pad=1'), + transform=ax.transAxes) + + fig.savefig(f'./{newpath}/Likelihoods_{idx}.pdf', + bbox_inches='tight') + plt.close() + + else: + distHellinger = 0.0 + + # Bayesian inference with Emulator only for 2D problem + if post_snapshot and MetaModel.n_params == 2 and not idx % 5: + from bayes_inference.bayes_inference import BayesInference + from bayes_inference.discrepancy import Discrepancy + import pandas as pd + BayesOpts = BayesInference(MetaModel) + BayesOpts.emulator = True + BayesOpts.plot_post_pred = False + + # Select the inference method + import emcee + BayesOpts.inference_method = "MCMC" + # Set the MCMC parameters passed to self.mcmc_params + BayesOpts.mcmc_params = { + 'n_steps': 1e5, + 'n_walkers': 30, + 'moves': emcee.moves.KDEMove(), + 'verbose': False + } + + # ----- Define the discrepancy model ------- + obs_data = pd.DataFrame(obs_data, columns=self.Model.Output.names) + BayesOpts.measurement_error = obs_data + + # # -- (Option B) -- + DiscrepancyOpts = Discrepancy('') + DiscrepancyOpts.type = 'Gaussian' + DiscrepancyOpts.parameters = obs_data**2 + BayesOpts.Discrepancy = DiscrepancyOpts + # Start the calibration/inference + Bayes_PCE = BayesOpts.create_inference() + X_Posterior = Bayes_PCE.posterior_df.values + + # Clean up + del Y_MC, std_MC + gc.collect() + + return (logBME, KLD, X_Posterior, Likelihoods, distHellinger) + + # ------------------------------------------------------------------------- + def __validError(self, MetaModel): + + # MetaModel = self.MetaModel + Model = MetaModel.ModelObj + OutputName = Model.Output.names + + # Extract the original model with the generated samples + valid_samples = MetaModel.valid_samples + valid_model_runs = MetaModel.valid_model_runs + + # Run the PCE model with the generated samples + m_1 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + valid_PCE_runs, valid_PCE_std = MetaModel.eval_metamodel(samples=valid_samples) + m_2 = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 + print(f"\nMemory eval_metamodel: {m_2-m_1:.2f} MB") + + rms_error = {} + valid_error = {} + # Loop over the keys and compute RMSE error. + for key in OutputName: + rms_error[key] = mean_squared_error( + valid_model_runs[key], valid_PCE_runs[key], + multioutput='raw_values', + sample_weight=None, + squared=False) + + # Validation error + valid_error[key] = (rms_error[key]**2) + valid_error[key] /= np.var(valid_model_runs[key], ddof=1, axis=0) + + # Print a report table + print("\n>>>>> Updated Errors of {} <<<<<".format(key)) + print("\nIndex | RMSE | Validation Error") + print('-'*35) + print('\n'.join(f'{i+1} | {k:.3e} | {j:.3e}' for i, (k, j) + in enumerate(zip(rms_error[key], + valid_error[key])))) + + return rms_error, valid_error + + # ------------------------------------------------------------------------- + def __error_Mean_Std(self): + + MetaModel = self.MetaModel + # Extract the mean and std provided by user + df_MCReference = MetaModel.ModelObj.mc_reference + + # Compute the mean and std based on the MetaModel + pce_means, pce_stds = self._compute_pce_moments(MetaModel) + + # Compute the root mean squared error + for output in MetaModel.ModelObj.Output.names: + + # Compute the error between mean and std of MetaModel and OrigModel + RMSE_Mean = mean_squared_error( + df_MCReference['mean'], pce_means[output], squared=False + ) + RMSE_std = mean_squared_error( + df_MCReference['std'], pce_means[output], squared=False + ) + + return RMSE_Mean, RMSE_std + + # ------------------------------------------------------------------------- + def _compute_pce_moments(self, MetaModel): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moment (mean) of the surrogate. + pce_stds: dict + The second moment (standard deviation) of the surrogate. + + """ + outputs = MetaModel.ModelObj.Output.names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(MetaModel.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = MetaModel.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = MetaModel.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = MetaModel.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if MetaModel.dim_red_method.lower() == 'pca': + PCA = MetaModel.pca[f'b_{b_i+1}'][output] + means[output] = PCA.mean_ + np.dot( + pce_mean, PCA.components_) + stds[output] = np.sqrt(np.dot(pce_var, + PCA.components_**2)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + return pce_means, pce_stds diff --git a/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/surrogate_models.py b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/surrogate_models.py new file mode 100644 index 000000000..a6d31ccd1 --- /dev/null +++ b/examples/umbridge_tsunamitutorial/bayesvalidrox/surrogate_models/surrogate_models.py @@ -0,0 +1,1473 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import warnings +import numpy as np +import math +import h5py +import matplotlib.pyplot as plt +from sklearn.preprocessing import MinMaxScaler +import scipy as sp +from tqdm import tqdm +from sklearn.decomposition import PCA as sklearnPCA +import sklearn.linear_model as lm +from sklearn.gaussian_process import GaussianProcessRegressor +import sklearn.gaussian_process.kernels as kernels +import os +from joblib import Parallel, delayed +import copy + +from .input_space import InputSpace +from .glexindex import glexindex +from .eval_rec_rule import eval_univ_basis +from .reg_fast_ard import RegressionFastARD +from .reg_fast_laplace import RegressionFastLaplace +from .orthogonal_matching_pursuit import OrthogonalMatchingPursuit +from .bayes_linear import VBLinearRegression, EBLinearRegression +from .apoly_construction import apoly_construction +warnings.filterwarnings("ignore") +# Load the mplstyle +plt.style.use(os.path.join(os.path.split(__file__)[0], + '../', 'bayesvalidrox.mplstyle')) + + +class MetaModel(): + """ + Meta (surrogate) model + + This class trains a surrogate model. It accepts an input object (input_obj) + containing the specification of the distributions for uncertain parameters + and a model object with instructions on how to run the computational model. + + Attributes + ---------- + input_obj : obj + Input object with the information on the model input parameters. + meta_model_type : str + Surrogate model types. Three surrogate model types are supported: + polynomial chaos expansion (`PCE`), arbitrary PCE (`aPCE`) and + Gaussian process regression (`GPE`). Default is PCE. + pce_reg_method : str + PCE regression method to compute the coefficients. The following + regression methods are available: + + 1. OLS: Ordinary Least Square method + 2. BRR: Bayesian Ridge Regression + 3. LARS: Least angle regression + 4. ARD: Bayesian ARD Regression + 5. FastARD: Fast Bayesian ARD Regression + 6. VBL: Variational Bayesian Learning + 7. EBL: Emperical Bayesian Learning + Default is `OLS`. + bootstrap_method : str + Bootstraping method. Options are `'normal'` and `'fast'`. The default + is `'fast'`. It means that in each iteration except the first one, only + the coefficent are recalculated with the ordinary least square method. + n_bootstrap_itrs : int + Number of iterations for the bootstrap sampling. The default is `1`. + pce_deg : int or list of int + Polynomial degree(s). If a list is given, an adaptive algorithm is used + to find the best degree with the lowest Leave-One-Out cross-validation + (LOO) error (or the highest score=1-LOO). Default is `1`. + pce_q_norm : float + Hyperbolic (or q-norm) truncation for multi-indices of multivariate + polynomials. Default is `1.0`. + dim_red_method : str + Dimensionality reduction method for the output space. The available + method is based on principal component analysis (PCA). The Default is + `'no'`. There are two ways to select number of components: use + percentage of the explainable variance threshold (between 0 and 100) + (Option A) or direct prescription of components' number (Option B): + + >>> MetaModelOpts.dim_red_method = 'PCA' + >>> MetaModelOpts.var_pca_threshold = 99.999 # Option A + >>> MetaModelOpts.n_pca_components = 12 # Option B + + verbose : bool + Prints summary of the regression results. Default is `False`. + + Note + ------- + To define the sampling methods and the training set, an experimental design + instance shall be defined. This can be done by: + + >>> MetaModelOpts.add_InputSpace() + + Two experimental design schemes are supported: one-shot (`normal`) and + adaptive sequential (`sequential`) designs. + For experimental design refer to `InputSpace`. + + """ + + def __init__(self, input_obj, meta_model_type='PCE', + pce_reg_method='OLS', bootstrap_method='fast', + n_bootstrap_itrs=1, pce_deg=1, pce_q_norm=1.0, + dim_red_method='no', verbose=False): + + self.input_obj = input_obj + self.meta_model_type = meta_model_type + self.pce_reg_method = pce_reg_method + self.bootstrap_method = bootstrap_method + self.n_bootstrap_itrs = n_bootstrap_itrs + self.pce_deg = pce_deg + self.pce_q_norm = pce_q_norm + self.dim_red_method = dim_red_method + self.verbose = verbose + + def build_metamodel(self, n_init_samples = None) -> None: + """ + Builds the parts for the metamodel (polynomes,...) that are neede before fitting. + + Returns + ------- + None + DESCRIPTION. + + """ + + # Add InputSpace to MetaModel if it does not have any + if not hasattr(self, 'InputSpace'): + self.InputSpace = InputSpace(self.input_obj) + self.InputSpace.n_init_samples = n_init_samples + self.InputSpace.init_param_space(np.max(self.pce_deg)) + + self.ndim = self.InputSpace.ndim + + if not hasattr(self, 'CollocationPoints'): + raise AttributeError('Please provide samples to the metamodel before building it.') + + self.n_params = len(self.input_obj.Marginals) + + # Generate polynomials + if self.meta_model_type.lower() != 'gpe': + self.generate_polynomials(np.max(self.pce_deg)) + + # Initialize the nested dictionaries + if self.meta_model_type.lower() == 'gpe': + self.gp_poly = self.auto_vivification() + self.x_scaler = self.auto_vivification() + self.LCerror = self.auto_vivification() + else: + self.deg_dict = self.auto_vivification() + self.q_norm_dict = self.auto_vivification() + self.coeffs_dict = self.auto_vivification() + self.basis_dict = self.auto_vivification() + self.score_dict = self.auto_vivification() + self.clf_poly = self.auto_vivification() + self.LCerror = self.auto_vivification() + if self.dim_red_method.lower() == 'pca': + self.pca = self.auto_vivification() + + # Define an array containing the degrees + self.CollocationPoints = np.array(self.CollocationPoints) + self.n_samples, ndim = self.CollocationPoints.shape + if self.ndim != ndim: + raise AttributeError('The given samples do not match the given number of priors. The samples should be a 2D array of size (#samples, #priors)') + + self.deg_array = self.__select_degree(ndim, self.n_samples) + + # Generate all basis indices + self.allBasisIndices = self.auto_vivification() + for deg in self.deg_array: + keys = self.allBasisIndices.keys() + if deg not in np.fromiter(keys, dtype=float): + # Generate the polynomial basis indices + for qidx, q in enumerate(self.pce_q_norm): + basis_indices = glexindex(start=0, stop=deg+1, + dimensions=self.n_params, + cross_truncation=q, + reverse=False, graded=True) + self.allBasisIndices[str(deg)][str(q)] = basis_indices + + + + def fit(self, X, y, parallel = True, verbose = False): + """ + Fits the surrogate to the given data (samples X, outputs y). + Note here that the samples X should be the transformed samples provided + by the experimental design if the transformation is used there. + + Parameters + ---------- + X : 2D list or np.array of shape (#samples, #dim) + The parameter value combinations that the model was evaluated at. + y : dict of 2D lists or arrays of shape (#samples, #timesteps) + The respective model evaluations. + + Returns + ------- + None. + + """ + X = np.array(X) + for key in y.keys(): + y_val = np.array(y[key]) + if y_val.ndim !=2: + raise ValueError('The given outputs y should be 2D') + y[key] = np.array(y[key]) + + # Output names are the same as the keys in y + self.out_names = list(y.keys()) + + # Build the MetaModel on the static samples + self.CollocationPoints = X + + # TODO: other option: rebuild every time + if not hasattr(self, 'deg_array'): + self.build_metamodel(n_init_samples = X.shape[1]) + + # Evaluate the univariate polynomials on InputSpace + if self.meta_model_type.lower() != 'gpe': + self.univ_p_val = self.univ_basis_vals(self.CollocationPoints) + + # --- Loop through data points and fit the surrogate --- + if verbose: + print(f"\n>>>> Training the {self.meta_model_type} metamodel " + "started. <<<<<<\n") + + # --- Bootstrap sampling --- + # Correct number of bootstrap if PCA transformation is required. + if self.dim_red_method.lower() == 'pca' and self.n_bootstrap_itrs == 1: + self.n_bootstrap_itrs = 100 + + # Check if fast version (update coeffs with OLS) is selected. + if self.bootstrap_method.lower() == 'fast': + fast_bootstrap = True + first_out = {} + n_comp_dict = {} + else: + fast_bootstrap = False + + # Prepare tqdm iteration maessage + if verbose and self.n_bootstrap_itrs > 1: + enum_obj = tqdm(range(self.n_bootstrap_itrs), + total=self.n_bootstrap_itrs, + desc="Bootstrapping the metamodel", + ascii=True) + else: + enum_obj = range(self.n_bootstrap_itrs) + + # Loop over the bootstrap iterations + for b_i in enum_obj: + if b_i > 0: + b_indices = np.random.randint(self.n_samples, size=self.n_samples) + else: + b_indices = np.arange(len(X)) + + X_train_b = X[b_indices] + + if verbose and self.n_bootstrap_itrs == 1: + items = tqdm(y.items(), desc="Fitting regression") + else: + items = y.items() + + # For loop over the components/outputs + for key, Output in items: + + # Dimensionality reduction with PCA, if specified + if self.dim_red_method.lower() == 'pca': + + # Use the stored n_comp for fast bootsrtrapping + if fast_bootstrap and b_i > 0: + self.n_pca_components = n_comp_dict[key] + + # Start transformation + pca, target, n_comp = self.pca_transformation( + Output[b_indices], verbose=False + ) + self.pca[f'b_{b_i+1}'][key] = pca + # Store the number of components for fast bootsrtrapping + if fast_bootstrap and b_i == 0: + n_comp_dict[key] = n_comp + else: + target = Output[b_indices] + + # Parallel fit regression + if self.meta_model_type.lower() == 'gpe': + # Prepare the input matrix + scaler = MinMaxScaler() + X_S = scaler.fit_transform(X_train_b) + + self.x_scaler[f'b_{b_i+1}'][key] = scaler + if parallel: + out = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.gaussian_process_emulator)( + X_S, target[:, idx]) for idx in + range(target.shape[1])) + else: + results = map(self.gaussian_process_emulator, + [X_train_b]*target.shape[1], + [target[:, idx] for idx in + range(target.shape[1])] + ) + out = list(results) + + for idx in range(target.shape[1]): + self.gp_poly[f'b_{b_i+1}'][key][f"y_{idx+1}"] = out[idx] + + else: + self.univ_p_val = self.univ_p_val[b_indices] + if parallel and (not fast_bootstrap or b_i == 0): + out = Parallel(n_jobs=-1, backend='multiprocessing')( + delayed(self.adaptive_regression)(X_train_b, + target[:, idx], + idx) + for idx in range(target.shape[1])) + elif not parallel and (not fast_bootstrap or b_i == 0): + results = map(self.adaptive_regression, + [X_train_b]*target.shape[1], + [target[:, idx] for idx in + range(target.shape[1])], + range(target.shape[1])) + out = list(results) + + # Store the first out dictionary + if fast_bootstrap and b_i == 0: + first_out[key] = copy.deepcopy(out) + + if b_i > 0 and fast_bootstrap: + + # fast bootstrap + out = self.update_pce_coeffs( + X_train_b, target, first_out[key]) + + for i in range(target.shape[1]): + # Create a dict to pass the variables + self.deg_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['degree'] + self.q_norm_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['qnorm'] + self.coeffs_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['coeffs'] + self.basis_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['multi_indices'] + self.score_dict[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['LOOCVScore'] + self.clf_poly[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['clf_poly'] + #self.LCerror[f'b_{b_i+1}'][key][f"y_{i+1}"] = out[i]['LCerror'] + + if verbose: + print(f"\n>>>> Training the {self.meta_model_type} metamodel" + " sucessfully completed. <<<<<<\n") + + # ------------------------------------------------------------------------- + def update_pce_coeffs(self, X, y, out_dict = None): + """ + Updates the PCE coefficents using only the ordinary least square method + for the fast version of the bootstrapping. + + Parameters + ---------- + X : array of shape (n_samples, n_params) + Training set. + y : array of shape (n_samples, n_outs) + The (transformed) model responses. + out_dict : dict + The training output dictionary of the first iteration, i.e. + the surrogate model for the original experimental design. + + Returns + ------- + final_out_dict : dict + The updated training output dictionary. + + """ + # Make a copy + final_out_dict = copy.deepcopy(out_dict) + + # Loop over the points + for i in range(y.shape[1]): + + + # Extract nonzero basis indices + nnz_idx = np.nonzero(out_dict[i]['coeffs'])[0] + if len(nnz_idx) != 0: + basis_indices = out_dict[i]['multi_indices'] + + # Evaluate the multivariate polynomials on CollocationPoints + psi = self.create_psi(basis_indices, self.univ_p_val) + + # Calulate the cofficients of surrogate model + updated_out = self.regression( + psi, y[:, i], basis_indices, reg_method='OLS', + sparsity=False + ) + + # Update coeffs in out_dict + final_out_dict[i]['coeffs'][nnz_idx] = updated_out['coeffs'] + + return final_out_dict + + # ------------------------------------------------------------------------- + def add_InputSpace(self): + """ + Instanciates experimental design object. + + Returns + ------- + None. + + """ + self.InputSpace = InputSpace(self.input_obj, + meta_Model_type=self.meta_model_type) + + # ------------------------------------------------------------------------- + def univ_basis_vals(self, samples, n_max=None): + """ + Evaluates univariate regressors along input directions. + + Parameters + ---------- + samples : array of shape (n_samples, n_params) + Samples. + n_max : int, optional + Maximum polynomial degree. The default is `None`. + + Returns + ------- + univ_basis: array of shape (n_samples, n_params, n_max+1) + All univariate regressors up to n_max. + """ + # Extract information + poly_types = self.InputSpace.poly_types + if samples.ndim != 2: + samples = samples.reshape(1, len(samples)) + n_max = np.max(self.pce_deg) if n_max is None else n_max + + # Extract poly coeffs + if self.InputSpace.input_data_given or self.InputSpace.apce: + apolycoeffs = self.polycoeffs + else: + apolycoeffs = None + + # Evaluate univariate basis + univ_basis = eval_univ_basis(samples, n_max, poly_types, apolycoeffs) + + return univ_basis + + # ------------------------------------------------------------------------- + def create_psi(self, basis_indices, univ_p_val): + """ + This function assemble the design matrix Psi from the given basis index + set INDICES and the univariate polynomial evaluations univ_p_val. + + Parameters + ---------- + basis_indices : array of shape (n_terms, n_params) + Multi-indices of multivariate polynomials. + univ_p_val : array of (n_samples, n_params, n_max+1) + All univariate regressors up to `n_max`. + + Raises + ------ + ValueError + n_terms in arguments do not match. + + Returns + ------- + psi : array of shape (n_samples, n_terms) + Multivariate regressors. + + """ + # Check if BasisIndices is a sparse matrix + sparsity = sp.sparse.issparse(basis_indices) + if sparsity: + basis_indices = basis_indices.toarray() + + # Initialization and consistency checks + # number of input variables + n_params = univ_p_val.shape[1] + + # Size of the experimental design + n_samples = univ_p_val.shape[0] + + # number of basis terms + n_terms = basis_indices.shape[0] + + # check that the variables have consistent sizes + if n_params != basis_indices.shape[1]: + raise ValueError( + f"The shapes of basis_indices ({basis_indices.shape[1]}) and " + f"univ_p_val ({n_params}) don't match!!" + ) + + # Preallocate the Psi matrix for performance + psi = np.ones((n_samples, n_terms)) + # Assemble the Psi matrix + for m in range(basis_indices.shape[1]): + aa = np.where(basis_indices[:, m] > 0)[0] + try: + basisIdx = basis_indices[aa, m] + bb = univ_p_val[:, m, basisIdx].reshape(psi[:, aa].shape) + psi[:, aa] = np.multiply(psi[:, aa], bb) + except ValueError as err: + raise err + return psi + + # ------------------------------------------------------------------------- + def regression(self, X, y, basis_indices, reg_method=None, sparsity=True): + """ + Fit regression using the regression method provided. + + Parameters + ---------- + X : array of shape (n_samples, n_features) + Training vector, where n_samples is the number of samples and + n_features is the number of features. + y : array of shape (n_samples,) + Target values. + basis_indices : array of shape (n_terms, n_params) + Multi-indices of multivariate polynomials. + reg_method : str, optional + DESCRIPTION. The default is None. + + Returns + ------- + return_out_dict : Dict + Fitted estimator, spareMulti-Index, sparseX and coefficients. + + """ + if reg_method is None: + reg_method = self.pce_reg_method + + bias_term = self.dim_red_method.lower() != 'pca' + + compute_score = True if self.verbose else False + + # inverse of the observed variance of the data + if np.var(y) != 0: + Lambda = 1 / np.var(y) + else: + Lambda = 1e-6 + + # Bayes sparse adaptive aPCE + if reg_method.lower() == 'ols': + clf_poly = lm.LinearRegression(fit_intercept=False) + elif reg_method.lower() == 'brr': + clf_poly = lm.BayesianRidge(n_iter=1000, tol=1e-7, + fit_intercept=False, + #normalize=True, + compute_score=compute_score, + alpha_1=1e-04, alpha_2=1e-04, + lambda_1=Lambda, lambda_2=Lambda) + clf_poly.converged = True + + elif reg_method.lower() == 'ard': + if X.shape[0]<2: + raise ValueError('Regression with ARD can only be performed for more than 2 samples') + clf_poly = lm.ARDRegression(fit_intercept=False, + #normalize=True, + compute_score=compute_score, + n_iter=1000, tol=0.0001, + alpha_1=1e-3, alpha_2=1e-3, + lambda_1=Lambda, lambda_2=Lambda) + + elif reg_method.lower() == 'fastard': + clf_poly = RegressionFastARD(fit_intercept=False, + normalize=True, + compute_score=compute_score, + n_iter=300, tol=1e-10) + + elif reg_method.lower() == 'bcs': + if X.shape[0]<10: + raise ValueError('Regression with BCS can only be performed for more than 10 samples') + clf_poly = RegressionFastLaplace(fit_intercept=False, + bias_term=bias_term, + n_iter=1000, tol=1e-7) + + elif reg_method.lower() == 'lars': + if X.shape[0]<10: + raise ValueError('Regression with LARS can only be performed for more than 5 samples') + clf_poly = lm.LassoLarsCV(fit_intercept=False) + + elif reg_method.lower() == 'sgdr': + clf_poly = lm.SGDRegressor(fit_intercept=False, + max_iter=5000, tol=1e-7) + + elif reg_method.lower() == 'omp': + clf_poly = OrthogonalMatchingPursuit(fit_intercept=False) + + elif reg_method.lower() == 'vbl': + clf_poly = VBLinearRegression(fit_intercept=False) + + elif reg_method.lower() == 'ebl': + clf_poly = EBLinearRegression(optimizer='em') + + # Fit + clf_poly.fit(X, y) + + # Select the nonzero entries of coefficients + if sparsity: + nnz_idx = np.nonzero(clf_poly.coef_)[0] + else: + nnz_idx = np.arange(clf_poly.coef_.shape[0]) + + # This is for the case where all outputs are zero, thereby + # all coefficients are zero + if (y == 0).all(): + nnz_idx = np.insert(np.nonzero(clf_poly.coef_)[0], 0, 0) + + sparse_basis_indices = basis_indices[nnz_idx] + sparse_X = X[:, nnz_idx] + coeffs = clf_poly.coef_[nnz_idx] + clf_poly.coef_ = coeffs + + # Create a dict to pass the outputs + return_out_dict = dict() + return_out_dict['clf_poly'] = clf_poly + return_out_dict['spareMulti-Index'] = sparse_basis_indices + return_out_dict['sparePsi'] = sparse_X + return_out_dict['coeffs'] = coeffs + return return_out_dict + + # -------------------------------------------------------------------------------------------------------- + def adaptive_regression(self, ED_X, ED_Y, varIdx, verbose=False): + """ + Adaptively fits the PCE model by comparing the scores of different + degrees and q-norm. + + Parameters + ---------- + ED_X : array of shape (n_samples, n_params) + Experimental design. + ED_Y : array of shape (n_samples,) + Target values, i.e. simulation results for the Experimental design. + varIdx : int + Index of the output. + verbose : bool, optional + Print out summary. The default is False. + + Returns + ------- + returnVars : Dict + Fitted estimator, best degree, best q-norm, LOOCVScore and + coefficients. + + """ + + n_samples, n_params = ED_X.shape + # Initialization + qAllCoeffs, AllCoeffs = {}, {} + qAllIndices_Sparse, AllIndices_Sparse = {}, {} + qAllclf_poly, Allclf_poly = {}, {} + qAllnTerms, AllnTerms = {}, {} + qAllLCerror, AllLCerror = {}, {} + + # Extract degree array and qnorm array + deg_array = np.array([*self.allBasisIndices], dtype=int) + qnorm = [*self.allBasisIndices[str(int(deg_array[0]))]] + + # Some options for EarlyStop + errorIncreases = False + # Stop degree, if LOO error does not decrease n_checks_degree times + n_checks_degree = 3 + # Stop qNorm, if criterion isn't fulfilled n_checks_qNorm times + n_checks_qNorm = 2 + nqnorms = len(qnorm) + qNormEarlyStop = True + if nqnorms < n_checks_qNorm+1: + qNormEarlyStop = False + + # ===================================================================== + # basis adaptive polynomial chaos: repeat the calculation by increasing + # polynomial degree until the highest accuracy is reached + # ===================================================================== + # For each degree check all q-norms and choose the best one + scores = -np.inf * np.ones(deg_array.shape[0]) + qNormScores = -np.inf * np.ones(nqnorms) + + for degIdx, deg in enumerate(deg_array): + + for qidx, q in enumerate(qnorm): + + # Extract the polynomial basis indices from the pool of + # allBasisIndices + BasisIndices = self.allBasisIndices[str(deg)][str(q)] + + # Assemble the Psi matrix + Psi = self.create_psi(BasisIndices, self.univ_p_val) + + # Calulate the cofficients of the meta model + outs = self.regression(Psi, ED_Y, BasisIndices) + + # Calculate and save the score of LOOCV + score, LCerror = self.corr_loocv_error(outs['clf_poly'], + outs['sparePsi'], + outs['coeffs'], + ED_Y) + + # Check the convergence of noise for FastARD + if self.pce_reg_method == 'FastARD' and \ + outs['clf_poly'].alpha_ < np.finfo(np.float32).eps: + score = -np.inf + + qNormScores[qidx] = score + qAllCoeffs[str(qidx+1)] = outs['coeffs'] + qAllIndices_Sparse[str(qidx+1)] = outs['spareMulti-Index'] + qAllclf_poly[str(qidx+1)] = outs['clf_poly'] + qAllnTerms[str(qidx+1)] = BasisIndices.shape[0] + qAllLCerror[str(qidx+1)] = LCerror + + # EarlyStop check + # if there are at least n_checks_qNorm entries after the + # best one, we stop + if qNormEarlyStop and \ + sum(np.isfinite(qNormScores)) > n_checks_qNorm: + # If the error has increased the last two iterations, stop! + qNormScores_nonInf = qNormScores[np.isfinite(qNormScores)] + deltas = np.sign(np.diff(qNormScores_nonInf)) + if sum(deltas[-n_checks_qNorm+1:]) == 2: + # stop the q-norm loop here + break + if np.var(ED_Y) == 0: + break + + # Store the score in the scores list + best_q = np.nanargmax(qNormScores) + scores[degIdx] = qNormScores[best_q] + + AllCoeffs[str(degIdx+1)] = qAllCoeffs[str(best_q+1)] + AllIndices_Sparse[str(degIdx+1)] = qAllIndices_Sparse[str(best_q+1)] + Allclf_poly[str(degIdx+1)] = qAllclf_poly[str(best_q+1)] + AllnTerms[str(degIdx+1)] = qAllnTerms[str(best_q+1)] + AllLCerror[str(degIdx+1)] = qAllLCerror[str(best_q+1)] + + # Check the direction of the error (on average): + # if it increases consistently stop the iterations + if len(scores[scores != -np.inf]) > n_checks_degree: + scores_nonInf = scores[scores != -np.inf] + ss = np.sign(scores_nonInf - np.max(scores_nonInf)) + # ss<0 error decreasing + errorIncreases = np.sum(np.sum(ss[-2:])) <= -1*n_checks_degree + + if errorIncreases: + break + + # Check only one degree, if target matrix has zero variance + if np.var(ED_Y) == 0: + break + + # ------------------ Summary of results ------------------ + # Select the one with the best score and save the necessary outputs + best_deg = np.nanargmax(scores)+1 + coeffs = AllCoeffs[str(best_deg)] + basis_indices = AllIndices_Sparse[str(best_deg)] + clf_poly = Allclf_poly[str(best_deg)] + LOOCVScore = np.nanmax(scores) + P = AllnTerms[str(best_deg)] + LCerror = AllLCerror[str(best_deg)] + degree = deg_array[np.nanargmax(scores)] + qnorm = float(qnorm[best_q]) + + # ------------------ Print out Summary of results ------------------ + if self.verbose: + # Create PSI_Sparse by removing redundent terms + nnz_idx = np.nonzero(coeffs)[0] + BasisIndices_Sparse = basis_indices[nnz_idx] + + print(f'Output variable {varIdx+1}:') + print('The estimation of PCE coefficients converged at polynomial ' + f'degree {deg_array[best_deg-1]} with ' + f'{len(BasisIndices_Sparse)} terms (Sparsity index = ' + f'{round(len(BasisIndices_Sparse)/P, 3)}).') + + print(f'Final ModLOO error estimate: {1-max(scores):.3e}') + print('\n'+'-'*50) + + if verbose: + print('='*50) + print(' '*10 + ' Summary of results ') + print('='*50) + + print("Scores:\n", scores) + print("Degree of best score:", self.deg_array[best_deg-1]) + print("No. of terms:", len(basis_indices)) + print("Sparsity index:", round(len(basis_indices)/P, 3)) + print("Best Indices:\n", basis_indices) + + if self.pce_reg_method in ['BRR', 'ARD']: + fig, ax = plt.subplots(figsize=(12, 10)) + plt.title("Marginal log-likelihood") + plt.plot(clf_poly.scores_, color='navy', linewidth=2) + plt.ylabel("Score") + plt.xlabel("Iterations") + if self.pce_reg_method.lower() == 'bbr': + text = f"$\\alpha={clf_poly.alpha_:.1f}$\n" + f"$\\lambda={clf_poly.lambda_:.3f}$\n" + f"$L={clf_poly.scores_[-1]:.1f}$" + else: + text = f"$\\alpha={clf_poly.alpha_:.1f}$\n$" + f"\\L={clf_poly.scores_[-1]:.1f}$" + + plt.text(0.75, 0.5, text, fontsize=18, transform=ax.transAxes) + plt.show() + print('='*80) + + # Create a dict to pass the outputs + returnVars = dict() + returnVars['clf_poly'] = clf_poly + returnVars['degree'] = degree + returnVars['qnorm'] = qnorm + returnVars['coeffs'] = coeffs + returnVars['multi_indices'] = basis_indices + returnVars['LOOCVScore'] = LOOCVScore + returnVars['LCerror'] = LCerror + + return returnVars + + # ------------------------------------------------------------------------- + def corr_loocv_error(self, clf, psi, coeffs, y): + """ + Calculates the corrected LOO error for regression on regressor + matrix `psi` that generated the coefficients based on [1] and [2]. + + [1] Blatman, G., 2009. Adaptive sparse polynomial chaos expansions for + uncertainty propagation and sensitivity analysis (Doctoral + dissertation, Clermont-Ferrand 2). + + [2] Blatman, G. and Sudret, B., 2011. Adaptive sparse polynomial chaos + expansion based on least angle regression. Journal of computational + Physics, 230(6), pp.2345-2367. + + Parameters + ---------- + clf : object + Fitted estimator. + psi : array of shape (n_samples, n_features) + The multivariate orthogonal polynomials (regressor). + coeffs : array-like of shape (n_features,) + Estimated cofficients. + y : array of shape (n_samples,) + Target values. + + Returns + ------- + R_2 : float + LOOCV Validation score (1-LOOCV erro). + residual : array of shape (n_samples,) + Residual values (y - predicted targets). + + """ + psi = np.array(psi, dtype=float) + + # Create PSI_Sparse by removing redundent terms + nnz_idx = np.nonzero(coeffs)[0] + if len(nnz_idx) == 0: + nnz_idx = [0] + psi_sparse = psi[:, nnz_idx] + + # NrCoeffs of aPCEs + P = len(nnz_idx) + # NrEvaluation (Size of experimental design) + N = psi.shape[0] + + # Build the projection matrix + PsiTPsi = np.dot(psi_sparse.T, psi_sparse) + + if np.linalg.cond(PsiTPsi) > 1e-12: #and \ + # np.linalg.cond(PsiTPsi) < 1/sys.float_info.epsilon: + # faster + try: + M = sp.linalg.solve(PsiTPsi, + sp.sparse.eye(PsiTPsi.shape[0]).toarray()) + except: + raise AttributeError('There are too few samples for the corrected loo-cv error. Fit surrogate on at least as many samples as parameters to use this') + else: + # stabler + M = np.linalg.pinv(PsiTPsi) + + # h factor (the full matrix is not calculated explicitly, + # only the trace is, to save memory) + PsiM = np.dot(psi_sparse, M) + + h = np.sum(np.multiply(PsiM, psi_sparse), axis=1, dtype=np.longdouble)#float128) + + # ------ Calculate Error Loocv for each measurement point ---- + # Residuals + try: + residual = clf.predict(psi) - y + except: + residual = np.dot(psi, coeffs) - y + + # Variance + var_y = np.var(y) + + if var_y == 0: + norm_emp_error = 0 + loo_error = 0 + LCerror = np.zeros((y.shape)) + return 1-loo_error, LCerror + else: + norm_emp_error = np.mean(residual**2)/var_y + + # LCerror = np.divide(residual, (1-h)) + LCerror = residual / (1-h) + loo_error = np.mean(np.square(LCerror)) / var_y + # if there are NaNs, just return an infinite LOO error (this + # happens, e.g., when a strongly underdetermined problem is solved) + if np.isnan(loo_error): + loo_error = np.inf + + # Corrected Error for over-determined system + tr_M = np.trace(M) + if tr_M < 0 or abs(tr_M) > 1e6: + tr_M = np.trace(np.linalg.pinv(np.dot(psi.T, psi))) + + # Over-determined system of Equation + if N > P: + T_factor = N/(N-P) * (1 + tr_M) + + # Under-determined system of Equation + else: + T_factor = np.inf + + corrected_loo_error = loo_error * T_factor + + R_2 = 1 - corrected_loo_error + + return R_2, LCerror + + # ------------------------------------------------------------------------- + def pca_transformation(self, target, verbose=False): + """ + Transforms the targets (outputs) via Principal Component Analysis + + Parameters + ---------- + target : array of shape (n_samples,) + Target values. + + Returns + ------- + pca : obj + Fitted sklearnPCA object. + OutputMatrix : array of shape (n_samples,) + Transformed target values. + n_pca_components : int + Number of selected principal components. + + """ + # Transform via Principal Component Analysis + if hasattr(self, 'var_pca_threshold'): + var_pca_threshold = self.var_pca_threshold + else: + var_pca_threshold = 100.0 + n_samples, n_features = target.shape + + if hasattr(self, 'n_pca_components'): + n_pca_components = self.n_pca_components + else: + # Instantiate and fit sklearnPCA object + covar_matrix = sklearnPCA(n_components=None) + covar_matrix.fit(target) + var = np.cumsum(np.round(covar_matrix.explained_variance_ratio_, + decimals=5)*100) + # Find the number of components to explain self.varPCAThreshold of + # variance + try: + n_components = np.where(var >= var_pca_threshold)[0][0] + 1 + except IndexError: + n_components = min(n_samples, n_features) + + n_pca_components = min(n_samples, n_features, n_components) + + # Print out a report + if verbose: + print() + print('-' * 50) + print(f"PCA transformation is performed with {n_pca_components}" + " components.") + print('-' * 50) + print() + + # Fit and transform with the selected number of components + pca = sklearnPCA(n_components=n_pca_components, svd_solver='arpack') + scaled_target = pca.fit_transform(target) + + return pca, scaled_target, n_pca_components + + # ------------------------------------------------------------------------- + def gaussian_process_emulator(self, X, y, nug_term=None, autoSelect=False, + varIdx=None): + """ + Fits a Gaussian Process Emulator to the target given the training + points. + + Parameters + ---------- + X : array of shape (n_samples, n_params) + Training points. + y : array of shape (n_samples,) + Target values. + nug_term : float, optional + Nugget term. The default is None, i.e. variance of y. + autoSelect : bool, optional + Loop over some kernels and select the best. The default is False. + varIdx : int, optional + The index number. The default is None. + + Returns + ------- + gp : object + Fitted estimator. + + """ + + nug_term = nug_term if nug_term else np.var(y) + + Kernels = [nug_term * kernels.RBF(length_scale=1.0, + length_scale_bounds=(1e-25, 1e15)), + nug_term * kernels.RationalQuadratic(length_scale=0.2, + alpha=1.0), + nug_term * kernels.Matern(length_scale=1.0, + length_scale_bounds=(1e-15, 1e5), + nu=1.5)] + + # Automatic selection of the kernel + if autoSelect: + gp = {} + BME = [] + for i, kernel in enumerate(Kernels): + gp[i] = GaussianProcessRegressor(kernel=kernel, + n_restarts_optimizer=3, + normalize_y=False) + + # Fit to data using Maximum Likelihood Estimation + gp[i].fit(X, y) + + # Store the MLE as BME score + BME.append(gp[i].log_marginal_likelihood()) + + gp = gp[np.argmax(BME)] + + else: + gp = GaussianProcessRegressor(kernel=Kernels[0], + n_restarts_optimizer=3, + normalize_y=False) + gp.fit(X, y) + + # Compute score + if varIdx is not None: + Score = gp.score(X, y) + print('-'*50) + print(f'Output variable {varIdx}:') + print('The estimation of GPE coefficients converged,') + print(f'with the R^2 score: {Score:.3f}') + print('-'*50) + + return gp + + # ------------------------------------------------------------------------- + def eval_metamodel(self, samples): + """ + Evaluates meta-model at the requested samples. One can also generate + nsamples. + + Parameters + ---------- + samples : array of shape (n_samples, n_params), optional + Samples to evaluate meta-model at. The default is None. + nsamples : int, optional + Number of samples to generate, if no `samples` is provided. The + default is None. + sampling_method : str, optional + Type of sampling, if no `samples` is provided. The default is + 'random'. + return_samples : bool, optional + Retun samples, if no `samples` is provided. The default is False. + + Returns + ------- + mean_pred : dict + Mean of the predictions. + std_pred : dict + Standard deviatioon of the predictions. + """ + # Transform into np array - can also be given as list + samples = np.array(samples) + + # Transform samples to the independent space + samples = self.InputSpace.transform( + samples, + method='user' + ) + # Compute univariate bases for the given samples + if self.meta_model_type.lower() != 'gpe': + univ_p_val = self.univ_basis_vals( + samples, + n_max=np.max(self.pce_deg) + ) + + mean_pred_b = {} + std_pred_b = {} + # Loop over bootstrap iterations + for b_i in range(self.n_bootstrap_itrs): + + # Extract model dictionary + if self.meta_model_type.lower() == 'gpe': + model_dict = self.gp_poly[f'b_{b_i+1}'] + else: + model_dict = self.coeffs_dict[f'b_{b_i+1}'] + + # Loop over outputs + mean_pred = {} + std_pred = {} + for output, values in model_dict.items(): + + mean = np.empty((len(samples), len(values))) + std = np.empty((len(samples), len(values))) + idx = 0 + for in_key, InIdxValues in values.items(): + + # Prediction with GPE + if self.meta_model_type.lower() == 'gpe': + X_T = self.x_scaler[f'b_{b_i+1}'][output].transform(samples) + gp = self.gp_poly[f'b_{b_i+1}'][output][in_key] + y_mean, y_std = gp.predict(X_T, return_std=True) + + else: + # Prediction with PCE + # Assemble Psi matrix + basis = self.basis_dict[f'b_{b_i+1}'][output][in_key] + psi = self.create_psi(basis, univ_p_val) + + # Prediction + if self.bootstrap_method != 'fast' or b_i == 0: + # with error bar, i.e. use clf_poly + clf_poly = self.clf_poly[f'b_{b_i+1}'][output][in_key] + try: + y_mean, y_std = clf_poly.predict( + psi, return_std=True + ) + except TypeError: + y_mean = clf_poly.predict(psi) + y_std = np.zeros_like(y_mean) + else: + # without error bar + coeffs = self.coeffs_dict[f'b_{b_i+1}'][output][in_key] + y_mean = np.dot(psi, coeffs) + y_std = np.zeros_like(y_mean) + + mean[:, idx] = y_mean + std[:, idx] = y_std + idx += 1 + + # Save predictions for each output + if self.dim_red_method.lower() == 'pca': + PCA = self.pca[f'b_{b_i+1}'][output] + mean_pred[output] = PCA.inverse_transform(mean) + std_pred[output] = np.zeros(mean.shape) + else: + mean_pred[output] = mean + std_pred[output] = std + + # Save predictions for each bootstrap iteration + mean_pred_b[b_i] = mean_pred + std_pred_b[b_i] = std_pred + + # Change the order of nesting + mean_pred_all = {} + for i in sorted(mean_pred_b): + for k, v in mean_pred_b[i].items(): + if k not in mean_pred_all: + mean_pred_all[k] = [None] * len(mean_pred_b) + mean_pred_all[k][i] = v + + # Compute the moments of predictions over the predictions + for output in self.out_names: + # Only use bootstraps with finite values + finite_rows = np.isfinite( + mean_pred_all[output]).all(axis=2).all(axis=1) + outs = np.asarray(mean_pred_all[output])[finite_rows] + # Compute mean + mean_pred[output] = np.mean(outs, axis=0) + # Compute standard deviation + if self.n_bootstrap_itrs > 1: + std_pred[output] = np.std(outs, axis=0) + else: + std_pred[output] = std_pred_b[b_i][output] + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + def create_model_error(self, X, y, Model, name='Calib'): + """ + Fits a GPE-based model error. + + Parameters + ---------- + X : array of shape (n_outputs, n_inputs) + Input array. It can contain any forcing inputs or coordinates of + extracted data. + y : array of shape (n_outputs,) + The model response for the MAP parameter set. + name : str, optional + Calibration or validation. The default is `'Calib'`. + + Returns + ------- + self: object + Self object. + + """ + outputNames = self.out_names + self.errorRegMethod = 'GPE' + self.errorclf_poly = self.auto_vivification() + self.errorScale = self.auto_vivification() + + # Read data + # TODO: do this call outside the metamodel + MeasuredData = Model.read_observation(case=name) + + # Fitting GPR based bias model + for out in outputNames: + nan_idx = ~np.isnan(MeasuredData[out]) + # Select data + try: + data = MeasuredData[out].values[nan_idx] + except AttributeError: + data = MeasuredData[out][nan_idx] + + # Prepare the input matrix + scaler = MinMaxScaler() + delta = data # - y[out][0] + BiasInputs = np.hstack((X[out], y[out].reshape(-1, 1))) + X_S = scaler.fit_transform(BiasInputs) + gp = self.gaussian_process_emulator(X_S, delta) + + self.errorScale[out]["y_1"] = scaler + self.errorclf_poly[out]["y_1"] = gp + + return self + + # ------------------------------------------------------------------------- + def eval_model_error(self, X, y_pred): + """ + Evaluates the error model. + + Parameters + ---------- + X : array + Inputs. + y_pred : dict + Predictions. + + Returns + ------- + mean_pred : dict + Mean predition of the GPE-based error model. + std_pred : dict + standard deviation of the GPE-based error model. + + """ + mean_pred = {} + std_pred = {} + + for Outkey, ValuesDict in self.errorclf_poly.items(): + + pred_mean = np.zeros_like(y_pred[Outkey]) + pred_std = np.zeros_like(y_pred[Outkey]) + + for Inkey, InIdxValues in ValuesDict.items(): + + gp = self.errorclf_poly[Outkey][Inkey] + scaler = self.errorScale[Outkey][Inkey] + + # Transform Samples using scaler + for j, pred in enumerate(y_pred[Outkey]): + BiasInputs = np.hstack((X[Outkey], pred.reshape(-1, 1))) + Samples_S = scaler.transform(BiasInputs) + y_hat, y_std = gp.predict(Samples_S, return_std=True) + pred_mean[j] = y_hat + pred_std[j] = y_std + # pred_mean[j] += pred + + mean_pred[Outkey] = pred_mean + std_pred[Outkey] = pred_std + + return mean_pred, std_pred + + # ------------------------------------------------------------------------- + class auto_vivification(dict): + """ + Implementation of perl's AutoVivification feature. + + Source: https://stackoverflow.com/a/651879/18082457 + """ + + def __getitem__(self, item): + try: + return dict.__getitem__(self, item) + except KeyError: + value = self[item] = type(self)() + return value + + # ------------------------------------------------------------------------- + def copy_meta_model_opts(self): + """ + This method is a convinient function to copy the metamodel options. + + Returns + ------- + new_MetaModelOpts : object + The copied object. + + """ + # TODO: what properties should be moved to the new object? + new_MetaModelOpts = copy.deepcopy(self) + new_MetaModelOpts.input_obj = self.input_obj#InputObj + new_MetaModelOpts.InputSpace = self.InputSpace + #new_MetaModelOpts.InputSpace.meta_Model = 'aPCE' + #new_MetaModelOpts.InputSpace.InputObj = self.input_obj + #new_MetaModelOpts.InputSpace.ndim = len(self.input_obj.Marginals) + new_MetaModelOpts.n_params = len(self.input_obj.Marginals) + #new_MetaModelOpts.InputSpace.hdf5_file = None + + return new_MetaModelOpts + + # ------------------------------------------------------------------------- + def __select_degree(self, ndim, n_samples): + """ + Selects degree based on the number of samples and parameters in the + sequential design. + + Parameters + ---------- + ndim : int + Dimension of the parameter space. + n_samples : int + Number of samples. + + Returns + ------- + deg_array: array + Array containing the arrays. + + """ + # Define the deg_array + max_deg = np.max(self.pce_deg) + min_Deg = np.min(self.pce_deg) + + # TODO: remove the options for sequential? + #nitr = n_samples - self.InputSpace.n_init_samples + + # Check q-norm + if not np.isscalar(self.pce_q_norm): + self.pce_q_norm = np.array(self.pce_q_norm) + else: + self.pce_q_norm = np.array([self.pce_q_norm]) + + def M_uptoMax(maxDeg): + n_combo = np.zeros(maxDeg) + for i, d in enumerate(range(1, maxDeg+1)): + n_combo[i] = math.factorial(ndim+d) + n_combo[i] /= math.factorial(ndim) * math.factorial(d) + return n_combo + + deg_new = max_deg + #d = nitr if nitr != 0 and self.n_params > 5 else 1 + # d = 1 + # min_index = np.argmin(abs(M_uptoMax(max_deg)-ndim*n_samples*d)) + # deg_new = range(1, max_deg+1)[min_index] + + if deg_new > min_Deg and self.pce_reg_method.lower() != 'fastard': + deg_array = np.arange(min_Deg, deg_new+1) + else: + deg_array = np.array([deg_new]) + + return deg_array + + def generate_polynomials(self, max_deg=None): + # Check for InputSpace + if not hasattr(self, 'InputSpace'): + raise AttributeError('Generate or add InputSpace before generating polynomials') + + ndim = self.InputSpace.ndim + # Create orthogonal polynomial coefficients if necessary + if (self.meta_model_type.lower()!='gpe') and max_deg is not None:# and self.input_obj.poly_coeffs_flag: + self.polycoeffs = {} + for parIdx in tqdm(range(ndim), ascii=True, + desc="Computing orth. polynomial coeffs"): + poly_coeffs = apoly_construction( + self.InputSpace.raw_data[parIdx], + max_deg + ) + self.polycoeffs[f'p_{parIdx+1}'] = poly_coeffs + else: + raise AttributeError('MetaModel cannot generate polynomials in the given scenario!') + + # ------------------------------------------------------------------------- + def _compute_pce_moments(self): + """ + Computes the first two moments using the PCE-based meta-model. + + Returns + ------- + pce_means: dict + The first moment (mean) of the surrogate. + pce_stds: dict + The second moment (standard deviation) of the surrogate. + + """ + + # Check if its truly a pce-surrogate + if self.meta_model_type.lower() == 'gpe': + raise AttributeError('Moments can only be computed for pce-type surrogates') + + outputs = self.out_names + pce_means_b = {} + pce_stds_b = {} + + # Loop over bootstrap iterations + for b_i in range(self.n_bootstrap_itrs): + # Loop over the metamodels + coeffs_dicts = self.coeffs_dict[f'b_{b_i+1}'].items() + means = {} + stds = {} + for output, coef_dict in coeffs_dicts: + + pce_mean = np.zeros((len(coef_dict))) + pce_var = np.zeros((len(coef_dict))) + + for index, values in coef_dict.items(): + idx = int(index.split('_')[1]) - 1 + coeffs = self.coeffs_dict[f'b_{b_i+1}'][output][index] + + # Mean = c_0 + if coeffs[0] != 0: + pce_mean[idx] = coeffs[0] + else: + clf_poly = self.clf_poly[f'b_{b_i+1}'][output] + pce_mean[idx] = clf_poly[index].intercept_ + # Var = sum(coeffs[1:]**2) + pce_var[idx] = np.sum(np.square(coeffs[1:])) + + # Save predictions for each output + if self.dim_red_method.lower() == 'pca': + PCA = self.pca[f'b_{b_i+1}'][output] + means[output] = PCA.inverse_transform(pce_mean) + stds[output] = PCA.inverse_transform(np.sqrt(pce_var)) + else: + means[output] = pce_mean + stds[output] = np.sqrt(pce_var) + + # Save predictions for each bootstrap iteration + pce_means_b[b_i] = means + pce_stds_b[b_i] = stds + + # Change the order of nesting + mean_all = {} + for i in sorted(pce_means_b): + for k, v in pce_means_b[i].items(): + if k not in mean_all: + mean_all[k] = [None] * len(pce_means_b) + mean_all[k][i] = v + std_all = {} + for i in sorted(pce_stds_b): + for k, v in pce_stds_b[i].items(): + if k not in std_all: + std_all[k] = [None] * len(pce_stds_b) + std_all[k][i] = v + + # Back transformation if PCA is selected. + pce_means, pce_stds = {}, {} + for output in outputs: + pce_means[output] = np.mean(mean_all[output], axis=0) + pce_stds[output] = np.mean(std_all[output], axis=0) + + return pce_means, pce_stds diff --git a/examples/umbridge_tsunamitutorial/test_umbridge_testmodel.py b/examples/umbridge_tsunamitutorial/test_umbridge_testmodel.py new file mode 100644 index 000000000..95ec964fa --- /dev/null +++ b/examples/umbridge_tsunamitutorial/test_umbridge_testmodel.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Dec 11 14:03:23 2023 + +Example and test for using umbridge with bayesvalidrox. +Example model is the tsunami model by +docker run -it -p 4242:4242 -v ~/tsunami_output:/output linusseelinger/model-exahype-tsunami + +@author: rkohlhaas +""" + +import joblib +import numpy as np +import umbridge +import bayesvalidrox as bv + +from bayesvalidrox.pylink.pylink import PyLinkForwardModel +from bayesvalidrox.surrogate_models.inputs import Input +from bayesvalidrox.surrogate_models.exp_designs import ExpDesigns +from bayesvalidrox.surrogate_models.surrogate_models import MetaModel +from bayesvalidrox.post_processing.post_processing import PostProcessing +from bayesvalidrox.surrogate_models.engine import Engine + + +if __name__ == '__main__': + + # This model has 2 inputs and four outputs + n_prior_sample = 1000 + priors = bv.Input() + priors.add_marginals() + priors.Marginals[0].name = 'x' + priors.Marginals[0].input_data = np.random.uniform(50,150,n_prior_sample) + + # Define the model - level 0 + model = PyLinkForwardModel() + #model.link_type = 'Function' + #model.py_file = 'testmodel' + #model.name = 'testmodel' + model.link_type = 'umbridge' + model.host = 'http://testmodel.linusseelinger.de' + model.modelparams = {} + model.name = 'testmodel' + model.Output.names = ['y'] + model.output_type = 'single-valued' + + # Create the surrogate + surrogate_opts = MetaModel(priors) + + # Select your metamodel method + surrogate_opts.meta_model_type = 'aPCE' + surrogate_opts.pce_reg_method = 'FastARD' + surrogate_opts.pce_deg = np.arange(1, 5) + surrogate_opts.pce_q_norm = 0.4 + + # Select your metamodel method + ExpDesign = ExpDesigns(priors) + ExpDesign.n_init_samples = 50 + ExpDesign.sampling_method = 'latin-hypercube' + + engine = Engine(surrogate_opts, model, ExpDesign) + engine.start_engine() + engine.train_normal(parallel = False) + print('Surrogate completed') + print('') + + # Save surrogate + with open('testmodel.pk1', 'wb') as output: + joblib.dump(engine.MetaModel, output, 2) + + # Post processing + L2_PostPCE = PostProcessing(engine) + L2_PostPCE.plot_moments(plot_type='line') + # Plot to check validation visually. + L2_PostPCE.valid_metamodel(n_samples=1) + # Compute and print RMSE error + L2_PostPCE.check_accuracy(n_samples=300) + total_sobol = L2_PostPCE.sobol_indices() diff --git a/examples/umbridge_tsunamitutorial/testmodel.pk1 b/examples/umbridge_tsunamitutorial/testmodel.pk1 new file mode 100644 index 0000000000000000000000000000000000000000..700c643fc23e631a23cb23dd0972954904268377 GIT binary patch literal 12063 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 ULH8_6w`rJ;EflFKay{w)03D*=fdBvi literal 0 HcmV?d00001 diff --git a/examples/umbridge_tsunamitutorial/testmodel.py b/examples/umbridge_tsunamitutorial/testmodel.py new file mode 100644 index 000000000..b213d2a3a --- /dev/null +++ b/examples/umbridge_tsunamitutorial/testmodel.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +Runs the umbridge command for the tsunami model + +@author: Rebecca Kohlhaas +""" +import umbridge +import numpy as np + +def testmodel(params): + # Get the model + model = umbridge.HTTPModel('http://testmodel.linusseelinger.de', 'forward') + # Run the model + params = np.ndarray.tolist(params) + out = np.array(model(params)) + #print(out) + return {'y':out[:,0],'x_values':[0]} + + + \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 78940cfb5..af5fbbda3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,19 +20,19 @@ package_dir = packages = find: python_requires = >=3.8 install_requires = - numpy==1.22.1 + numpy==1.23.3 pandas==1.2.4 - joblib==1.0.1 + joblib==1.2.0 matplotlib==3.4.2 seaborn==0.11.1 - scipy==1.7.3 - scikit-learn==0.24.2 + scipy==1.11.1 + scikit-learn==1.3.0 tqdm==4.61.1 chaospy==4.3.3 emcee==3.0.2 corner==2.2.1 - h5py==3.2.1 - statsmodels==0.13.2 + h5py==3.8.0 + statsmodels==0.14 [options.packages.find] where = src diff --git a/src/bayesvalidrox.egg-info/PKG-INFO b/src/bayesvalidrox.egg-info/PKG-INFO new file mode 100644 index 000000000..0d570efc3 --- /dev/null +++ b/src/bayesvalidrox.egg-info/PKG-INFO @@ -0,0 +1,86 @@ +Metadata-Version: 2.1 +Name: bayesvalidrox +Version: 0.0.5 +Summary: An open-source, object-oriented Python package for surrogate-assisted Bayesain Validation of computational models. +Home-page: https://git.iws.uni-stuttgart.de/inversemodeling/bayesian-validation +Author: Farid Mohammadi +Author-email: farid.mohammadi@iws.uni-stuttgart.de +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENCE.md +Requires-Dist: numpy==1.23.3 +Requires-Dist: pandas==1.2.4 +Requires-Dist: joblib==1.2.0 +Requires-Dist: matplotlib==3.4.2 +Requires-Dist: seaborn==0.11.1 +Requires-Dist: scipy==1.11.1 +Requires-Dist: scikit-learn==1.3.0 +Requires-Dist: tqdm==4.61.1 +Requires-Dist: chaospy==4.3.3 +Requires-Dist: emcee==3.0.2 +Requires-Dist: corner==2.2.1 +Requires-Dist: h5py==3.8.0 +Requires-Dist: statsmodels==0.14 + +# BayesValidRox + +<div align="center"> + <img src="https://git.iws.uni-stuttgart.de/inversemodeling/bayesian-validation/-/raw/master/docs/logo/bayesvalidrox-logo.png" alt="bayesvalidrox logo"/> +</div> + +An open-source, object-oriented Python package for surrogate-assisted Bayesain Validation of computational models. +This framework provides an automated workflow for surrogate-based sensitivity analysis, Bayesian calibration, and validation of computational models with a modular structure. + +## Authors +- [@farid](https://git.iws.uni-stuttgart.de/farid) + +## Installation +The best practive is to create a virtual environment and install the package inside it. + +To create and activate the virtual environment run the following command in the terminal: +```bash + python3 -m venv bayes_env + cd bayes_env + source bin/activate +``` +You can replace `bayes_env` with your preferred name. For more information on virtual environments see [this link](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/). + +Now, you can install the latest release of the package on PyPI inside the venv with: +```bash + pip install bayesvalidrox +``` +and installing the version on the master branch can be done by cloning this repo and installing: +```bash + git clone https://git.iws.uni-stuttgart.de/inversemodeling/bayesvalidrox.git + cd bayesvalidrox + pip install . +``` + +## Features +* Surrogate modeling with Polynomial Chaos Expansion +* Global sensitivity analysis using Sobol Indices +* Bayesian calibration with MCMC using `emcee` package +* Bayesian validation with model weights for multi-model setting + +## Requirements +* numpy==1.22.1 +* pandas==1.2.4 +* joblib==1.0.1 +* matplotlib==3.4.2 +* seaborn==0.11.1 +* scikit-learn==0.24.2 +* tqdm==4.61.1 +* chaospy==4.3.3 +* emcee==3.0.2 +* corner==2.2.1 +* h5py==3.2.1 +* statsmodels==0.13.2 + +## TexLive for Plotting with matplotlib +Here you need super user rights +```bash +sudo apt-get install dvipng texlive-latex-extra texlive-fonts-recommended cm-super +``` diff --git a/src/bayesvalidrox.egg-info/SOURCES.txt b/src/bayesvalidrox.egg-info/SOURCES.txt new file mode 100644 index 000000000..be2f4cde5 --- /dev/null +++ b/src/bayesvalidrox.egg-info/SOURCES.txt @@ -0,0 +1,44 @@ +LICENCE.md +README.md +pyproject.toml +setup.cfg +src/bayesvalidrox/__init__.py +src/bayesvalidrox/bayesvalidrox.mplstyle +src/bayesvalidrox.egg-info/PKG-INFO +src/bayesvalidrox.egg-info/SOURCES.txt +src/bayesvalidrox.egg-info/dependency_links.txt +src/bayesvalidrox.egg-info/requires.txt +src/bayesvalidrox.egg-info/top_level.txt +src/bayesvalidrox/bayes_inference/__init__.py +src/bayesvalidrox/bayes_inference/bayes_inference.py +src/bayesvalidrox/bayes_inference/bayes_model_comparison.py +src/bayesvalidrox/bayes_inference/discrepancy.py +src/bayesvalidrox/bayes_inference/mcmc.py +src/bayesvalidrox/post_processing/__init__.py +src/bayesvalidrox/post_processing/post_processing.py +src/bayesvalidrox/pylink/__init__.py +src/bayesvalidrox/pylink/pylink.py +src/bayesvalidrox/surrogate_models/__init__.py +src/bayesvalidrox/surrogate_models/adaptPlot.py +src/bayesvalidrox/surrogate_models/apoly_construction.py +src/bayesvalidrox/surrogate_models/bayes_linear.py +src/bayesvalidrox/surrogate_models/engine.py +src/bayesvalidrox/surrogate_models/eval_rec_rule.py +src/bayesvalidrox/surrogate_models/exp_designs.py +src/bayesvalidrox/surrogate_models/exploration.py +src/bayesvalidrox/surrogate_models/glexindex.py +src/bayesvalidrox/surrogate_models/input_space.py +src/bayesvalidrox/surrogate_models/inputs.py +src/bayesvalidrox/surrogate_models/orthogonal_matching_pursuit.py +src/bayesvalidrox/surrogate_models/reg_fast_ard.py +src/bayesvalidrox/surrogate_models/reg_fast_laplace.py +src/bayesvalidrox/surrogate_models/sequential_design.py +src/bayesvalidrox/surrogate_models/surrogate_models.py +tests/test_Discrepancy.py +tests/test_ExpDesign.py +tests/test_Input.py +tests/test_InputSpace.py +tests/test_MetaModel.py +tests/test_engine.py +tests/test_polyconst.py +tests/test_pylink.py \ No newline at end of file diff --git a/src/bayesvalidrox.egg-info/dependency_links.txt b/src/bayesvalidrox.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/bayesvalidrox.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/bayesvalidrox.egg-info/requires.txt b/src/bayesvalidrox.egg-info/requires.txt new file mode 100644 index 000000000..9aad4b04a --- /dev/null +++ b/src/bayesvalidrox.egg-info/requires.txt @@ -0,0 +1,13 @@ +numpy==1.23.3 +pandas==1.2.4 +joblib==1.2.0 +matplotlib==3.4.2 +seaborn==0.11.1 +scipy==1.11.1 +scikit-learn==1.3.0 +tqdm==4.61.1 +chaospy==4.3.3 +emcee==3.0.2 +corner==2.2.1 +h5py==3.8.0 +statsmodels==0.14 diff --git a/src/bayesvalidrox.egg-info/top_level.txt b/src/bayesvalidrox.egg-info/top_level.txt new file mode 100644 index 000000000..2753d5241 --- /dev/null +++ b/src/bayesvalidrox.egg-info/top_level.txt @@ -0,0 +1 @@ +bayesvalidrox diff --git a/src/bayesvalidrox/pylink/pylink.py b/src/bayesvalidrox/pylink/pylink.py index dda7c8fc9..3fd1db366 100644 --- a/src/bayesvalidrox/pylink/pylink.py +++ b/src/bayesvalidrox/pylink/pylink.py @@ -13,7 +13,9 @@ import multiprocessing from functools import partial import tqdm -from multiprocessing import get_context +import umbridge # TODO: add this to the imports!? +#from multiprocessing import get_context +from multiprocess import get_context @@ -51,6 +53,7 @@ def within_range(out, minout, maxout): inside = True return inside + class PyLinkForwardModel(object): """ A forward model binder @@ -466,6 +469,10 @@ class PyLinkForwardModel(object): # TODO: if umbridge, just run, no parallel from here # If the link type is UM-Bridge, then no parallel needs to be started from here if self.link_type.lower() == 'umbridge': + # Init model + #model = umbridge.HTTPModel('http://localhost:4242', 'forward') + self.model = umbridge.HTTPModel(self.host, 'forward') # TODO: is this always forward? + Function = self.uMBridge_model # For now just do same as usual self.link_type = 'function' @@ -521,7 +528,7 @@ class PyLinkForwardModel(object): elif self.multi_process or mp: with get_context('spawn').Pool(n_cpus) as p: #with multiprocessing.Pool(n_cpus) as p: - + if self.link_type.lower() == 'function': imap_var = p.imap(partial(Function, **self.func_args), c_points[:, np.newaxis]) @@ -533,7 +540,6 @@ class PyLinkForwardModel(object): if verbose: desc = f'Running forward model {key_str}' - print(imap_var) group_results = list(tqdm.tqdm(imap_var, total=n_c_points, desc=desc)) else: @@ -575,6 +581,59 @@ class PyLinkForwardModel(object): ) return all_outputs, new_c_points + + def uMBridge_model(self, params): + """ + Function that calls a UMBridge model and transforms its output into the + shape expected for the surrogate. + + Parameters + ---------- + params : 2d np.array, shape (#samples, #params) + The parameter values for which the model is run. + + Returns + ------- + dict + The transformed model outputs. + + """ + # Run the model + #out = np.array(model(np.ndarray.tolist(params), {'level':0})) + out = np.array(self.model(np.ndarray.tolist(params), self.modelparams)) + + # Sort into dict + out_dict = {} + cnt = 0 + for key in self.Output.names: + # If needed resort into single-value outputs + if self.output_type == 'single-valued': + if out[:,cnt].shape[1] >1: # TODO: this doesn't fully seem correct?? + for i in range(out[:,key]): + new_key = key+str(i) + if new_key not in self.Output.names: + self.Output.names.append(new_key) + if i == 0: + self.Ouptut.names.remove(key) + out_dict[new_key] = out[:,cnt,i] # TODO: not sure about this, need to test + else: + out_dict[key] = out[:,cnt] + + + else: + out_dict[key] = out[:,cnt] + cnt += 1 + + + # TODO: how to deal with the x-values? + if self.output_type == 'single-valued': + out_dict['x_values'] = [0] + else: + out_dict['x_values'] = np.arange(0,out[:,0].shape[0],1) + + #return {'T1':out[:,0], 'T2':out[:,1], 'H1':out[:,2], 'H2':out[:,3], + # 'x_values':[0]} + return out_dict # ------------------------------------------------------------------------- def _store_simulations(self, c_points, all_outputs, NaN_idx, key_str, @@ -606,7 +665,6 @@ class PyLinkForwardModel(object): hdf5file = f'ExpDesign_{self.name}.hdf5' else: hdf5file = f'ValidSet_{self.name}.hdf5' - print(hdf5file) hdf5_exist = os.path.exists(hdf5file) file = h5py.File(hdf5file, 'a') diff --git a/src/bayesvalidrox/surrogate_models/engine.py b/src/bayesvalidrox/surrogate_models/engine.py index 377ffd493..7f5c1bf77 100644 --- a/src/bayesvalidrox/surrogate_models/engine.py +++ b/src/bayesvalidrox/surrogate_models/engine.py @@ -740,11 +740,11 @@ class Engine(): # with Y_mean_can as the mean and Y_std_can as std. Y_MC, std_MC = {}, {} logPriorLikelihoods = np.zeros((mc_size)) - print(y_hat) - print(list[y_hat]) + # print(y_hat) + # print(list[y_hat]) for key in list(y_hat): cov = np.diag(std[key]**2) - print(y_hat[key], cov) + # print(y_hat[key], cov) # TODO: added the allow_singular = True here rv = stats.multivariate_normal(mean=y_hat[key], cov=cov,) Y_MC[key] = rv.rvs(size=mc_size) @@ -1098,8 +1098,8 @@ class Engine(): y_hat = {key: items[idx] for key, items in y_can.items()} std = {key: items[idx] for key, items in std_can.items()} - print(y_hat) - print(std) + # print(y_hat) + # print(std) U_J_d[idx] = self.util_BayesianActiveDesign( y_hat, std, sigma2Dict, var) @@ -1453,8 +1453,8 @@ class Engine(): split_cand = np.array_split( candidates, n_cand_groups, axis=0 ) - print(candidates) - print(split_cand) + # print(candidates) + # print(split_cand) if self.parallel: results = Parallel(n_jobs=-1, backend='multiprocessing')( delayed(self.run_util_func)( @@ -1531,7 +1531,7 @@ class Engine(): # Generate candidate samples from Exploration class nMeasurement = old_EDY[OutputNames[0]].shape[1] - print(UtilMethod) + # print(UtilMethod) # Find sensitive region if UtilMethod == 'LOOCV': @@ -1544,7 +1544,7 @@ class Engine(): LCerror[y_key][key]) ExploitScore = np.max(np.max(allModifiedLOO, axis=1), axis=1) - print(allModifiedLOO.shape) + # print(allModifiedLOO.shape) elif UtilMethod in ['EIGF', 'ALM']: # ----- All other in ['EIGF', 'ALM'] ----- @@ -1599,9 +1599,9 @@ class Engine(): # Normalize U_J_d ExploitScore = ExploitScore / np.sum(ExploitScore) totalScore = exploit_w * ExploitScore - print(totalScore.shape) - print(explore_w) - print(scoreExploration.shape) + # print(totalScore.shape) + # print(explore_w) + # print(scoreExploration.shape) totalScore += explore_w * scoreExploration temp = totalScore.copy() @@ -1748,7 +1748,7 @@ class Engine(): Phi[idx] = np.linalg.cond(M) else: - print(var.lower()) + # print(var.lower()) raise Exception('The optimality criterion you requested has ' 'not been implemented yet!') @@ -1795,7 +1795,7 @@ class Engine(): for idx, out in enumerate(self.out_names): # (Meta)Model Output - print(y_hat_pce[out]) + # print(y_hat_pce[out]) nsamples, nout = y_hat_pce[out].shape # Prepare data and remove NaN diff --git a/src/bayesvalidrox/surrogate_models/exp_designs.py b/src/bayesvalidrox/surrogate_models/exp_designs.py index e99fcf1be..665ee4fc3 100644 --- a/src/bayesvalidrox/surrogate_models/exp_designs.py +++ b/src/bayesvalidrox/surrogate_models/exp_designs.py @@ -52,9 +52,6 @@ class ExpDesigns(InputSpace): Input : obj Input object containing the parameter marginals, i.e. name, distribution type and distribution parameters or available raw data. - method : str - Type of the experimental design. The default is `'normal'`. Other - option is `'sequential'`. meta_Model_type : str Type of the meta_Model_type. sampling_method : str @@ -143,7 +140,7 @@ class ExpDesigns(InputSpace): - K-Opt (K-Optimality) """ - def __init__(self, Input, method='normal', meta_Model_type='pce', + def __init__(self, Input, meta_Model_type='pce', sampling_method='random', hdf5_file=None, n_new_samples=1, n_max_samples=None, mod_LOO_threshold=1e-16, tradeoff_scheme=None, n_canddidate=1, explore_method='random', @@ -152,7 +149,6 @@ class ExpDesigns(InputSpace): step_snapshot=1, max_a_post=[], adapt_verbose=False, max_func_itr=1): self.InputObj = Input - self.method = method # TODO: this still doing sth? self.meta_Model_type = meta_Model_type self.sampling_method = sampling_method self.hdf5_file = hdf5_file -- GitLab