Univariate Bases#

template<class Mixer>
class OrthogonalPolynomial : public Mixer#

Generic class to represent orthogonal polynomials.

An orthogonal polynomial has form

\[ p_{k}(x) = (a_k x + b_k) p_{k-1}(x) - c_k p_{k-2}(x) \]
where \(a_k,b_k,c_k\) are all given explicitly (three-term recurrence).

Public Functions

inline OrthogonalPolynomial(bool normalize = false)#
inline void EvaluateAll(double *output, unsigned int maxOrder, double x) const#
inline void EvaluateDerivatives(double *derivs, unsigned int maxDegree, double x) const#

Evaluates the derivative of every polynomial in this family up to degree maxOrder (inclusive). The results are stored in the memory pointed to by the derivs pointer.

inline void EvaluateDerivatives(double *vals, double *derivs, unsigned int maxOrder, double x) const#

Evaluates the value and derivative of every polynomial in this family up to degree maxOrder (inclusive). The results are stored in the memory pointed to by the derivs pointer.

inline void EvaluateSecondDerivatives(double *vals, double *derivs, double *secondDerivs, unsigned int maxOrder, double x) const#
inline double Evaluate(unsigned int const order, double const x) const#
inline double Derivative(unsigned int const order, double const x) const#
inline double SecondDerivative(unsigned int const order, double const x) const#
template<typename MemorySpace, typename SigmoidType = SigmoidTypeSpace::Logistic, typename EdgeType = SoftPlus>
class Sigmoid1d#

Class to represent univariate function space spanned by sigmoids. Order should generally be >= 4.

This class stores functions of the form

\[f_{k}(x;\mathbf{c},\mathbf{b},\mathbf{w})=b_0+b_1(x-c_1)+w_2g(-b_2(x-c_2))+w_3g(b_3(x-c_3))+\sum_{j=4}^kw_js(b_j(x-c_j))\]

where \(w_j,b_j\geq 0\) and \(s\) is a monotone increasing function. While it is expected that \(s\) is a sigmoid (e.g., Logistic or Erf function), any monotone function will allow this class to work as expected. Without loss of generality we set \(b_0,b_1\equiv 1\) and \(c_1\equiv0\)&#8212; for a linear basis, this will be equivalent to the class of functions presented above. If \(k\in\{0,1\}\), then we revert only to (increasing) linear functions. The function \(g\) should be an “edge” term where it is a monotone increasing function with \(\lim_{x\to-\infty}g(x)=0\) and \(\lim_{x\to\infty}g(x)=\infty\). The difference here between \(g\) and \(s\) is that \(s\) is generally expected to approach a constant value as \(x\to\infty\).

In the above expression, we denote \(\mathbf{c}\) as the “centers”, \(\mathbf{b}\) as the “width” or “bandwidth”, and \(\mathbf{w}\) as the “weights”. If we want a function class that works with up to \(n\) sigmoids, then we need to store two “center+width+weight” for the edge terms, then one “center+width+weight” for the first order, then two “center+width+weight”s for the second order (representing two sigmoids), then three “center+width+weight”s for the third order and so on. Generally, the weights will be uniform, but the centers and widths of these sigmoids can affect behavior dramatically. If performing approximation in \(L^2(\mu)\), a good heuristic is to place the weights at the quantiles of \(\mu\) and create widths that are half the distance to the nearest neighbor.

Currently the minimum order one can construct is 1, i.e., an affine map.

Template Parameters:
  • MemorySpace – Where the (nonlinear) parameters are stored

  • SigmoidType – Class defining eval, SigmoidTypeSpace

Public Functions

inline Sigmoid1d(Kokkos::View<double*, MemorySpace> centers, Kokkos::View<double*, MemorySpace> widths, Kokkos::View<double*, MemorySpace> weights)#

Construct a new Sigmoid 1d object.

Each input should be of length \(2 + n(n+1)/2\), where \(n\) is the number of sigmoids.

Parameters:
  • centers – Where to center the sigmoids

  • widths – How “wide” the basis functions should be

  • weights – How much to weight the sigmoids linearly

inline Sigmoid1d(Kokkos::View<double*, MemorySpace> centers, Kokkos::View<double*, MemorySpace> widths)#

Construct a new Sigmoid 1d object from centers and widths.

Each input should be of length \(2 + n(n+1)/2\), where \(n\) is the number of sigmoids.

Parameters:
  • centers

  • widths

inline void EvaluateAll(double *output, int max_order, double input) const#

Evaluate all sigmoids at one input.

Parameters:
  • output – Place to put the output (size max_order+1)

  • max_order – Maximum order of basis function to evaluate

  • input – Point to evaluate function

inline void EvaluateDerivatives(double *output, double *output_diff, int max_order, double input) const#

Evaluate all sigmoids up to given order and first derivatives.

Parameters:
  • output – Storage for sigmoid evaluation, size max_order+1

  • output_diff – Storage for sigmoid derivative, size max_order+1

  • max_order – Number of sigmoids to evaluate

  • input – Where to evaluate sigmoids

inline void EvaluateSecondDerivatives(double *output, double *output_diff, double *output_diff2, int max_order, double input) const#

Evaluate sigmoids up to given order and first+second derivatives.

Parameters:
  • output – Storage for sigmoid evaluation, size max_order+1

  • output_diff – Storage for sigmoid derivative, size max_order+1

  • output_diff2 – Storage for sigmoid 2nd deriv, size max_order+1

  • max_order – Maximum order of sigmoid to evaluate

  • input – Where to evaluate the sigmoids

inline int GetOrder() const#

Get the maximum order of this function class.

Returns:

int

Public Static Functions

static inline double LengthToOrder(int length)#

Given the length of centers, return the number of sigmoid levels.