The SKIRT project
advanced radiative transfer for astrophysics
Static Public Member Functions | Static Private Member Functions | List of all members
NR Class Reference

#include <NR.hpp>

Static Public Member Functions

template<class V >
static Array array (const V &sourcev)
 
template<class V , typename = std::enable_if_t<!CompileTimeUtils::isNumericArgList<V>()>>
static void assign (Array &targetv, const V &sourcev)
 
template<typename... Values, typename = std::enable_if_t<sizeof...(Values) != 0 && CompileTimeUtils::isFloatArgList<Values...>()>>
static void assign (Array &targetv, Values... values)
 
static double buildLinearGrid (Array &xv, double xmin, double xmax, int n)
 
static void buildLogGrid (Array &xv, double xmin, double xmax, int n)
 
static void buildPowerLawGrid (Array &xv, double xmin, double xmax, int n, double ratio)
 
static void buildSymmetricPowerLawGrid (Array &xv, double xmin, double xmax, int n, double ratio)
 
static void buildZeroLogGrid (Array &xv, double xmin, double xmax, int n)
 
static double cdf (Array &Pv, const Array &pv)
 
template<typename Functor >
static double cdf (Array &Pv, int n, Functor pv)
 
template<double interpolateFunction>
static double cdf (Array &xv, Array &pv, Array &Pv, const Array &inxv, const Array &inpv, Range xrange)
 
static double cdf2 (bool loglog, const Array &xv, Array &pv, Array &Pv)
 
template<double interpolateFunction>
static Array clampedResample (const Array &xresv, const Array &xoriv, const Array &yoriv)
 
template<double interpolateFunction>
static double clampedValue (double x, const Array &xv, const Array &yv)
 
static double interpolateLinLin (double x, double x1, double x2, double f1, double f2)
 
static double interpolateLogLin (double x, double x1, double x2, double f1, double f2)
 
static double interpolateLogLog (double x, double x1, double x2, double f1, double f2)
 
static int locate (const Array &xv, double x)
 
template<typename T >
static int locate (const std::vector< T > &xv, const T &x)
 
static int locateBasicImpl (const Array &xv, double x, int n)
 
static int locateClip (const Array &xv, double x)
 
static int locateFail (const Array &xv, double x)
 
template<double interpolateFunction>
static Array resample (const Array &xresv, const Array &xoriv, const Array &yoriv)
 
static void reverse (Array &xv, size_t blocksize=1)
 
static void sort (Array &xv)
 
template<typename T >
static void sort (std::vector< T > &xv)
 
template<typename T >
static void unique (std::vector< T > &xv)
 
template<double interpolateFunction>
static double value (double x, const Array &xv, const Array &yv)
 

Static Private Member Functions

template<typename... Values>
static void assignValues (size_t index, Array &target, double value, Values... values)
 
static void assignValues (size_t, Array &)
 

Detailed Description

This static class contains a collection of functions that operate on Array objects and on std::vector<T> objects where T is some numeric type. Most implementations are provided inline in the header.

Member Function Documentation

◆ array()

template<class V >
static Array NR::array ( const V &  sourcev)
inlinestatic

This template function converts the source sequence to an Array object and returns the result. This template function works for any source container type with indexed random access (specifically including std::vector), and for any item types, as long as the source items can be assigned to or converted to double.

◆ assign() [1/2]

template<class V , typename = std::enable_if_t<!CompileTimeUtils::isNumericArgList<V>()>>
static void NR::assign ( Array targetv,
const V &  sourcev 
)
inlinestatic

This template function assigns the source sequence to the destination array, resizing the destination array if necessary. This template function works for any source container type with indexed random access (specifically including std::vector), and for any item types, as long as the source items can be assigned to or converted to double.

◆ assign() [2/2]

template<typename... Values, typename = std::enable_if_t<sizeof...(Values) != 0 && CompileTimeUtils::isFloatArgList<Values...>()>>
static void NR::assign ( Array targetv,
Values...  values 
)
inlinestatic

This template function assigns the floating point values specified as its arguments to the destination array, resizing the destination array if necessary.

◆ buildLinearGrid()

static double NR::buildLinearGrid ( Array xv,
double  xmin,
double  xmax,
int  n 
)
inlinestatic

This function builds a linear grid over the specified range \([x_{\text{min}}, x_{\text{max}}]\) and with the specified number of \(N>0\) bins, and stores the resulting \(N+1\) border points \(x_i\) in the provided array, which is resized appropriately. The grid's border points are calculated according to

