LCOV - code coverage report
Current view: top level - src/samplers - AffineInvariantDES.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: f45d79 Lines: 53 58 91.4 %
Date: 2025-07-25 05:00:46 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "AffineInvariantDES.h"
      11             : #include "Normal.h"
      12             : #include "Uniform.h"
      13             : 
      14             : registerMooseObject("StochasticToolsApp", AffineInvariantDES);
      15             : 
      16             : /*
      17             :  Tuning options for the internal parameters
      18             :   1. Braak2006_static:
      19             :   - the gamma param is set to 2.38 / sqrt(2 * dim)
      20             :   - the b param is set to (scale) * 1e-6
      21             : */
      22             : 
      23             : InputParameters
      24         196 : AffineInvariantDES::validParams()
      25             : {
      26         196 :   InputParameters params = PMCMCBase::validParams();
      27         196 :   params.addClassDescription("Perform Affine Invariant Ensemble MCMC with differential sampler.");
      28         392 :   params.addRequiredParam<ReporterName>(
      29             :       "previous_state", "Reporter value with the previous state of all the walkers.");
      30         392 :   params.addRequiredParam<ReporterName>(
      31             :       "previous_state_var",
      32             :       "Reporter value with the previous state of all the walkers for variance.");
      33         392 :   MooseEnum tuning_option("Braak2006_static", "Braak2006_static");
      34         392 :   params.addParam<MooseEnum>(
      35             :       "tuning_option", tuning_option, "The tuning option for internal parameters.");
      36         392 :   params.addParam<std::vector<Real>>("scales", "Scales for the parameters.");
      37         196 :   return params;
      38         196 : }
      39             : 
      40         116 : AffineInvariantDES::AffineInvariantDES(const InputParameters & parameters)
      41             :   : PMCMCBase(parameters),
      42         116 :     _previous_state(getReporterValue<std::vector<std::vector<Real>>>("previous_state")),
      43         116 :     _previous_state_var(getReporterValue<std::vector<Real>>("previous_state_var")),
      44         348 :     _tuning_option(getParam<MooseEnum>("tuning_option"))
      45             : {
      46         116 :   if (_num_parallel_proposals < 5)
      47           0 :     paramError(
      48             :         "num_parallel_proposals",
      49             :         "At least five parallel proposals should be used for the Differential Evolution Sampler.");
      50             : 
      51         116 :   if (_num_parallel_proposals < _priors.size())
      52           0 :     mooseWarning(
      53             :         "It is recommended that the parallel proposals be greater than or equal to the "
      54             :         "inferred parameters. This will allow the sampler to not get stuck on a hyper-plane.");
      55             : 
      56         232 :   if (isParamValid("scales"))
      57             :   {
      58          12 :     _scales = getParam<std::vector<Real>>("scales");
      59           4 :     if (_scales.size() != _priors.size())
      60           4 :       paramError("scales",
      61             :                  "The number of scales provided should match the number of tunable params.");
      62             :   }
      63             :   else
      64         112 :     _scales.assign(_priors.size(), 1.0);
      65         112 : }
      66             : 
      67             : void
      68        5360 : AffineInvariantDES::computeDifferential(
      69             :     const Real & state1, const Real & state2, const Real & rnd, const Real & scale, Real & diff)
      70             : {
      71             :   Real gamma;
      72             :   Real b;
      73        5360 :   tuneParams(gamma, b, scale);
      74        5360 :   diff = gamma * (state1 - state2) + Normal::quantile(rnd, 0.0, b);
      75        5360 : }
      76             : 
      77             : void
      78        5360 : AffineInvariantDES::tuneParams(Real & gamma, Real & b, const Real & scale)
      79             : {
      80        5360 :   if (_tuning_option == "Braak2006_static")
      81             :   {
      82        5360 :     gamma = 2.38 / std::sqrt(2 * _priors.size());
      83        5360 :     b = 1e-6 * scale;
      84             :   }
      85        5360 : }
      86             : 
      87             : void
      88         400 : AffineInvariantDES::proposeSamples(const unsigned int seed_value)
      89             : {
      90         400 :   unsigned int j = 0;
      91             :   bool indicator;
      92             :   unsigned int index_req1, index_req2;
      93             :   Real diff;
      94        2920 :   while (j < _num_parallel_proposals)
      95             :   {
      96             :     indicator = 0;
      97        2120 :     randomIndexPair(_num_parallel_proposals, j, seed_value, index_req1, index_req2);
      98        6360 :     for (unsigned int i = 0; i < _priors.size(); ++i)
      99             :     {
     100        4240 :       computeDifferential(_previous_state[index_req1][i],
     101        4240 :                           _previous_state[index_req2][i],
     102        4240 :                           getRand(seed_value),
     103             :                           _scales[i],
     104             :                           diff);
     105        5840 :       _new_samples[j][i] = (_t_step > decisionStep()) ? (_previous_state[j][i] + diff)
     106        1600 :                                                       : _priors[i]->quantile(getRand(seed_value));
     107        4240 :       if (_lower_bound)
     108           0 :         indicator =
     109           0 :             (_new_samples[j][i] < (*_lower_bound)[i] || _new_samples[j][i] > (*_upper_bound)[i])
     110           0 :                 ? 1
     111             :                 : indicator;
     112             :     }
     113        2120 :     if (_var_prior)
     114             :     {
     115        1120 :       computeDifferential(_previous_state_var[index_req1],
     116        1120 :                           _previous_state_var[index_req2],
     117        1120 :                           getRand(seed_value),
     118        1120 :                           1.0,
     119             :                           diff);
     120        1520 :       _new_var_samples[j] = (_t_step > decisionStep()) ? (_previous_state_var[j] + diff)
     121         400 :                                                        : _var_prior->quantile(getRand(seed_value));
     122        1120 :       if (_new_var_samples[j] < 0.0)
     123             :         indicator = 1;
     124             :     }
     125        2120 :     if (!indicator)
     126        2000 :       ++j;
     127             :   }
     128         400 : }

Generated by: LCOV version 1.14