LCOV - code coverage report
Current view: top level - src/samplers - AffineInvariantDES.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: #31405 (292dce) with base fef103 Lines: 53 58 91.4 %
Date: 2025-09-04 07:57:52 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         212 : AffineInvariantDES::validParams()
      25             : {
      26         212 :   InputParameters params = PMCMCBase::validParams();
      27         212 :   params.addClassDescription("Perform Affine Invariant Ensemble MCMC with differential sampler.");
      28         424 :   params.addRequiredParam<ReporterName>(
      29             :       "previous_state", "Reporter value with the previous state of all the walkers.");
      30         424 :   params.addRequiredParam<ReporterName>(
      31             :       "previous_state_var",
      32             :       "Reporter value with the previous state of all the walkers for variance.");
      33         424 :   MooseEnum tuning_option("Braak2006_static", "Braak2006_static");
      34         424 :   params.addParam<MooseEnum>(
      35             :       "tuning_option", tuning_option, "The tuning option for internal parameters.");
      36         424 :   params.addParam<std::vector<Real>>("scales", "Scales for the parameters.");
      37         212 :   return params;
      38         212 : }
      39             : 
      40         124 : AffineInvariantDES::AffineInvariantDES(const InputParameters & parameters)
      41             :   : PMCMCBase(parameters),
      42         124 :     _previous_state(getReporterValue<std::vector<std::vector<Real>>>("previous_state")),
      43         124 :     _previous_state_var(getReporterValue<std::vector<Real>>("previous_state_var")),
      44         372 :     _tuning_option(getParam<MooseEnum>("tuning_option"))
      45             : {
      46         124 :   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         124 :   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         248 :   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         120 :     _scales.assign(_priors.size(), 1.0);
      65         120 : }
      66             : 
      67             : void
      68        5896 : 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        5896 :   tuneParams(gamma, b, scale);
      74        5896 :   diff = gamma * (state1 - state2) + Normal::quantile(rnd, 0.0, b);
      75        5896 : }
      76             : 
      77             : void
      78        5896 : AffineInvariantDES::tuneParams(Real & gamma, Real & b, const Real & scale)
      79             : {
      80        5896 :   if (_tuning_option == "Braak2006_static")
      81             :   {
      82        5896 :     gamma = 2.38 / std::sqrt(2 * _priors.size());
      83        5896 :     b = 1e-6 * scale;
      84             :   }
      85        5896 : }
      86             : 
      87             : void
      88         440 : AffineInvariantDES::proposeSamples(const unsigned int seed_value)
      89             : {
      90         440 :   unsigned int j = 0;
      91             :   bool indicator;
      92             :   unsigned int index_req1, index_req2;
      93             :   Real diff;
      94        3212 :   while (j < _num_parallel_proposals)
      95             :   {
      96             :     indicator = 0;
      97        2332 :     randomIndexPair(_num_parallel_proposals, j, seed_value, index_req1, index_req2);
      98        6996 :     for (unsigned int i = 0; i < _priors.size(); ++i)
      99             :     {
     100        4664 :       computeDifferential(_previous_state[index_req1][i],
     101        4664 :                           _previous_state[index_req2][i],
     102        4664 :                           getRand(seed_value),
     103             :                           _scales[i],
     104             :                           diff);
     105        6424 :       _new_samples[j][i] = (_t_step > decisionStep()) ? (_previous_state[j][i] + diff)
     106        1760 :                                                       : _priors[i]->quantile(getRand(seed_value));
     107        4664 :       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        2332 :     if (_var_prior)
     114             :     {
     115        1232 :       computeDifferential(_previous_state_var[index_req1],
     116        1232 :                           _previous_state_var[index_req2],
     117        1232 :                           getRand(seed_value),
     118        1232 :                           1.0,
     119             :                           diff);
     120        1672 :       _new_var_samples[j] = (_t_step > decisionStep()) ? (_previous_state_var[j] + diff)
     121         440 :                                                        : _var_prior->quantile(getRand(seed_value));
     122        1232 :       if (_new_var_samples[j] < 0.0)
     123             :         indicator = 1;
     124             :     }
     125        2332 :     if (!indicator)
     126        2200 :       ++j;
     127             :   }
     128         440 : }

Generated by: LCOV version 1.14