\[ x_i = x_{\text{min}} + (x_{\text{max}}-x_{\text{min}})\,\frac{i}{N} \qquad i=0,\ldots,N. \]

The function returns the bin width, i.e. the distance between two adjacent border points, given by \((x_{\text{max}}-x_{\text{min}})/N\).

◆ buildLogGrid()

static void NR::buildLogGrid ( Array xv,
double  xmin,
double  xmax,
int  n 
)
inlinestatic

This function builds a logarithmic grid over the specified range \([x_{\text{min}}, x_{\text{max}}]\) and with the specified number of \(N>0\) bins, and stores the resulting \(N+1\) border points \(x_i\) in the provided array, which is resized appropriately. The grid's border points are calculated according to

\[ x_i = x_{\text{min}} \left( \frac{x_{\text{max}}}{x_{\text{min}}} \right)^{i/N} \qquad i=0,\ldots,N. \]

◆ buildPowerLawGrid()

static void NR::buildPowerLawGrid ( Array xv,
double  xmin,
double  xmax,
int  n,
double  ratio 
)
inlinestatic

This function builds a power-law grid over the specified range \([x_{\text{min}}, x_{\text{max}}]\) and with the specified number of \(N>0\) bins and specified ratio \({\cal{R}}\) of last over first bin widths, and stores the resulting \(N+1\) border points \(x_i\) in the provided array, which is resized appropriately. If the specified ratio is very close to one, the function simply builds a linear grid. Otherwise the grid's border points are calculated according to

\[ x_i = x_{\text{min}} + (x_{\text{max}} - x_{\text{min}}) \left(\frac{1-q^i}{1-q^N}\right) \qquad i=0,\ldots,N, \]

with \( q = {\cal{R}}^{1/(N-1)} \). It is easy to check that the ratio between the widths of the last and first bins is indeed \({\cal{R}}\):

\[ \frac{ x_N-x_{N-1} }{ x_1-x_0 } = \frac{ q^{N-1} - q^N }{ 1-q } = q^{N-1} = {\cal{R}}. \]

◆ buildSymmetricPowerLawGrid()

static void NR::buildSymmetricPowerLawGrid ( Array xv,
double  xmin,
double  xmax,
int  n,
double  ratio 
)
inlinestatic

This function builds a symmetrical power-law grid over the specified range \([x_{\text{min}}, x_{\text{max}}]\) and with the specified number of \(N>0\) bins and specified ratio \({\cal{R}}\) of outermost over innermost bin widths, and stores the resulting \(N+1\) border points \(x_i\) in the provided array, which is resized appropriately. If the specified ratio is very close to one, the function simply builds a linear grid. Otherwise, because of the required symmetry, the expression for the grid's border points depends on whether the number of bins is even or odd. Define the centre of the grid as \(x_{\text{c}} = \tfrac12(x_{\text{min}}+x_{\text{max}})\). If \(N\) is even, we define \(M=N/2\) and set \(x_M=x_{\text{c}}\) and

\[ x_{M\pm i} = x_{\text{c}} \pm \tfrac12(x_{\text{max}}-x_{\text{min}}) \left(\frac{1-q^i}{1-q^M}\right) \qquad i=1,\ldots,M \]

with \( q = {\cal{R}}^{1/(M-1)} \). The ratio between the widths of the outermost and the innermost bins is now

\[ \frac{x_{2M}-x_{2M-1}}{x_{M+1}-x_M} = \frac{q^{M-1}-q^M}{1-q} = q^{M-1} = {\cal{R}}. \]

On the other hand, if \(N\) is odd, we define \(M = (N+1)/2\) and

\[ x_{M-\frac12\pm (i-\frac12)} = x_{\text{c}} \pm \tfrac12(x_{\text{max}}-x_{\text{min}}) \left[ \frac{ \frac12\,(1+q) - q^i }{ \frac12\,(1+q) - q^M } \right] \qquad i=1,\ldots,M, \]

with again \( q = {\cal{R}}^{1/(M-1)} \). The ratio between the widths of the outermost and the innermost bins is for this case

\[ \frac{ x_{2M-1}-x_{2M-2} }{ x_M-x_{M-1} } = \frac{ q^{M-1} - q^M }{ 1-q } = q^{M-1} = {\cal{R}}. \]

◆ buildZeroLogGrid()

static void NR::buildZeroLogGrid ( Array xv,
double  xmin,
double  xmax,
int  n 
)
inlinestatic

