LCOV - code coverage report
Current view: top level - src/distributions - KernelDensity1D.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: f45d79 Lines: 67 73 91.8 %
Date: 2025-07-25 05:00:46 Functions: 8 8 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 "KernelDensity1D.h"
      11             : #include "math.h"
      12             : #include "libmesh/utility.h"
      13             : #include "DelimitedFileReader.h"
      14             : #include "SystemBase.h"
      15             : #include "Assembly.h"
      16             : #include "Normal.h"
      17             : #include "Uniform.h"
      18             : 
      19             : registerMooseObject("StochasticToolsApp", KernelDensity1D);
      20             : 
      21             : InputParameters
      22         160 : KernelDensity1D::validParams()
      23             : {
      24         160 :   InputParameters params = Distribution::validParams();
      25         320 :   MooseEnum bandwidth_rule("silverman standarddeviation userdefined");
      26         320 :   MooseEnum kernel_function("gaussian uniform");
      27         160 :   params.addClassDescription("KernelDensity1D distribution");
      28         320 :   params.addRequiredParam<MooseEnum>(
      29             :       "bandwidth_rule", bandwidth_rule, "Bandwidth rule for evaluating the bandwith.");
      30         320 :   params.addRequiredParam<MooseEnum>(
      31             :       "kernel_function",
      32             :       kernel_function,
      33             :       "Kernel function determines the shape of the underlying kernel for the kernel density.");
      34         480 :   params.addRangeCheckedParam<Real>("bandwidth",
      35         320 :                                     1.0,
      36             :                                     "bandwidth > 0",
      37             :                                     "Bandwidth controls the smoothness of the kernel density.");
      38         320 :   params.addParam<std::vector<Real>>("data", "The data vector.");
      39         320 :   params.addParam<FileName>("file_name", "Name of the CSV file.");
      40         320 :   params.addParam<std::string>(
      41             :       "file_column_name", "Name of column in csv file to use, by default first column is used.");
      42         160 :   return params;
      43         160 : }
      44             : 
      45          80 : KernelDensity1D::KernelDensity1D(const InputParameters & parameters)
      46             :   : Distribution(parameters),
      47          80 :     _bandwidth_rule(getParam<MooseEnum>("bandwidth_rule")),
      48         160 :     _kernel_function(getParam<MooseEnum>("kernel_function")),
      49         240 :     _bandwidth(getParam<Real>("bandwidth"))
      50             : {
      51         256 :   if (isParamValid("data") && isParamValid("file_name"))
      52           0 :     paramError("data", "data and file_name both cannot be set at the same time.");
      53         160 :   else if (isParamValid("file_name"))
      54             :   {
      55          64 :     MooseUtils::DelimitedFileReader reader(getParam<FileName>("file_name"));
      56          32 :     reader.read();
      57          64 :     if (isParamValid("file_column_name"))
      58           0 :       _data = reader.getData(getParam<std::string>("file_column_name"));
      59             :     else
      60          32 :       _data = reader.getData(0);
      61          32 :   }
      62          96 :   else if (isParamValid("data"))
      63         144 :     _data = getParam<std::vector<Real>>("data");
      64             :   else
      65           0 :     mooseError("Either 'data' or 'file_name' parameters must be specified to represent input data");
      66             :   Real mu = 0;
      67             :   Real sd = 0;
      68        3760 :   for (unsigned i = 0; i < _data.size(); ++i)
      69             :   {
      70        3680 :     mu += _data[i] / _data.size();
      71             :   }
      72        3760 :   for (unsigned i = 0; i < _data.size(); ++i)
      73             :   {
      74        3680 :     sd += Utility::pow<2>((_data[i] - mu)) / _data.size();
      75             :   }
      76          80 :   sd = std::pow(sd, 0.5);
      77          80 :   if (_bandwidth_rule == "silverman")
      78             :   {
      79          48 :     _bandwidth = 1.06 * sd * std::pow(_data.size(), -0.2);
      80             :   }
      81          32 :   else if (_bandwidth_rule == "standarddeviation")
      82             :   {
      83          16 :     _bandwidth = sd;
      84             :   }
      85          80 : }
      86             : 
      87             : Real
      88          80 : KernelDensity1D::pdf(const Real & x,
      89             :                      const Real & bandwidth,
      90             :                      const std::vector<Real> & data,
      91             :                      const MooseEnum & kernel_function)
      92             : {
      93             :   Real value = 0;
      94          80 :   if (kernel_function == "gaussian")
      95             :   {
      96        2144 :     for (unsigned i = 0; i < data.size(); ++i)
      97             :     {
      98        2080 :       value += 1 / (data.size() * bandwidth) * Normal::pdf(((x - data[i]) / bandwidth), 0.0, 1.0);
      99             :     }
     100             :   }
     101          16 :   else if (kernel_function == "uniform")
     102             :   {
     103        1616 :     for (unsigned i = 0; i < data.size(); ++i)
     104             :     {
     105        1600 :       value += 1 / (data.size() * bandwidth) * Uniform::pdf(((x - data[i]) / bandwidth), -1.0, 1.0);
     106             :     }
     107             :   }
     108             :   else
     109           0 :     ::mooseError("Invalid kernel function type ", std::string(kernel_function));
     110          80 :   return value;
     111             : }
     112             : 
     113             : Real
     114          80 : KernelDensity1D::cdf(const Real & x,
     115             :                      const Real & bandwidth,
     116             :                      const std::vector<Real> & data,
     117             :                      const MooseEnum & kernel_function)
     118             : {
     119             :   Real value = 0;
     120          80 :   if (kernel_function == "gaussian")
     121             :   {
     122        2144 :     for (unsigned i = 0; i < data.size(); ++i)
     123             :     {
     124        2080 :       value += 1.0 / (data.size()) * Normal::cdf(x, data[i], bandwidth);
     125             :     }
     126             :   }
     127          16 :   else if (kernel_function == "uniform")
     128             :   {
     129        1616 :     for (unsigned i = 0; i < data.size(); ++i)
     130             :     {
     131        1600 :       value += 1.0 / (data.size()) * Uniform::cdf((x - data[i]) / bandwidth, -1.0, 1.0);
     132             :     }
     133             :   }
     134             :   else
     135           0 :     ::mooseError("Invalid kernel function type ", std::string(kernel_function));
     136          80 :   return value;
     137             : }
     138             : 
     139             : Real
     140          80 : KernelDensity1D::quantile(const Real & p,
     141             :                           const Real & bandwidth,
     142             :                           const std::vector<Real> & data,
     143             :                           const MooseEnum & kernel_function)
     144             : {
     145             :   Real value = 0;
     146          80 :   if (kernel_function == "gaussian")
     147             :   {
     148          64 :     int index = std::round(p * (data.size() - 1));
     149          64 :     value = (Normal::quantile(p, data[index], bandwidth));
     150             :   }
     151          16 :   else if (kernel_function == "uniform")
     152             :   {
     153          16 :     int index = std::round(p * (data.size() - 1));
     154          16 :     value = (Uniform::quantile(p, -1.0, 1.0) * bandwidth + data[index]);
     155             :   }
     156             :   else
     157           0 :     ::mooseError("Invalid kernel function type ", std::string(kernel_function));
     158          80 :   return value;
     159             : }
     160             : 
     161             : Real
     162          80 : KernelDensity1D::pdf(const Real & x) const
     163             : {
     164          80 :   return pdf(x, _bandwidth, _data, _kernel_function);
     165             : }
     166             : 
     167             : Real
     168          80 : KernelDensity1D::cdf(const Real & x) const
     169             : {
     170          80 :   return cdf(x, _bandwidth, _data, _kernel_function);
     171             : }
     172             : 
     173             : Real
     174          80 : KernelDensity1D::quantile(const Real & p) const
     175             : {
     176          80 :   return quantile(p, _bandwidth, _data, _kernel_function);
     177             : }

Generated by: LCOV version 1.14