mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
radprofIntegral.hpp
Go to the documentation of this file.
1 /** \file radprofIntegral.hpp
2  * \author Jared R. Males (jaredmales@gmail.com)
3  * \brief 2D integration of a radial profile
4  * \ingroup gen_math_files
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2022 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 #ifndef radprofIntegral_hpp
27 #define radprofIntegral_hpp
28 
29 #include <cmath>
30 #include <vector>
31 #include <type_traits>
32 
33 #include "../mxException.hpp"
34 
35 #include "constants.hpp"
36 
37 namespace mx
38 {
39 namespace math
40 {
41 
42 /// Calculate the 2D integral given a radial profile.
43 /** Calculates the integral
44  * \f[
45  2\pi \int_{min}^{max} p(r) r dr
46  \f]
47  * using the <a href="https://en.wikipedia.org/wiki/Trapezoidal_rule">Trapezoid rule</a>.
48  *
49  * The limits of integration are normally `r[0]` to `r.back()` inclusive. If the parameter \p inczero
50  * is set to true, then the region from `0` to `r[0]` is included, using the value of `p[0]`, where the
51  * the integral is there estimate as \f$ p[0] \pi r[0]^2 \f$.
52  *
53  * \todo the trapezoid rule may not be strictly valid as implemented. Is there a weighting to apply based on r?
54  *
55  * \returns the value of the integral
56  *
57  * \throws mxException if the sizes of the input vectors don't match.
58  *
59  * \ingroup integration
60  */
61 template< typename vectorScT, typename vectorT>
62 typename vectorT::value_type radprofIntegral( vectorScT r, /// [in] the r
63  vectorT p,
64  bool inczero = false
65  )
66 {
67  typedef typename vectorT::value_type floatT;
68 
69  static_assert( std::is_floating_point<typename std::remove_cv<floatT>::type>::value, "radprofIntegral: function must be floating point");
70 
71  if(r.size() != p.size())
72  {
73  mxThrowException(err::sizeerr, "radprofIntegral", "vectors must have same size");
74  }
75 
76  if(r.size() < 2)
77  {
78  mxThrowException(err::sizeerr, "radprofIntegral", "must be at least 2 elements in radial profile");
79  }
80 
81  floatT s = 0;
82 
83  if(inczero) s = p[0]*pow(r[0],2);
84 
85  size_t n = 0;
86  s += 0.5*p[n]*(pow(r[n+1],2) - pow(r[n],2));//r[0] * ( r[1] - r[0] );
87 
88  for(n=1; n < r.size()-1; ++n)
89  {
90  s += p[n]*(pow(r[n],2) - pow(r[n-1],2));//r[n] * ( r[n] - r[n-1]);
91  }
92 
93  s += 0.5*p[n]*(pow(r[n],2) - pow(r[n-1],2));
94 
95  //size_t n = r.size()-1;
96  //s += 2*p[n]*r[n] * ( r[n] - r[n-1] );
97 
98  return s*pi<floatT>();
99 }
100 
101 } //namespace math
102 } //namespace mx
103 
104 #endif //radprofIntegral_hpp
mxException for a size error
vectorT::value_type radprofIntegral(vectorScT r, vectorT p, bool inczero=false)
Calculate the 2D integral given a radial profile.
The mxlib c++ namespace.
Definition: mxError.hpp:107