This function builds a grid with its first bin starting at zero, and subsequent logarithmic border points over the specified range \([x_{\text{min}}, x_{\text{max}}]\). The grid has the specified number of \(N>0\) bins and the resulting \(N+1\) border points \(x_i\) are stored in the provided array, which is resized appropriately. The grid's border points are calculated according to \(x_0=0\) and

\[ x_i = x_{\text{min}} \left( \frac{x_{\text{max}}}{x_{\text{min}}} \right)^{(i-1)/(N-1)} \qquad i=1,\ldots,N. \]

◆ cdf() [1/3]

static double NR::cdf ( Array Pv,
const Array pv 
)
inlinestatic

Given a discrete distribution over \(N\) points

\[p_i \qquad i=0,\dots,N-1\]

this function builds the corresponding normalized cumulative distribution

\[P_0=0;\quad P_{i+1}=\frac{\sum_{j=0}^i p_j}{\sum_{j=0}^{N-1} p_j} \qquad i=0,\dots,N-1\]

with \(N+1\) elements. The function returns the factor used to normalize the cumulative distribution. In this version of the function, the source distribution is specified as an array with at least one element; the target array is resized appropriately and replaced by the cumulative distribution.

◆ cdf() [2/3]

template<typename Functor >
static double NR::cdf ( Array Pv,
int  n,
Functor  pv 
)
inlinestatic

Given a discrete distribution over \(N\) points

\[p_i \qquad i=0,\dots,N-1\]

this function builds the corresponding normalized cumulative distribution

\[P_0=0;\quad P_{i+1}=\frac{\sum_{j=0}^i p_j}{\sum_{j=0}^{N-1} p_j} \qquad i=0,\dots,N-1\]

with \(N+1\) elements. The function returns the factor used to normalize the cumulative distribution. In this version of the function, the source distribution is specified by a function object with signature double pv(int i); the number of source points \(N>0\) is specified as a separate argument. The source function is called once for each index \(i=0,\dots,N-1\). The target array is resized appropriately and replaced by the cumulative distribution.

◆ cdf() [3/3]

template<double interpolateFunction>
static double NR::cdf ( Array xv,
Array pv,
Array Pv,
const Array inxv,
const Array inpv,
Range  xrange 
)
inlinestatic

Given the tabulated values for a continuous probability distribution, this function constructs both the normalized probability density function (pdf) and the corresponding normalized cumulative distribution function (cdf) within a given range. The incoming distribution is specified by the inxv and inpv arrays and does not need to be normalized. The specified xrange must overlap the incoming grid, but it does not need to coincide with it. The function constructs a new grid xv that matches the given range and then constructs both the normalized pdf pv and the normalized cdf Pv corresponding to this new grid. It returns the factor used to normalize the distributions.

The outer grid points of the new grid match the specified range, and therefore usually do not occur in the incoming grid. The pv values for those new grid points are interpolated using the function specified as template argument. The interpolation functions provided by this namespace can be passed as a template argument for this purpose.

The interpolation function specified as a template argument also determines the integration mechanism used to calculate the cdf. If the NR::interpolateLogLog() function is specified, it is assumed that the pdf behaves as a power-law between any two grid points, and the integration is performed accordingly. In all other cases, piece-wise linear behavior is assumed and regular trapezium-rule integration is used.

◆ cdf2()

static double NR::cdf2 ( bool  loglog,
const Array xv,
Array pv,
Array Pv 
)
static

This function calculates the normalized cdf Pv for the given axis grid xv and corresponding unnormalized pdf pv. It also normalizes the incoming pdf pv and returns the normalization factor. This non-template function is not implemented inline (1) to avoid code-duplication and (2) to avoid propagating the dependencies (includes) of the implementation to all NR users.

If the loglog flag is false, piece-wise linear behavior of both the pdf and cdf is assumed and regular trapezium-rule integration is used. If the loglog flag is true, it is assumed that the pdf is linear in log-log space between any two grid points (equivalent to power-law behavior), and the integration is performed accordingly, as described below.

Consider the pdf values \(p_i\) and \(p_{i+1}\) at two consecutive grid points \(x_i\) and \(x_{i+1}\). Assuming power-law behavior, the pdf between these two grid points can be written as

\[ p(x) = p_i \left(\frac{x}{x_i}\right)^{\alpha_i}, \quad\mathrm{with}\; \alpha_i = \frac{\ln p_{i+1}/\ln p_i}{\ln x_{i+1}/\ln x_i} \]

