# 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 defines a family of basis functions $f_k(x)$ built from one-dimensional sigmoid functions. This family is index by an integer $$k$$, similar to the way the polynomial degree is used to index a class of orthogonal polynomials. In particular, the family of functions is defined by

\begin{split} \begin{aligned} f_0(x) & = 1 \\ f_1(x) & = x \\ f_2(x) & = -w_0 g(-b_0(x-c_0))\\ f_3(x) & = w_1 g(b_1(x-c_1)) \\ f_k(x) & = \sum_{j=1}^{N_k} w_{kj} s( b_{kj}(x-c_{kj})) \end{aligned} \end{split}
where $$c$$ represents the “center” of a single sigmoid function $s$, $$w_j,b_j\geq 0$$ are positive constants, $$s$$ is a monotone increasing function, and $$g$$ is an “edge” function satisfying $$\lim_{x\to-\infty}g(x)=0$$ and $$\lim_{x\to\infty}g(x)=\infty$$. 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.

The quantities $$w_{kj}$$, $$b_{kj}$$, and $$c_{kj}$$ are stored in unrolled vectors and indexed by an array with values $$\sigma_k$$ that store the index of $$c_{k0}$$ in the unrolled vector, much like the vector used to define sparse matrices stored in CSR format. For example if c is the unrolled vector of centers and startInds contains $$\sigma_k$$, then $$c_{kj}$$ is stored at c[startInds[k]+j-1].

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

• SigmoidType – Class defining eval, SigmoidTypeSpace

• EdgeType – Class defining the edge function type, e.g., SoftPlus

Public Functions

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

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

• startInds – Contains indices into “centers”, “widths”, and “weights” indicating where each term starts. This contains the $$\sigma_k$$ values mentioned above.

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

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 Sigmoid1d(Kokkos::View<double*, MemorySpace> centers, Kokkos::View<double*, MemorySpace> widths, Kokkos::View<double*, MemorySpace> weights, SigmoidSumSizeType sumType = SigmoidSumSizeType::Linear)#

Construct a new Sigmoid 1d object.

Each input should either be of length $$2 + n(n+1)/2$$ if sumType==Linear or of length $$2+n$$ if sumType==Constant, 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

• sumType – Indication of how the centers and widths should be interpreted: Either as separate basis functions if sumType==Constant or if sumType==Linear, it will assume that basis function k includes the sum of k-3 Sigmoid terms.

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

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

Each input should either be of length $$2 + n(n+1)/2$$ if sumType==Linear or of length $$2+n$$ if sumType==Constant, where $$n$$ is the number of sigmoids.

Parameters:
• centers – Where to center the sigmoids

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

• sumType – Indication of how the centers and widths should be interpreted: Either as separate basis functions if sumType==Constant or if sumType==Linear, it will assume that basis function k includes the sum of k-3 Sigmoid terms.

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 Kokkos::View<unsigned int*, MemorySpace> ConstructStartInds(unsigned int centerSize, SigmoidSumSizeType sumType)#

Constructs starting indices from the number of provided centers.

Parameters:
• centerSize – The number of centers provided to the constructor, i.e., centers.extent(0)

• sumType – The form of each term’s expansion.

static inline int ComputeNumSigmoids(int numCenters, SigmoidSumSizeType sumType)#

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