Skip to content

Commit

Permalink
Merge pull request #340 from MeasureTransport/dannys4/trainDox
Browse files Browse the repository at this point in the history
Adding more doxygen docs, fix Docker
  • Loading branch information
dannys4 authored Jul 26, 2023
2 parents 7356892 + 738242a commit aa08ee2
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ RUN --mount=type=cache,target=/opt/conda/pkgs conda env create -f MParT_/.docker

SHELL ["conda", "run", "-n", "mpart", "/bin/bash", "-c"]

RUN git clone --depth=1 --branch 3.7.00 https://github.com/kokkos/kokkos.git && \
RUN git clone --depth=1 --branch 3.7.02 https://github.com/kokkos/kokkos.git && \
mkdir kokkos/build && \
cd kokkos/build && \
cmake \
Expand Down
45 changes: 26 additions & 19 deletions MParT/HermiteFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@

namespace mpart{

class HermiteFunction
/**
* @brief Class representing a Hermite function for multivariate expansions
* @details The \f$k\f$th Hermite function can be represented as
\f[ \psi_k(x) = \mathrm{He}_k(x)\exp(-x^2/4) \f]
* where \f$\mathrm{He}_k(x)\f$ is the \f$k\f$th probabilist Hermite polynomial.
*
*/
class HermiteFunction
{
public:

KOKKOS_INLINE_FUNCTION void EvaluateAll(double* output,
unsigned int maxOrder,
double x) const
{
{

output[0] = 1.0;

if(maxOrder>0){
output[1] = x;

if(maxOrder>1){
// Evaluate all of the physicist hermite polynomials
output[2] = std::pow(M_PI, -0.25) * std::exp(-0.5*x*x);
Expand All @@ -39,7 +46,7 @@ class HermiteFunction
double* derivs,
unsigned int maxOrder,
double x) const
{
{
vals[0] = 1.0;
derivs[0] = 0.0;

Expand All @@ -51,7 +58,7 @@ class HermiteFunction
// Evaluate all of the physicist hermite polynomials
polyBase.EvaluateDerivatives(&vals[2], &derivs[2], maxOrder-2, x);

// Add the scaling
// Add the scaling
const double baseScaling = std::pow(M_PI, -0.25) * std::exp(-0.5*x*x);
double scale;
double currFactorial = 1;
Expand All @@ -78,26 +85,26 @@ class HermiteFunction
double* derivs2,
unsigned int maxOrder,
double x) const
{
{
// Evaluate all of the physicist hermite polynomials
EvaluateDerivatives(vals, derivs, maxOrder, x);

derivs2[0] = 0.0;

if(maxOrder>0){
derivs2[1] = 0.0;

if(maxOrder>1){
// Add the scaling

// Add the scaling
for(unsigned int i=0; i<=maxOrder-2; ++i)
derivs2[i+2] = -(2.0*i + 1.0 - x*x)*vals[i+2];
}
}
}


KOKKOS_INLINE_FUNCTION double Evaluate(unsigned int const order,
KOKKOS_INLINE_FUNCTION double Evaluate(unsigned int const order,
double const x) const
{
if(order==0){
Expand All @@ -110,9 +117,9 @@ class HermiteFunction
}
}

KOKKOS_INLINE_FUNCTION double Derivative(unsigned int const order,
double const x) const
{
KOKKOS_INLINE_FUNCTION double Derivative(unsigned int const order,
double const x) const
{
if(order==0){
return 0.0;
}else if(order==1){
Expand All @@ -124,21 +131,21 @@ class HermiteFunction
}
}

KOKKOS_INLINE_FUNCTION double SecondDerivative(unsigned int const order,
KOKKOS_INLINE_FUNCTION double SecondDerivative(unsigned int const order,
double const x) const
{
{
if(order<2){
return 0;
return 0;
}else{
return -(2.0*order+1.0-x*x)*Evaluate(order-2, x);
}
}

private:
PhysicistHermite polyBase;

}; // class HermiteFunction

}

#endif
#endif
35 changes: 21 additions & 14 deletions MParT/LinearizedBasis.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

namespace mpart{

/**
* @brief Basis that is linear outside a given upper and lower bound.
* @details Implemented to be piecewise-defined mapping \f$F_{ab}[\psi]\f$, where \f$\psi\f$ is a real-valued univariate function. We define
* \f[ F_{ab}[\psi](x) = \begin{cases}\psi(x) & x\in[a,b]\\\psi(a)+(x-a)\psi^\prime(a) & x<a\\\psi(b) + (x-b)\psi^\prime(b) && x>b \f]
*
* @tparam OtherBasis type of basis inside bounds (e.g. OrthogonalPolynomial)
*/
template<typename OtherBasis>
class LinearizedBasis
{
Expand All @@ -30,8 +37,8 @@ class LinearizedBasis
KOKKOS_INLINE_FUNCTION void EvaluateAll(double* output,
unsigned int maxOrder,
double x) const
{
{

if(x<lb_){
polyBasis_.EvaluateAll(output, maxOrder, lb_);

Expand All @@ -55,21 +62,21 @@ class LinearizedBasis
double* derivs,
unsigned int maxOrder,
double x) const
{
{
if(x<lb_){

// Evaluate the underlying basis at the left linearization point
polyBasis_.EvaluateDerivatives(vals, derivs, maxOrder, lb_);

// Now update the basis values based on the derivative values at the left point
// Now update the basis values based on the derivative values at the left point
for(unsigned int i=0; i<=maxOrder; ++i)
vals[i] += derivs[i]*(x-lb_);

}else if(x>ub_){

// Evaluate the underlying basis at the right linearization point
polyBasis_.EvaluateDerivatives(vals, derivs, maxOrder, ub_);

// Now update the basis values based on the derivative values at the right point
for(unsigned int i=0; i<=maxOrder; ++i)
vals[i] += derivs[i]*(x-ub_);
Expand All @@ -85,12 +92,12 @@ class LinearizedBasis
double* derivs2,
unsigned int maxOrder,
double x) const
{
{
if(x<lb_){
EvaluateDerivatives(vals, derivs, maxOrder, x);
for(unsigned int i=0; i<=maxOrder; ++i)
derivs2[i] = 0.0;

}else if(x>ub_){
EvaluateDerivatives(vals, derivs, maxOrder, x);
for(unsigned int i=0; i<=maxOrder; ++i)
Expand All @@ -102,7 +109,7 @@ class LinearizedBasis
}


KOKKOS_INLINE_FUNCTION double Evaluate(unsigned int const order,
KOKKOS_INLINE_FUNCTION double Evaluate(unsigned int const order,
double const x) const
{
if(x<lb_){
Expand All @@ -114,9 +121,9 @@ class LinearizedBasis
}
}

KOKKOS_INLINE_FUNCTION double Derivative(unsigned int const order,
double const x) const
{
KOKKOS_INLINE_FUNCTION double Derivative(unsigned int const order,
double const x) const
{
if(x<lb_){
return polyBasis_.Derivative(order,lb_);
}else if(x>ub_){
Expand All @@ -126,9 +133,9 @@ class LinearizedBasis
}
}

KOKKOS_INLINE_FUNCTION double SecondDerivative(unsigned int const order,
KOKKOS_INLINE_FUNCTION double SecondDerivative(unsigned int const order,
double const x) const
{
{
if(x<lb_){
return 0.0;
}else if(x>ub_){
Expand All @@ -148,4 +155,4 @@ class LinearizedBasis

}

#endif
#endif
4 changes: 2 additions & 2 deletions MParT/MonotoneComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ namespace mpart{
The function \f$T\f$ is based on another (generally non-monotone) function \f$f : R^N\rightarrow R\f$ and a strictly positve function
\f$g : R\rightarrow R_{>0}\f$. Together, these functions define the monotone component $T$ through
$$
\f[
T(x_1, x_2, ..., x_D) = f(x_1,x_2,..., x_{D-1}, 0) + \int_0^{x_D} g\left( \partial_D f(x_1,x_2,..., x_{D-1}, t) \right) dt
$$
\f]
@tparam ExpansionType A class defining the function \f$f\f$. It must satisfy the cached parameterization concept.
@tparam PosFuncType A class defining the function \f$g\f$. This class must have `Evaluate` and `Derivative` functions accepting a double and returning a double. The MParT::SoftPlus and MParT::Exp classes in PositiveBijectors.h are examples of classes defining this interface.
Expand Down
11 changes: 7 additions & 4 deletions MParT/OrthogonalPolynomial.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@

namespace mpart{

/*
p_{k}(x) = (a_k x + b_k) p_{k-1}(x) - c_k p_{k-2}(x)
*/
/**
* @brief Generic class to represent orthogonal polynomials.
* @details An orthogonal polynomial has form
\f[ p_{k}(x) = (a_k x + b_k) p_{k-1}(x) - c_k p_{k-2}(x) \f]
* where \f(a_k,b_k,c_k\f) are all given explicitly (three-term recurrence).
*/
template<class Mixer>
class OrthogonalPolynomial : public Mixer
{
Expand All @@ -33,7 +36,7 @@ class OrthogonalPolynomial : public Mixer

if(normalize_){
for(unsigned int order=0; order<=maxOrder; ++order){
output[order] /= this->Normalization(order);
output[order] /= this->Normalization(order);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions MParT/ParameterizedFunctionBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace mpart {
virtual Kokkos::View<double*, MemorySpace>& Coeffs(){return this->savedCoeffs;};

/** @brief Set the internally stored view of coefficients.
@detail Performs a deep copy of the input coefficients to the internally stored coefficients.
@details Performs a deep copy of the input coefficients to the internally stored coefficients.
@param coeffs A view containing the coefficients to copy.
*/
virtual void SetCoeffs(Kokkos::View<const double*, MemorySpace> coeffs);
Expand All @@ -51,7 +51,7 @@ namespace mpart {
#endif

/** @brief Wrap the internal coefficient view around another view.
@detail Performs a shallow copy of the input coefficients to the internally stored coefficients.
@details Performs a shallow copy of the input coefficients to the internally stored coefficients.
If values in the view passed to this function are changed, the values will also change in the
internally stored view.
@param coeffs A view containing the coefficients we want to wrap.
Expand Down
15 changes: 12 additions & 3 deletions MParT/TrainMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,30 @@ namespace mpart {

/**
* @brief TrainOptions adds options for training your map,
* with fields largely based on nlopt settings. verbose is an integer
* where 0=nothing, 1=some diagnostics, 2=debugging
* with fields largely based on NLopt settings. For documentation
* of such fields, see <a href="https://nlopt.readthedocs.io/en/latest/NLopt_C-plus-plus_Reference/#stopping-criteria">NLOpt</a>.
*
*/
struct TrainOptions {
/** NLOpt: Optimization Algorithm to use */
std::string opt_alg = "LD_SLSQP";
/** NLOpt: Lower bound on optimizer */
double opt_stopval = -std::numeric_limits<double>::infinity();
/** NLOpt: Relative tolerance on function value change */
double opt_ftol_rel = 1e-3;
/** NLOpt: Absolute tolerance of function value change */
double opt_ftol_abs = 1e-3;
/** NLOpt: Relative tolerance of minimizer value change */
double opt_xtol_rel = 1e-4;
/** NLOpt: Absolute tolerance of minimizer value change */
double opt_xtol_abs = 1e-4;
/** NLOpt: Maximum number of evaluations of function to optimize */
int opt_maxeval = 1000;
/** NLOpt: Maximum amount of time to spend optimizing */
double opt_maxtime = std::numeric_limits<double>::infinity();
/** Verbosity of map training (1: verbose, 2: debug) */
int verbose = 0;

/**
* @brief Create a string representation of these training options (helpful for bindings)
*
Expand All @@ -47,7 +57,6 @@ struct TrainOptions {
/**
* @brief Function to train a map inplace given an objective and optimization options
*
* @tparam ObjectiveType
* @param map Map to optimize (inplace)
* @param objective MapObjective to optimize over
* @param options Options for optimizing the map
Expand Down
25 changes: 23 additions & 2 deletions MParT/TrainMapAdaptive.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,43 @@

namespace mpart {

// Options specifically for ATM algorithm, with map eval opts -> training opts-> ATM specific opts
/**
* @brief Both map and training options combined with special ATM options.
*
*/
struct ATMOptions: public MapOptions, public TrainOptions {
/** Maximum number of iterations that do not improve error */
unsigned int maxPatience = 10;
unsigned int maxSize = 10;
/** Maximum number of coefficients in final expansion (including ALL dimensions of map) */
unsigned int maxSize = std::numeric_limits<unsigned int>::infinity();
/** Multiindex representing the maximum degree in each input dimension */
MultiIndex maxDegrees;

/**
* @brief Create a string representation of these options.
*
* @return std::string
*/
std::string String() override {
std::string md_str = maxDegrees.String();
std::stringstream ss;
ss << MapOptions::String() << "\n" << TrainOptions::String() << "\n";
ss << "maxPatience = " << maxPatience << "\n";
ss << "maxSize = " << maxSize << "\n";
ss << "maxDegrees = " << maxDegrees.String();

return ss.str();
}
};

/**
* @brief Adaptively discover new terms in coefficient basis to add to map using the ATM algorithm of Baptista, et al. 2022.
*
* @tparam MemorySpace Device or host space to work in
* @param mset0 vector storing initial (minimal) guess of multiindex sets, corresponding to each dimension. Is changed in-place.
* @param objective What this map should be adapted to fits
* @return std::shared_ptr<ConditionalMapBase<MemorySpace>> New map according to specifications.
*/
template<typename MemorySpace>
std::shared_ptr<ConditionalMapBase<MemorySpace>> TrainMapAdaptive(std::vector<MultiIndexSet> &mset0,
std::shared_ptr<MapObjective<MemorySpace>> objective,
Expand Down
3 changes: 2 additions & 1 deletion docs/source/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ API Reference
multivariateexpansionworker
templateconcepts
utilities/initialization
utilities/serialization
utilities/serialization
maptraining
Loading

0 comments on commit aa08ee2

Please sign in to comment.