Skip to content
Draft
2 changes: 1 addition & 1 deletion MParT/BasisEvaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class BasisEvaluator<BasisHomogeneity::OffdiagHomogeneous,
* @param offdiag Evaluator for offdiagonal input elements
* @param diag Evaluator for diagonal input element
*/
BasisEvaluator(unsigned int dim, OffdiagEvaluatorType const &offdiag = OffdiagEvaluatorType(),
BasisEvaluator(unsigned int dim = 0, OffdiagEvaluatorType const &offdiag = OffdiagEvaluatorType(),
DiagEvaluatorType const &diag = DiagEvaluatorType())
: offdiag_(offdiag), diag_(diag), dim_(dim) {}

Expand Down
5 changes: 3 additions & 2 deletions MParT/MapFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,15 @@ namespace mpart{
*/
template<typename MemorySpace>
struct CompFactoryImpl{
typedef std::tuple<BasisTypes, bool, PosFuncTypes, QuadTypes> OptionsKeyType;
typedef std::tuple<BasisTypes, bool, PosFuncTypes, QuadTypes, bool> OptionsKeyType;
typedef std::function<std::shared_ptr<ConditionalMapBase<MemorySpace>>(FixedMultiIndexSet<MemorySpace> const&, MapOptions options)> FactoryFunctionType;
typedef std::map<OptionsKeyType, FactoryFunctionType> FactoryMapType;

static FactoryFunctionType GetFactoryFunction(MapOptions opts)
{
bool isLinearized = (!isinf(opts.basisLB)) ||(!isinf(opts.basisUB));
OptionsKeyType optionsKey(opts.basisType, isLinearized, opts.posFuncType, opts.quadType);
bool isCompact = opts.isCompact;
OptionsKeyType optionsKey(opts.basisType, isLinearized, opts.posFuncType, opts.quadType, isCompact);

auto factoryMap = GetFactoryMap();

Expand Down
5 changes: 4 additions & 1 deletion MParT/MapOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace mpart{
{
ProbabilistHermite,
PhysicistHermite,
HermiteFunctions
HermiteFunctions,
Legendre
};

enum class PosFuncTypes
Expand Down Expand Up @@ -76,6 +77,8 @@ namespace mpart{
double basisLB = -std::numeric_limits<double>::infinity();
double basisUB = std::numeric_limits<double>::infinity();

/** Whether the map should be compactly supported (cannot be linearized, only works with certain other map options */
bool isCompact = false;

/** The type of positive bijector used inside the monotonicity-guaranteeing integral
formulation.
Expand Down
279 changes: 175 additions & 104 deletions MParT/MonotoneComponent.h

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions MParT/MultivariateExpansionWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,27 @@ class MultivariateExpansionWorker
*/
KOKKOS_INLINE_FUNCTION unsigned int InputSize() const {return multiSet_.Length();};

/**
@brief Fills cache to evaluate f(0)
@details
@param polyCache A pointer to the start of the cache. This memory must be allocated before calling this function.
@param derivType

@see FillCache1, FillCache2
*/
KOKKOS_FUNCTION void FillCache0(double* polyCache,
DerivativeFlags::DerivativeType derivType) const
{
// Only allowed to evaluate, fail if you want derivatives; while possible this is a safety precaution
if(derivType == DerivativeFlags::None || derivType == DerivativeFlags::Parameters){
for(unsigned int d=0; d<dim_; ++d) {
basis1d_.EvaluateAll(d, &polyCache[startPos_(d)], maxDegrees_(d), 0.);
}
} else {
ProcAgnosticError<std::invalid_argument>("Cannot get derivatives for FillCache0");
}
}

/**
@brief Precomputes parts of the cache using all but the last component of the point, i.e., using only \f$x_1,x_2,\ldots,x_{d-1}\f$, not \f$x_d\f$.
@details
Expand Down
19 changes: 17 additions & 2 deletions MParT/OrthogonalPolynomial.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef ORTHOGONALPOLYNOMIAL_H
#define ORTHOGONALPOLYNOMIAL_H
#ifndef MPART_ORTHOGONALPOLYNOMIAL_H
#define MPART_ORTHOGONALPOLYNOMIAL_H

#include <Kokkos_Core.hpp>
#include <cmath>
Expand Down Expand Up @@ -327,6 +327,21 @@ class PhysicistHermiteMixer{
typedef OrthogonalPolynomial<PhysicistHermiteMixer> PhysicistHermite;


class ShiftedLegendreMixer{ // Polynomials orthogonal on U[0,1]
public:
KOKKOS_INLINE_FUNCTION double Normalization(unsigned int polyOrder) const { return 1./(2*polyOrder+1);}
protected:
// \f[ p_{k}(x) = (a_k x + b_k) p_{k-1}(x) - c_k p_{k-2}(x) \f]
KOKKOS_INLINE_FUNCTION double ak(unsigned int k) const {return 2. * (2. * k - 1)/k;}
KOKKOS_INLINE_FUNCTION double bk(unsigned int k) const {return -(2. * k - 1)/k;}
KOKKOS_INLINE_FUNCTION double ck(unsigned int k) const {return (k-1.)/k;}
KOKKOS_INLINE_FUNCTION double phi0(double) const {return 1.0;}
KOKKOS_INLINE_FUNCTION double phi1(double x) const {return 2*x-1;}
KOKKOS_INLINE_FUNCTION double phi1_deriv(double) const{return 2.0;};
};

using ShiftedLegendre = OrthogonalPolynomial<ShiftedLegendreMixer>;

} // namespace mpart

#endif
155 changes: 155 additions & 0 deletions MParT/UnivariateBases.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#ifndef MPART_UNIVARIATEBASES_H
#define MPART_UNIVARIATEBASES_H

#include <Kokkos_Core.hpp>
#include <cmath>

#include <iostream>

#include "MParT/Utilities/MathFunctions.h"

namespace mpart{

/**
* @brief Generic class to represent functions
* \f[p_0(x)\equiv 1,p_k(x)=sin(2\pi k x)\f]
*/
class SineBasis
{
public:
static constexpr double PI2 = 2*M_PI;

/* Evaluates all polynomials up to a specified order. */
KOKKOS_FUNCTION void EvaluateAll(double* output,
unsigned int maxOrder,
double x) const
{
output[0] = 1.;

double sin_x, cos_x, cos_kx;

if(maxOrder>0) {
sin_x = sin(PI2*x);
cos_x = cos(PI2*x);
cos_kx = cos_x;
output[1] = sin_x;
}

for(unsigned int order=2; order<=maxOrder; ++order) {
output[order] = output[order-1]*cos_x + cos_kx*sin_x;
cos_kx = cos_kx*cos_x - output[order-1]*sin_x;
}
}

/** 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.
*/
KOKKOS_FUNCTION void EvaluateDerivatives(double* derivs,
unsigned int maxOrder,
double x) const
{
derivs[0] = 0.;

double sin_x, cos_x, sin_kx;

if(maxOrder>0) {
sin_x = sin(PI2*x);
cos_x = cos(PI2*x);
sin_kx = sin_x;
derivs[1] = cos_x;
}

// d_x sin(2pi k x) = 2pi k cos(2pi k x)
for(unsigned int order=2; order<=maxOrder; ++order) {
derivs[order] = derivs[order-1]*cos_x - sin_kx*sin_x;
sin_kx = sin_kx*cos_x + derivs[order-1]*sin_x;
derivs[order-2] *= PI2*(order-2);
}
if(maxOrder>0) derivs[maxOrder-1] *= PI2*(maxOrder-1);
derivs[maxOrder] *= PI2*(maxOrder);
}

/** 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.
*/
KOKKOS_FUNCTION void EvaluateDerivatives(double* vals,
double* derivs,
unsigned int maxOrder,
double x) const
{
vals[0] = 1.;
derivs[0] = 0.;

double sin_x, cos_x;

if(maxOrder>0) {
sin_x = sin(PI2*x);
cos_x = cos(PI2*x);
vals[1] = sin_x;
derivs[1] = cos_x;
}

for(unsigned int order=2; order<=maxOrder; ++order) {
vals[order] = vals[order-1]*cos_x + derivs[order-1]*sin_x;
derivs[order] = derivs[order-1]*cos_x - vals[order-1]*sin_x;
derivs[order-2] *= PI2*(order-2);
}
if(maxOrder>0) derivs[maxOrder-1] *= PI2*(maxOrder-1);
derivs[maxOrder] *= PI2*(maxOrder);
}

KOKKOS_FUNCTION void EvaluateSecondDerivatives(double* vals,
double* derivs,
double* secondDerivs,
unsigned int maxOrder,
double x) const
{
vals[0] = 1.;
derivs[0] = 0.;
secondDerivs[0] = 0.;

double sin_x, cos_x;

if(maxOrder>0) {
sin_x = sin(PI2*x);
cos_x = cos(PI2*x);
vals[1] = sin_x;
derivs[1] = cos_x;
secondDerivs[1] = -PI2*PI2*vals[1];
}

for(unsigned int order=2; order<=maxOrder; ++order) {
vals[order] = vals[order-1]*cos_x + derivs[order-1]*sin_x;
derivs[order] = derivs[order-1]*cos_x - vals[order-1]*sin_x;
derivs[order-2] *= PI2*(order-2);
secondDerivs[order] = -(PI2*order)*(PI2*order)*vals[order];
}
if(maxOrder > 0) derivs[maxOrder-1] *= PI2*(maxOrder-1);
derivs[maxOrder] *= PI2*(maxOrder);
}



KOKKOS_FUNCTION double Evaluate(unsigned int const order,
double const x) const
{
return order == 0 ? 1. : sin(PI2*order*x);
}

KOKKOS_FUNCTION double Derivative(unsigned int const order,
double const x) const
{
return order == 0 ? 0. : PI2*order*cos(PI2*order*x);
}

KOKKOS_FUNCTION double SecondDerivative(unsigned int const order,
double const x) const
{
return -(PI2*order)*(PI2*order)*sin(PI2*order*x);
}

};

} // namespace mpart

#endif
6 changes: 4 additions & 2 deletions MParT/Utilities/Serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

// A macro that can be used for registering the various MonotoneComponent classes with CEREAL
// This macro is used in the MapFactoryImpl*.cpp files
#define REGISTER_MONO_COMP(BASIS_HOMOGENEITY, BASIS_TYPE, POS_TYPE, QUAD_TYPE, MEMORY_SPACE) \
CEREAL_REGISTER_TYPE(mpart::MonotoneComponent<mpart::MultivariateExpansionWorker<mpart::BasisEvaluator<BASIS_HOMOGENEITY, BASIS_TYPE>, MEMORY_SPACE>, mpart::POS_TYPE, mpart::QUAD_TYPE<MEMORY_SPACE>, MEMORY_SPACE>)
#define REGISTER_HOMOGENEOUS_MONO_COMP(BASIS_TYPE, POS_TYPE, QUAD_TYPE, MEMORY_SPACE, IS_COMPACT) \
CEREAL_REGISTER_TYPE(mpart::MonotoneComponent<mpart::MultivariateExpansionWorker<mpart::BasisEvaluator<BasisHomogeneity::Homogeneous, BASIS_TYPE>, MEMORY_SPACE>, mpart::POS_TYPE, mpart::QUAD_TYPE<MEMORY_SPACE>, MEMORY_SPACE, IS_COMPACT>)
#define REGISTER_OFFDIAGHOMOGENEOUS_MONO_COMP(BASIS_TYPE_1, BASIS_TYPE_2, RECTIFIER, POS_TYPE, QUAD_TYPE, MEMORY_SPACE, IS_COMPACT) \
CEREAL_REGISTER_TYPE(mpart::MonotoneComponent<mpart::MultivariateExpansionWorker<mpart::BasisEvaluator<BasisHomogeneity::OffdiagHomogeneous, Kokkos::pair<BASIS_TYPE_1, BASIS_TYPE_2>, RECTIFIER>, MEMORY_SPACE>, mpart::POS_TYPE, mpart::QUAD_TYPE<MEMORY_SPACE>, MEMORY_SPACE, IS_COMPACT>)


namespace cereal {
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ target_sources(mpart
MapFactoryImpl16.cpp
MapFactoryImpl17.cpp
MapFactoryImpl18.cpp
MapFactoryImpl19.cpp

${MPART_OPT_FILES}
Initialization.cpp
Expand Down
33 changes: 22 additions & 11 deletions src/MapFactoryImpl1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using namespace mpart;


template<typename MemorySpace, typename PosFuncType>
template<typename MemorySpace, typename PosFuncType, bool isCompact>
std::shared_ptr<ConditionalMapBase<MemorySpace>> CreateComponentImpl_Phys_ACC(FixedMultiIndexSet<MemorySpace> const& mset, MapOptions opts)
{
BasisEvaluator<BasisHomogeneity::Homogeneous,PhysicistHermite> basis1d(opts.basisNorm);
Expand All @@ -24,27 +24,38 @@ std::shared_ptr<ConditionalMapBase<MemorySpace>> CreateComponentImpl_Phys_ACC(Fi
MultivariateExpansionWorker<BasisEvaluator<BasisHomogeneity::Homogeneous,PhysicistHermite>,MemorySpace> expansion(mset, basis1d);
std::shared_ptr<ConditionalMapBase<MemorySpace>> output;

output = std::make_shared<MonotoneComponent<decltype(expansion), PosFuncType, decltype(quad), MemorySpace>>(expansion, quad, opts.contDeriv, opts.nugget);
output = std::make_shared<MonotoneComponent<decltype(expansion), PosFuncType, decltype(quad), MemorySpace, isCompact>>(expansion, quad, opts.contDeriv, opts.nugget);

Kokkos::View<const double*, MemorySpace> coeffs = Kokkos::View<double*,MemorySpace>("Component Coefficients", mset.Size());
output->SetCoeffs(coeffs);
return output;
}

static auto reg_host_phys_acc_exp = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, Exp>));
static auto reg_host_phys_acc_splus = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, SoftPlus>));
static auto reg_host_phys_acc_exp = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis, false), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, Exp, false>));
static auto reg_host_phys_acc_splus = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis, false), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, SoftPlus, false>));
#if defined(MPART_ENABLE_GPU)
static auto reg_device_phys_acc_exp = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, Exp>));
static auto reg_device_phys_acc_splus = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, SoftPlus>));
static auto reg_device_phys_acc_exp = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis, false), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, Exp, false>));
static auto reg_device_phys_acc_splus = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis, false), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, SoftPlus, false>));
#endif