The area under the curve is then

\[ \int_{x_i}^{x_{i+1}} p(x)\,\mathrm{d}x = \int_{x_i}^{x_{i+1}} p_i \left(\frac{x}{x_i}\right)^{\alpha_i}\mathrm{d}x = p_i x_i \;\mathrm{gln}\left(-\alpha_i, \frac{x_{i+1}}{x_i}\right) \]

where \(\mathrm{gln}(a,x)\) is the generalized logarithm defined in the description of the SpecialFunctions::gln() function.

◆ clampedResample()

template<double interpolateFunction>
static Array NR::clampedResample ( const Array xresv,
const Array xoriv,
const Array yoriv 
)
inlinestatic

This template function resamples the function values \(y_k\) defined on a grid \(x_k\) (both specified as arrays of the same length) onto an new grid \(x_l^*\). The result is returned as an array of function values \(y_l^*\) with the same length as the target grid. For new grid points that fall beyond the original grid, the function value is set to the value at the corresponding outer grid point, i.e. \(y_0\) or \(y_{n-1}\). For new grid points inside the original grid, the function value is interpolated using the function specified as template argument. The interpolation functions provided by this namespace can be passed as a template argument for this purpose.

◆ clampedValue()

template<double interpolateFunction>
static double NR::clampedValue ( double  x,
const Array xv,
const Array yv 
)
inlinestatic

This template function returns the interpolated function value \(y(x)\) given a value \(x\) and a tabulated version of the function \(y_k\) defined on a grid \(x_k\) (both specified as arrays of the same length). If \(x\) falls inside the grid, the \(y(x)\) value is interpolated between the neighboring grid points using the function specified as template argument. The interpolation functions provided by this namespace can be passed as a template argument for this purpose.

If \(x\) falls outside of the \(x_k\) grid, the \(y_k\) value at the corresponding outer grid point, i.e. \(y_0\) or \(y_{n-1}\) is returned as the result.

The function assumes that the specified arrays contain the same number of elements, that they each contain at least two elements, and that \(x_k\) elements are sorted in ascending order. If this is not the case, the result is undefined.

◆ interpolateLinLin()

static double NR::interpolateLinLin ( double  x,
double  x1,
double  x2,
double  f1,
double  f2 
)
inlinestatic

This function computes the interpolated value of a one-dimensional function, given its values at the edges of an interval. Both the axes coordinate \(x\) and the function value \(f(x)\) are interpolated linearly.

◆ interpolateLogLin()

static double NR::interpolateLogLin ( double  x,
double  x1,
double  x2,
double  f1,
double  f2 
)
inlinestatic

This function computes the interpolated value of a one-dimensional function, given its values at the edges of an interval. The axes coordinate \(x\) is interpolated logarithmically, and thus \(x_1\) and \(x_2\) must have positive values. If this is not the case, the function returns zero. The function value \(f(x)\) is interpolated linearly.

◆ interpolateLogLog()

static double NR::interpolateLogLog ( double  x,
double  x1,
double  x2,
double  f1,
double  f2 
)
inlinestatic

This function computes the interpolated value of a one-dimensional function, given its values at the edges of an interval. The coordinates on both axes are interpolated logarithmically, and thus all arguments must have positive values. If the function values \(f(x_1)\) and/or \(f(x_2)\) are not positive, the function returns zero. The other values are not verified.

◆ locate() [1/2]

static int NR::locate ( const Array xv,
double  x 
)
inlinestatic

The locate(), locateClip() and locateFail() functions perform a binary search on the ordered sequence of double values in an array. There are subtle differences between the various "locate" functions, as decribed below. All functions assume that the specified array contains at least two elements, and that all elements are sorted in ascending order. If this is not the case, the result is undefined. The algorithm is adapted from the Numerical Recipes in C++ handbook. The array passed as the first function argument specifies an ordered sequence \(\{x_i,\,i=0...N\}\) of \(N+1\) values \(x_i\), interpreted as borders defining a grid with \(N\) bins. There must be at least two values (defining a single bin). The second function argument specifies a query value \(x\). As long as the query is inside the range of the sequence, all functions return the zero-based index of the bin in which the query falls. Specifically, if \(x_0 \leq x < x_N\) then all functions return the integer number \(j\) such that \(x_j \leq x < x_{j+1}\). In addition, if \(x = x_N\) the function returns \(N-1\). In other words the rightmost border is always considered to be inside the last bin (and of course the leftmost border is inside the first bin). The return value of the various "locate" functions differs for query values outside of the range of the sequence, as listed in the table below.

