Quinoa regression test code coverage report
Current view: top level - Statistics - TriPDF.hpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 30 30 100.0 %
Date: 2021-11-09 13:40:20 Functions: 4 4 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 47 54 87.0 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Statistics/TriPDF.hpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     Joint trivariate PDF estimator
       9                 :            :   \details   Joint trivariate PDF estimator. This class can be used to estimate
      10                 :            :     a joint probability density function (PDF) of three scalar variables from an
      11                 :            :     ensemble. The implementation uses the standard container std::unordered_map,
      12                 :            :     which is a hash-based associative container with linear algorithmic
      13                 :            :     complexity for insertion of a new sample.
      14                 :            : */
      15                 :            : // *****************************************************************************
      16                 :            : #ifndef TriPDF_h
      17                 :            : #define TriPDF_h
      18                 :            : 
      19                 :            : #include <array>
      20                 :            : #include <unordered_map>
      21                 :            : #include <algorithm>
      22                 :            : 
      23                 :            : #include "Types.hpp"
      24                 :            : #include "PUPUtil.hpp"
      25                 :            : 
      26                 :            : namespace tk {
      27                 :            : 
      28                 :            : //! Joint trivariate PDF estimator
      29                 :      40076 : class TriPDF {
      30                 :            : 
      31                 :            :   public:
      32                 :            :     //! Number of sample space dimensions
      33                 :            :     static const std::size_t dim = 3;
      34                 :            : 
      35                 :            :     //! Key type
      36                 :            :     using key_type = std::array< long, dim >;
      37                 :            : 
      38                 :            :     //! Pair type
      39                 :            :     using pair_type = std::pair< const key_type, tk::real >;
      40                 :            : 
      41                 :            :     // Hash functor for key_type
      42                 :            :     struct key_hash {
      43                 :            :       std::size_t operator()( const key_type& key ) const {
      44                 :     500536 :         return std::hash< long >()( key[0] ) ^
      45                 :     500536 :                std::hash< long >()( key[1] ) ^
      46                 :     500536 :                std::hash< long >()( key[2] );
      47                 :            :       }
      48                 :            :     };
      49                 :            : 
      50                 :            :     //! \brief Joint trivariate PDF
      51                 :            :     //! \details The underlying container type is an unordered_map where the key
      52                 :            :     //!   is three bin ids corresponding to the three sample space dimensions,
      53                 :            :     //!   and the mapped value is the sample counter. The hasher functor,
      54                 :            :     //!   defined by key_hash provides an XORed hash of the three bin ids.
      55                 :            :     using map_type = std::unordered_map< key_type, tk::real, key_hash >;
      56                 :            : 
      57                 :            :     //! Empty constructor for Charm++
      58         [ +  - ]:      20072 :     explicit TriPDF() : m_binsize( {{ 0, 0, 0 }} ), m_nsample( 0 ), m_pdf() {}
      59                 :            : 
      60                 :            :     //! Constructor: Initialize joint trivariate PDF container
      61                 :            :     //! \param[in] bs Sample space bin size in all three directions
      62                 :         32 :     explicit TriPDF( const std::vector< tk::real >& bs ) :
      63                 :         32 :       m_binsize( {{ bs[0], bs[1], bs[2] }} ),
      64                 :            :       m_nsample( 0 ),
      65                 :         32 :       m_pdf() {}
      66                 :            : 
      67                 :            :     //! Accessor to number of samples
      68                 :            :     //! \return Number of samples collected
      69                 :            :     std::size_t nsample() const noexcept { return m_nsample; }
      70                 :            : 
      71                 :            :     //! Add sample to trivariate PDF
      72                 :            :     //! \param[in] sample Sample to add
      73                 :     120000 :     void add( std::array< tk::real, dim > sample ) {
      74                 :     120000 :       ++m_nsample;
      75                 :     240000 :       ++m_pdf[ {{ std::lround( sample[0] / m_binsize[0] ),
      76                 :     120000 :                   std::lround( sample[1] / m_binsize[1] ),
      77                 :     120000 :                   std::lround( sample[2] / m_binsize[2] ) }} ];
      78                 :     120000 :     }
      79                 :            : 
      80                 :            :     //! Add multiple samples from a PDF
      81                 :            :     //! \param[in] p PDF whose samples to add
      82                 :      30060 :     void addPDF( const TriPDF& p ) {
      83                 :      30060 :       m_binsize = p.binsize();
      84                 :      30060 :       m_nsample += p.nsample();
      85         [ +  + ]:     240066 :       for (const auto& e : p.map()) m_pdf[ e.first ] += e.second;
      86                 :      30060 :     }
      87                 :            : 
      88                 :            :     //! Zero bins
      89                 :      16096 :     void zero() noexcept { m_nsample = 0; m_pdf.clear(); }
      90                 :            : 
      91                 :            :     //! Constant accessor to underlying PDF map
      92                 :            :     //! \return Constant reference to underlying map
      93                 :            :     const map_type& map() const noexcept { return m_pdf; }
      94                 :            : 
      95                 :            :     //! Constant accessor to bin sizes
      96                 :            :     //! \return Constant reference to sample space bin sizes
      97                 :            :     const std::array< tk::real, dim >& binsize() const noexcept
      98                 :            :     { return m_binsize; }
      99                 :            : 
     100                 :            :     //! \brief Return minimum and maximum bin ids of sample space in all three
     101                 :            :     //!   dimensions
     102                 :            :     //! \return {xmin,xmax,ymin,ymax,zmin,zmax} Minima and maxima of bin the ids
     103                 :          8 :     std::array< long, 2*dim > extents() const {
     104                 :            :       Assert( !m_pdf.empty(), "PDF empty" );
     105                 :            :       auto x = std::minmax_element( begin(m_pdf), end(m_pdf),
     106                 :            :                  []( const pair_type& a, const pair_type& b )
     107 [ +  + ][ +  - ]:       9145 :                  { return a.first[0] < b.first[0]; } );
         [ -  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     108                 :            :       auto y = std::minmax_element( begin(m_pdf), end(m_pdf),
     109                 :            :                  []( const pair_type& a, const pair_type& b )
     110 [ +  + ][ +  - ]:       9134 :                  { return a.first[1] < b.first[1]; } );
         [ -  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     111                 :            :       auto z = std::minmax_element( begin(m_pdf), end(m_pdf),
     112                 :            :                  []( const pair_type& a, const pair_type& b )
     113 [ +  + ][ +  + ]:       9138 :                  { return a.first[2] < b.first[2]; } );
         [ -  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     114                 :            :       return {{ x.first->first[0], x.second->first[0],
     115                 :            :                 y.first->first[1], y.second->first[1],
     116                 :          8 :                 z.first->first[2], z.second->first[2] }};
     117                 :            :     }
     118                 :            : 
     119                 :            :     /** @name Pack/Unpack: Serialize BiPDF object for Charm++ */
     120                 :            :     ///@{
     121                 :            :     //! Pack/Unpack serialize member function
     122                 :            :     //! \param[in,out] p Charm++'s PUP::er serializer object reference
     123                 :      60120 :     void pup( PUP::er& p ) {
     124                 :            :       p | m_binsize;
     125                 :      60120 :       p | m_nsample;
     126                 :      60120 :       p | m_pdf;
     127                 :      60120 :     }
     128                 :            :     //! \brief Pack/Unpack serialize operator|
     129                 :            :     //! \param[in,out] p Charm++'s PUP::er serializer object reference
     130                 :            :     //! \param[in,out] c TriPDF object reference
     131         [ +  - ]:      60120 :     friend void operator|( PUP::er& p, TriPDF& c ) { c.pup(p); }
     132                 :            :     ///@}
     133                 :            : 
     134                 :            :   private:
     135                 :            :     std::array< tk::real, dim > m_binsize;   //!< Sample space bin sizes
     136                 :            :     std::size_t m_nsample;                   //!< Number of samples collected
     137                 :            :     map_type m_pdf;                          //!< Probability density function
     138                 :            : };
     139                 :            : 
     140                 :            : } // tk::
     141                 :            : 
     142                 :            : #endif // TriPDF_h

Generated by: LCOV version 1.14