static auto reg_host_phys_acc_exp_compact = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis, true), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, Exp, true>));
static auto reg_host_phys_acc_splus_compact = mpart::MapFactory::CompFactoryImpl<Kokkos::HostSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis, true), CreateComponentImpl_Phys_ACC<Kokkos::HostSpace, SoftPlus, true>));
#if defined(MPART_ENABLE_GPU)
static auto reg_device_phys_acc_exp_compact = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::Exp, QuadTypes::AdaptiveClenshawCurtis, true), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, Exp, true>));
static auto reg_device_phys_acc_splus_compact = mpart::MapFactory::CompFactoryImpl<mpart::DeviceSpace>::GetFactoryMap()->insert(std::make_pair(std::make_tuple(BasisTypes::PhysicistHermite, false, PosFuncTypes::SoftPlus, QuadTypes::AdaptiveClenshawCurtis, true), CreateComponentImpl_Phys_ACC<mpart::DeviceSpace, SoftPlus, true>));
#endif

#if defined(MPART_HAS_CEREAL)
REGISTER_MONO_COMP(BasisHomogeneity::Homogeneous, PhysicistHermite, Exp, AdaptiveClenshawCurtis, Kokkos::HostSpace)
REGISTER_MONO_COMP(BasisHomogeneity::Homogeneous, PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, Kokkos::HostSpace)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, Exp, AdaptiveClenshawCurtis, Kokkos::HostSpace, false)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, Kokkos::HostSpace, false)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, Exp, AdaptiveClenshawCurtis, Kokkos::HostSpace, true)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, Kokkos::HostSpace, true)
#if defined(MPART_ENABLE_GPU)
REGISTER_MONO_COMP(BasisHomogeneity::Homogeneous, PhysicistHermite, Exp, AdaptiveClenshawCurtis, mpart::DeviceSpace)
REGISTER_MONO_COMP(BasisHomogeneity::Homogeneous, PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, mpart::DeviceSpace)
#endif
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, Exp, AdaptiveClenshawCurtis, mpart::DeviceSpace, false)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, mpart::DeviceSpace, false)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, Exp, AdaptiveClenshawCurtis, mpart::DeviceSpace, true)
REGISTER_HOMOGENEOUS_MONO_COMP(PhysicistHermite, SoftPlus, AdaptiveClenshawCurtis, mpart::DeviceSpace, true)
#endif

CEREAL_REGISTER_DYNAMIC_INIT(mpartInitMapFactory1)
#endif
Loading