Function \(x<x_0\) \(x>x_N\) Comments (note that there are \(N+1\) values)
locate() \(-1\) \(N\) Out-of-range values are indicated with a corresponding out-of-range index
locateClip() \(0\) \(N-1\) Out-of-range values are considered to be inside the corresponding outermost bin
locateFail() \(-1\) \(-1\) Out-of-range values are indicated with a negative index

◆ locate() [2/2]

template<typename T >
static int NR::locate ( const std::vector< T > &  xv,
const T &  x 
)
inlinestatic

This template function quickly performs a binary search on an ordered sequence of items provided as a std::vector<T>. It works for any item type T that implements the less-than operator (including the built-in numeric types). Given a sequence \(\{x_i,\,i=0...N-1\}\) and a query value \(x\), the function returns the integer number \(j\) such that \(x_j \leq x < x_{j+1}\), as long as \(x_0 \leq x < x_{N-1}\). In addition, if \(x = x_{N-1}\) the function returns \(N-2\); in other words the rightmost border is considered to be inside the last bin. If \(x<x_0\) the function returns \(-1\); if \(x>x_{N-1}\) the function returns \(N-1\). The function assumes that the provided sequence contains at least one element, and that the elements are sorted in ascending order. If this is not the case, the result is undefined. The algorithm is adapted from the Numerical Recipes in C++ handbook.

◆ locateBasicImpl()

static int NR::locateBasicImpl ( const Array xv,
double  x,
int  n 
)
inlinestatic

This function is an implementation detail and not intended for public use. See the description of the locate() function for more information.

◆ locateClip()

static int NR::locateClip ( const Array xv,
double  x 
)
inlinestatic

This function performs a binary search on the ordered sequence of double values in an array. See the description of the locate() function for more information.

◆ locateFail()

static int NR::locateFail ( const Array xv,
double  x 
)
inlinestatic

This function performs a binary search on the ordered sequence of double values in an array. See the description of the locate() function for more information.

◆ resample()

template<double interpolateFunction>
static Array NR::resample ( const Array xresv,
const Array xoriv,
const Array yoriv 
)
inlinestatic

This template function resamples the function values \(y_k\) defined on a grid \(x_k\) (both specified as arrays of the same length) onto an new grid \(x_l^*\). The result is returned as an array of function values \(y_l^*\) with the same length as the target grid. For new grid points that fall beyond the original grid, the function value is set to zero. For new grid points inside the original grid, the function value is interpolated using the function specified as template argument. The interpolation functions provided by this namespace can be passed as a template argument for this purpose.

◆ reverse()

static void NR::reverse ( Array xv,
size_t  blocksize = 1 
)
static

This function reverses blocks of values in the specified array. The number of values in the array must be an integer multiple of the specified block size. If not, the behavior is undefined.

◆ sort() [1/2]

static void NR::sort ( Array xv)
inlinestatic

This function sorts the values in the specified array.

◆ sort() [2/2]

template<typename T >
static void NR::sort ( std::vector< T > &  xv)
inlinestatic

This template function sorts a sequence of items given as a std::vector<T> where T is any built-in or user-defined type that implements the less-than operator (including the standard numeric types).

◆ unique()

template<typename T >
static void NR::unique ( std::vector< T > &  xv)
inlinestatic

This template function sorts and removes duplicates from a sequence of items given as a std::vector<T> where T is any built-in or user-defined type that implements the less-than operator (including the standard numeric types).

◆ value()

template<double interpolateFunction>
static double NR::value ( double  x,
const Array xv,
const Array yv 
)
inlinestatic

This template function returns the interpolated function value \(y(x)\) given a value \(x\) and a tabulated version of the function \(y_k\) defined on a grid \(x_k\) (both specified as arrays of the same length). If \(x\) falls inside the grid, the \(y(x)\) value is interpolated between the neighboring grid points using the function specified as template argument. The interpolation functions provided by this namespace can be passed as a template argument for this purpose.

If \(x\) falls outside of the \(x_k\) grid, zero is returned as the result.

The function assumes that the specified arrays contain the same number of elements, that they each contain at least two elements, and that \(x_k\) elements are sorted in ascending order. If this is not the case, the result is undefined.


The documentation for this class was generated from the following file: