From b5b94a40dccfee9f5a289ed30f53596374df0978 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Wed, 27 May 2020 20:43:25 -0600 Subject: [PATCH 01/21] Moved interpolant coefficients into an aligned struct with aligned elements --- src/RngDriver.cpp | 35 +++++++++++++++++++ ...ArmadilloPrecomputedInterpolationTable.cpp | 16 +++++---- ...ArmadilloPrecomputedInterpolationTable.hpp | 1 + .../UniformConstantTaylorTable.hpp | 1 + src/table_types/UniformCubicHermiteTable.cpp | 15 ++++---- src/table_types/UniformCubicHermiteTable.hpp | 3 +- ...formCubicPrecomputedInterpolationTable.cpp | 15 ++++---- ...formCubicPrecomputedInterpolationTable.hpp | 1 + src/table_types/UniformCubicTaylorTable.cpp | 22 ++++++------ src/table_types/UniformCubicTaylorTable.hpp | 1 + .../UniformFailureProofCubicPITable.cpp | 15 ++++---- .../UniformFailureProofCubicPITable.hpp | 1 + .../UniformFailureProofLinearPITable.cpp | 11 +++--- .../UniformFailureProofLinearPITable.hpp | 1 + .../UniformLinearInterpolationTable.cpp | 12 +++---- .../UniformLinearInterpolationTable.hpp | 1 + ...ormLinearPrecomputedInterpolationTable.cpp | 11 +++--- ...ormLinearPrecomputedInterpolationTable.hpp | 1 + src/table_types/UniformLinearTaylorTable.cpp | 14 ++++---- src/table_types/UniformLinearTaylorTable.hpp | 1 + src/table_types/UniformLookupTable.hpp | 9 ++++- src/table_types/UniformPadeTable.cpp | 23 ++++++------ src/table_types/UniformPadeTable.hpp | 2 ++ ...QuadraticPrecomputedInterpolationTable.cpp | 22 ++++++------ ...QuadraticPrecomputedInterpolationTable.hpp | 1 + .../UniformQuadraticTaylorTable.cpp | 20 +++++------ .../UniformQuadraticTaylorTable.hpp | 1 + 27 files changed, 154 insertions(+), 102 deletions(-) create mode 100644 src/RngDriver.cpp diff --git a/src/RngDriver.cpp b/src/RngDriver.cpp new file mode 100644 index 0000000..319da3e --- /dev/null +++ b/src/RngDriver.cpp @@ -0,0 +1,35 @@ +#include + +#include "RngInterface.hpp" +#include "StdRng.hpp" + +// a dummy version of ImplementationComparator. Just samples points based on the +// type of RngInterface it's given +class Driver{ + RngInterface *mp_sampler; + public: + Driver(RngInterface *inRng=nullptr, unsigned int seed=2020) { + mp_sampler=inRng; + if(mp_sampler==nullptr) + mp_sampler=std::move(new StdRng> + (new std::uniform_real_distribution(0.0, 1.0))); + mp_sampler->init(seed); + } + + double samplePoints(){return mp_sampler->getPt();} + + ~Driver(){} +}; + + +int main(){ + // sample from a normal distribution + StdRng> standardRNG(new std::normal_distribution(-5.0, 1.0)); + Driver driver1(&standardRNG); + std::cout << driver1.samplePoints() << std::endl; + + // sample from the default uniform distribution + Driver driver2; + std::cout << driver2.samplePoints() << std::endl; +} + diff --git a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp index d19fd71..4e62c1d 100644 --- a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp @@ -2,6 +2,8 @@ #include "UniformArmadilloPrecomputedInterpolationTable.hpp" #include +#define SOLVE_OPTS arma::solve_opts::refine + // Template substitution happens way after the preprocessor does it's work so // we'll register all the available template values this way template<>REGISTER_ULUT_IMPL(UniformArmadilloPrecomputedInterpolationTable<4>); @@ -17,7 +19,7 @@ UniformArmadilloPrecomputedInterpolationTable::UniformArmadilloPrecomputedInt m_name = "UniformArmadilloPrecomputedInterpolationTable<" + std::to_string(N) + ">"; m_order = N+1; // take N as the degree of the polynomial interpolant which is of order N+1 m_numTableEntries = (N+1)*(m_numIntervals+1); - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* build the vandermonde system for finding the interpolating polynomial's coefficients */ arma::mat Van = arma::ones(N+1, N+1); @@ -30,7 +32,7 @@ UniformArmadilloPrecomputedInterpolationTable::UniformArmadilloPrecomputedInt arma::lu(L,U,P,Van); /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial[m_numTableEntries]); for (int ii=0;ii::UniformArmadilloPrecomputedInt // make y the coefficients of the polynomial interpolant y = solve(trimatu(U), solve(trimatl(L), P*y)); + //y = arma::solve(Van, y, SOLVE_OPTS); // move this back into the m_table array for (unsigned int k=0; k::operator()(double x) unsigned x0 = (unsigned) dx; // value of table entries around x position dx -= x0; - x0 *= N+1; // general degree horners method, evaluated from the inside out. - double sum = dx*m_table[x0+N]; + double sum = dx*m_table[x0].coefs[N]; for (int k=N-1; k>0; k--) - sum = dx*(m_table[x0+k] + sum); - return m_table[x0]+sum; + sum = dx*(m_table[x0].coefs[k] + sum); + return m_table[x0].coefs[0]+sum; } // declaration of the available values for the template N diff --git a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp index 2406210..5233721 100644 --- a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp +++ b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp @@ -21,6 +21,7 @@ class UniformArmadilloPrecomputedInterpolationTable final : public UniformLookup { REGISTER_ULUT(UniformArmadilloPrecomputedInterpolationTable); + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformArmadilloPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformConstantTaylorTable.hpp b/src/table_types/UniformConstantTaylorTable.hpp index fd34c06..7c8648f 100644 --- a/src/table_types/UniformConstantTaylorTable.hpp +++ b/src/table_types/UniformConstantTaylorTable.hpp @@ -16,6 +16,7 @@ class UniformConstantTaylorTable final : public UniformLookupTable { REGISTER_ULUT(UniformConstantTaylorTable); + __attribute__((aligned)) std::unique_ptr m_table; public: UniformConstantTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformCubicHermiteTable.cpp b/src/table_types/UniformCubicHermiteTable.cpp index 097daa5..bf42471 100644 --- a/src/table_types/UniformCubicHermiteTable.cpp +++ b/src/table_types/UniformCubicHermiteTable.cpp @@ -11,10 +11,10 @@ UniformCubicHermiteTable::UniformCubicHermiteTable(EvaluationFunctor[m_numTableEntries]); for (int ii=0; iideriv(x); const double y1 = (*mp_func)(x+m_stepSize); const double m1 = mp_func->deriv(x+m_stepSize); - m_table[4*ii] = y0; - m_table[4*ii+1] = m_stepSize*m0; - m_table[4*ii+2] = -3*y0+3*y1-(2*m0+m1)*m_stepSize; - m_table[4*ii+3] = 2*y0-2*y1+(m0+m1)*m_stepSize; + m_table[ii].coefs[0] = y0; + m_table[ii].coefs[1] = m_stepSize*m0; + m_table[ii].coefs[2] = -3*y0+3*y1-(2*m0+m1)*m_stepSize; + m_table[ii].coefs[3] = 2*y0-2*y1+(m0+m1)*m_stepSize; } } @@ -36,7 +36,6 @@ double UniformCubicHermiteTable::operator()(double x) // index of previous table entry unsigned x0 = (unsigned) dx; dx -= x0; - x0 *= 4; // linear interpolation - return m_table[x0]+dx*(m_table[x0+1]+dx*(m_table[x0+2]+dx*m_table[x0+3])); + return m_table[x0].coefs[0]+dx*(m_table[x0].coefs[1]+dx*(m_table[x0].coefs[2]+dx*m_table[x0].coefs[3])); } diff --git a/src/table_types/UniformCubicHermiteTable.hpp b/src/table_types/UniformCubicHermiteTable.hpp index ddb112f..5dc26ce 100644 --- a/src/table_types/UniformCubicHermiteTable.hpp +++ b/src/table_types/UniformCubicHermiteTable.hpp @@ -1,5 +1,5 @@ /* - Linear Interpolation LUT with uniform sampling (precomputed coefficients) + Cubic Interpolation LUT with uniform sampling (precomputed coefficients) Usage example: UniformCubicHermiteTable look(&function,0,10,0.0001); @@ -17,6 +17,7 @@ class UniformCubicHermiteTable final : public UniformLookupTable { REGISTER_ULUT(UniformCubicHermiteTable); + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformCubicHermiteTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp b/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp index 96f2cab..03fb0b5 100644 --- a/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp @@ -11,10 +11,10 @@ UniformCubicPrecomputedInterpolationTable::UniformCubicPrecomputedInterpolationT m_name = STR(IMPL_NAME); m_order = 4; m_numTableEntries = 4*(m_numIntervals+1); - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<4,32>[m_numTableEntries]); for (int ii=0;ii[]> m_table; public: UniformCubicPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformCubicTaylorTable.cpp b/src/table_types/UniformCubicTaylorTable.cpp index 1c1161b..fee418e 100644 --- a/src/table_types/UniformCubicTaylorTable.cpp +++ b/src/table_types/UniformCubicTaylorTable.cpp @@ -9,18 +9,18 @@ UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctor[m_numTableEntries]); for (int ii=0;iideriv(x); - m_table[4*ii+2] = func->deriv2(x)/2; - m_table[4*ii+3] = func->deriv3(x)/6; + m_table[ii].coefs[0] = (*func)(x); + m_table[ii].coefs[1] = func->deriv(x); + m_table[ii].coefs[2] = func->deriv2(x)/2; + m_table[ii].coefs[3] = func->deriv3(x)/6; } } @@ -30,8 +30,8 @@ double UniformCubicTaylorTable::operator()(double x) double dx = (x-m_minArg); double x1r = dx/m_stepSize+0.5; // index of previous table entry - unsigned x1 = 4*((unsigned) x1r); - dx -= x1*m_stepSize/4; - // linear Taylor series from grid point below x - return m_table[x1]+dx*(m_table[x1+1]+dx*(m_table[x1+2]+dx*m_table[x1+3])); + unsigned x1 = (unsigned) x1r; + dx -= x1*m_stepSize; + // Cubic Taylor series from grid point below x + return m_table[x1].coefs[0]+dx*(m_table[x1].coefs[1]+dx*(m_table[x1].coefs[2]+dx*m_table[x1].coefs[3])); } diff --git a/src/table_types/UniformCubicTaylorTable.hpp b/src/table_types/UniformCubicTaylorTable.hpp index 9ca2c51..b8254ba 100644 --- a/src/table_types/UniformCubicTaylorTable.hpp +++ b/src/table_types/UniformCubicTaylorTable.hpp @@ -16,6 +16,7 @@ class UniformCubicTaylorTable final : public UniformLookupTable { REGISTER_ULUT(UniformCubicTaylorTable); + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformCubicTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformFailureProofCubicPITable.cpp b/src/table_types/UniformFailureProofCubicPITable.cpp index e553494..1a9b4bd 100644 --- a/src/table_types/UniformFailureProofCubicPITable.cpp +++ b/src/table_types/UniformFailureProofCubicPITable.cpp @@ -32,10 +32,10 @@ UniformFailureProofCubicPITable::UniformFailureProofCubicPITable(EvaluationFunct m_name = STR(IMPL_NAME); m_order = 4; m_numTableEntries = 4*(m_numIntervals+1); - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<4,32>[m_numTableEntries]); for (int ii=0;ii m_args; #endif + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformFailureProofCubicPITable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformFailureProofLinearPITable.cpp b/src/table_types/UniformFailureProofLinearPITable.cpp index ceeba1e..fea5b87 100644 --- a/src/table_types/UniformFailureProofLinearPITable.cpp +++ b/src/table_types/UniformFailureProofLinearPITable.cpp @@ -32,16 +32,16 @@ UniformFailureProofLinearPITable::UniformFailureProofLinearPITable(EvaluationFun m_name = STR(IMPL_NAME); m_order = 2; m_numTableEntries = 2*m_numIntervals+2; - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<2,16>[m_numTableEntries]); for (int ii=0;ii m_args; #endif + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformFailureProofLinearPITable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformLinearInterpolationTable.cpp b/src/table_types/UniformLinearInterpolationTable.cpp index 5fb4f53..20d7907 100644 --- a/src/table_types/UniformLinearInterpolationTable.cpp +++ b/src/table_types/UniformLinearInterpolationTable.cpp @@ -10,14 +10,14 @@ UniformLinearInterpolationTable::UniformLinearInterpolationTable(EvaluationFunct m_name = STR(IMPL_NAME); m_order = 2; m_numTableEntries = m_numIntervals; - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<1,8>[m_numTableEntries]); for (int ii=0; ii[]> m_table; public: UniformLinearInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp b/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp index ea0ac06..e61d359 100644 --- a/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp @@ -11,16 +11,16 @@ UniformLinearPrecomputedInterpolationTable::UniformLinearPrecomputedInterpolatio m_name = STR(IMPL_NAME); m_order = 2; m_numTableEntries = 2*m_numIntervals+2; - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<2,16>[m_numTableEntries]); for (int ii=0;ii[]> m_table; public: UniformLinearPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformLinearTaylorTable.cpp b/src/table_types/UniformLinearTaylorTable.cpp index 1c140d5..149a426 100644 --- a/src/table_types/UniformLinearTaylorTable.cpp +++ b/src/table_types/UniformLinearTaylorTable.cpp @@ -10,15 +10,15 @@ UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor[m_numTableEntries]); for (int ii=0; iideriv(x); + m_table[ii].coefs[0] = (*mp_func)(x); + m_table[ii].coefs[1] = mp_func->deriv(x); } } @@ -28,8 +28,8 @@ double UniformLinearTaylorTable::operator()(double x) double dx = (x-m_minArg); double x1r = dx/m_stepSize+0.5; // index of previous table entry - unsigned x1 = 2*((unsigned) x1r); - dx -= 0.5*x1*m_stepSize; + unsigned x1 = (unsigned) x1r; + dx -= x1*m_stepSize; // linear Taylor series from grid point below x - return m_table[x1]+m_table[x1+1]*dx; + return m_table[x1].coefs[0]+m_table[x1].coefs[1]*dx; } diff --git a/src/table_types/UniformLinearTaylorTable.hpp b/src/table_types/UniformLinearTaylorTable.hpp index 590c8a9..c3e0c9c 100644 --- a/src/table_types/UniformLinearTaylorTable.hpp +++ b/src/table_types/UniformLinearTaylorTable.hpp @@ -16,6 +16,7 @@ class UniformLinearTaylorTable final : public UniformLookupTable { REGISTER_ULUT(UniformLinearTaylorTable); + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformLinearTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformLookupTable.hpp b/src/table_types/UniformLookupTable.hpp index 57c3617..bef8053 100644 --- a/src/table_types/UniformLookupTable.hpp +++ b/src/table_types/UniformLookupTable.hpp @@ -17,11 +17,18 @@ struct UniformLookupTableParameters double stepSize = 1; }; +template +struct alignas(ALIGN) polynomial{ + double coefs[NUM_COEFS]; +}; + class UniformLookupTable : public EvaluationImplementation { protected: - std::unique_ptr m_grid, m_table; // pointers to grid and evaluation data + std::unique_ptr m_grid; // pointers to grid and evaluation data + // a LUT array needs to be provided by each implementation + unsigned m_numIntervals; // sizes of grid and evaluation data unsigned m_numTableEntries; diff --git a/src/table_types/UniformPadeTable.cpp b/src/table_types/UniformPadeTable.cpp index c4948dc..a969c19 100644 --- a/src/table_types/UniformPadeTable.cpp +++ b/src/table_types/UniformPadeTable.cpp @@ -16,7 +16,7 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, m_name = "UniformPadeTable<" + std::to_string(M) + "," + std::to_string(N) + ">"; m_order = M+N+1; m_numTableEntries = (M+N+1)*(m_numIntervals+1); - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; // assign the first 7 derivatives to the derivs array for easy enumeration derivs[0]=&EvaluationFunctor::deriv; @@ -28,7 +28,7 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, derivs[6]=&EvaluationFunctor::deriv7; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial[m_numTableEntries]); for (int ii=0;ii::UniformPadeTable(EvaluationFunctor *func, // find the coefficients of Q. arma::mat Q = arma::null(T.rows(M+1, M+N)); + // Need to learn more about Pade approx. to see if this if statement is useful if(Q.n_cols > 1){ // Arma could throw an exception if Q isn't a vector but this is more descriptive throw "Pade table of order [" + std::to_string(M) + "/" + std::to_string(N) + "] does not exist."; return; @@ -59,10 +60,10 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, // move these coefs into m_table for (unsigned int k=0; k::operator()(double x) double dx = (x-m_minArg); double x1r = dx/m_stepSize+0.5; // index of previous table entry - unsigned x1 = (M+N+1)*((unsigned) x1r); - dx -= x1*m_stepSize/(M+N+1); + unsigned x1 = ((unsigned) x1r); + dx -= x1*m_stepSize; // general degree horners method, evaluated from the inside out. - double P = dx*m_table[x1+M]; + double P = dx*m_table[x1].coefs[M]; for (int k=M-1; k>0; k--) - P = dx*(m_table[x1+k] + P); - P = P+m_table[x1]; + P = dx*(m_table[x1].coefs[k] + P); + P = P+m_table[x1].coefs[0]; - double Q = dx*m_table[x1+M+N]; + double Q = dx*m_table[x1].coefs[M+N]; for (int k=N-1; k>0; k--) - Q = dx*(m_table[x1+M+k] + Q); + Q = dx*(m_table[x1].coefs[M+k] + Q); Q = 1+Q; // the constant term in Q will always be 1 return P/Q; diff --git a/src/table_types/UniformPadeTable.hpp b/src/table_types/UniformPadeTable.hpp index c4bf38e..c4f3cb3 100644 --- a/src/table_types/UniformPadeTable.hpp +++ b/src/table_types/UniformPadeTable.hpp @@ -21,6 +21,8 @@ class UniformPadeTable final : public UniformLookupTable { REGISTER_ULUT(UniformPadeTable); + //this one will need some work + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformPadeTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp index 565bc0f..426e166 100644 --- a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp @@ -4,29 +4,28 @@ #define IMPL_NAME UniformQuadraticPrecomputedInterpolationTable REGISTER_ULUT_IMPL(IMPL_NAME); - UniformQuadraticPrecomputedInterpolationTable::UniformQuadraticPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) { /* Base class default variables */ m_name = STR(IMPL_NAME); m_order = 3; - m_numTableEntries = 3*(m_numIntervals+1); - m_dataSize = (unsigned) sizeof(double) * m_numTableEntries; + m_numTableEntries = m_numIntervals+1; + m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* Allocate and set table */ - m_table.reset(new double[m_numTableEntries]); + m_table.reset(new polynomial<3,32>[m_numTableEntries]); for (int ii=0;ii[]> m_table; public: UniformQuadraticPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; diff --git a/src/table_types/UniformQuadraticTaylorTable.cpp b/src/table_types/UniformQuadraticTaylorTable.cpp index 0f1f097..edaef92 100644 --- a/src/table_types/UniformQuadraticTaylorTable.cpp +++ b/src/table_types/UniformQuadraticTaylorTable.cpp @@ -9,17 +9,17 @@ UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctor[m_numTableEntries]); for (int ii=0;iideriv(x); - m_table[3*ii+2] = func->deriv2(x)/2; + m_table[ii].coefs[0] = (*func)(x); + m_table[ii].coefs[1] = func->deriv(x); + m_table[ii].coefs[2] = func->deriv2(x)/2; } } @@ -29,8 +29,8 @@ double UniformQuadraticTaylorTable::operator()(double x) double dx = (x-m_minArg); double x1r = dx/m_stepSize+0.5; // index of previous table entry - unsigned x1 = 3*((unsigned) x1r); - dx -= x1*m_stepSize/3; - // linear Taylor series from grid point below x - return m_table[x1]+dx*(m_table[x1+1]+dx*m_table[x1+2]); + unsigned x1 = (unsigned) x1r; + dx -= x1*m_stepSize; + // Quadratic Taylor series from grid point below x + return m_table[x1].coefs[0]+dx*(m_table[x1].coefs[1]+dx*m_table[x1].coefs[2]); } diff --git a/src/table_types/UniformQuadraticTaylorTable.hpp b/src/table_types/UniformQuadraticTaylorTable.hpp index eb3fc9f..e116795 100644 --- a/src/table_types/UniformQuadraticTaylorTable.hpp +++ b/src/table_types/UniformQuadraticTaylorTable.hpp @@ -18,6 +18,7 @@ class UniformQuadraticTaylorTable final : public UniformLookupTable { REGISTER_ULUT(UniformQuadraticTaylorTable); + __attribute__((aligned)) std::unique_ptr[]> m_table; public: UniformQuadraticTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; From 4386d2bd2b7e86bb29797de89805b1cd6e34eacb Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Wed, 27 May 2020 21:43:21 -0600 Subject: [PATCH 02/21] fixed memory usage calculation --- .../UniformArmadilloPrecomputedInterpolationTable.cpp | 2 +- src/table_types/UniformCubicHermiteTable.cpp | 2 +- src/table_types/UniformCubicPrecomputedInterpolationTable.cpp | 2 +- src/table_types/UniformCubicTaylorTable.cpp | 2 +- src/table_types/UniformFailureProofCubicPITable.cpp | 2 +- src/table_types/UniformFailureProofLinearPITable.cpp | 2 +- src/table_types/UniformLinearInterpolationTable.cpp | 2 +- src/table_types/UniformLinearPrecomputedInterpolationTable.cpp | 2 +- src/table_types/UniformLinearTaylorTable.cpp | 2 +- src/table_types/UniformPadeTable.cpp | 2 +- src/table_types/UniformQuadraticTaylorTable.cpp | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp index 4e62c1d..881b57d 100644 --- a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp @@ -18,7 +18,7 @@ UniformArmadilloPrecomputedInterpolationTable::UniformArmadilloPrecomputedInt /* Base class default variables */ m_name = "UniformArmadilloPrecomputedInterpolationTable<" + std::to_string(N) + ">"; m_order = N+1; // take N as the degree of the polynomial interpolant which is of order N+1 - m_numTableEntries = (N+1)*(m_numIntervals+1); + m_numTableEntries = m_numIntervals+1; m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; /* build the vandermonde system for finding the interpolating polynomial's coefficients */ diff --git a/src/table_types/UniformCubicHermiteTable.cpp b/src/table_types/UniformCubicHermiteTable.cpp index bf42471..66dfef9 100644 --- a/src/table_types/UniformCubicHermiteTable.cpp +++ b/src/table_types/UniformCubicHermiteTable.cpp @@ -10,7 +10,7 @@ UniformCubicHermiteTable::UniformCubicHermiteTable(EvaluationFunctor::UniformPadeTable(EvaluationFunctor *func, /* Base class default variables */ m_name = "UniformPadeTable<" + std::to_string(M) + "," + std::to_string(N) + ">"; m_order = M+N+1; - m_numTableEntries = (M+N+1)*(m_numIntervals+1); + m_numTableEntries = m_numIntervals+1; m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; // assign the first 7 derivatives to the derivs array for easy enumeration diff --git a/src/table_types/UniformQuadraticTaylorTable.cpp b/src/table_types/UniformQuadraticTaylorTable.cpp index edaef92..7c1db8a 100644 --- a/src/table_types/UniformQuadraticTaylorTable.cpp +++ b/src/table_types/UniformQuadraticTaylorTable.cpp @@ -9,7 +9,7 @@ UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctor Date: Thu, 28 May 2020 14:47:04 -0600 Subject: [PATCH 03/21] Arma messages no longer show if you opt out of using it --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e538d51..94ef32c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ if(ARMADILLO_FOUND) If you wish to use Armadillo (NEEDED FOR HIGHER ORDER AND PADE TABLES), reconfigure with -DUSE_ARMADILLO=ON") endif() + if(USE_ARMADILLO) message(STATUS "Found Armadillo incl: ${ARMADILLO_INCLUDE_DIR}") message(STATUS "Armadillo libs to link: ${ARMADILLO_LIBRARIES}") message(STATUS "Found Armadillo lib: ${ARMADILLO_LIBRARY_DIRS}") From 9bdc7b567d454d821dc964eab48fc2778813d5fc Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Thu, 28 May 2020 20:25:31 -0600 Subject: [PATCH 04/21] ALIGN is now of type std::size_t --- src/table_types/UniformLookupTable.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/table_types/UniformLookupTable.hpp b/src/table_types/UniformLookupTable.hpp index bef8053..e3d6a74 100644 --- a/src/table_types/UniformLookupTable.hpp +++ b/src/table_types/UniformLookupTable.hpp @@ -17,7 +17,7 @@ struct UniformLookupTableParameters double stepSize = 1; }; -template +template struct alignas(ALIGN) polynomial{ double coefs[NUM_COEFS]; }; From 5c73aabc81d1edbe2237b7bd449ee8679954340e Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Fri, 19 Jun 2020 13:35:15 -0600 Subject: [PATCH 05/21] Added a failureproof table that wraps any UniformLookupTable and made that class's vector threadsafe --- src/CMakeLists.txt | 5 +- .../UniformFailureProofCubicPITable.cpp | 77 ------------------- .../UniformFailureProofCubicPITable.hpp | 35 --------- .../UniformFailureProofLinearPITable.cpp | 68 ---------------- .../UniformFailureProofLinearPITable.hpp | 36 --------- src/table_types/UniformFailureProofTable.cpp | 62 +++++++++++++++ src/table_types/UniformFailureProofTable.hpp | 43 +++++++++++ src/table_types/UniformTables.hpp | 5 +- 8 files changed, 108 insertions(+), 223 deletions(-) delete mode 100644 src/table_types/UniformFailureProofCubicPITable.cpp delete mode 100644 src/table_types/UniformFailureProofCubicPITable.hpp delete mode 100644 src/table_types/UniformFailureProofLinearPITable.cpp delete mode 100644 src/table_types/UniformFailureProofLinearPITable.hpp create mode 100644 src/table_types/UniformFailureProofTable.cpp create mode 100644 src/table_types/UniformFailureProofTable.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 97f6753..959a5ba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,8 +10,7 @@ list(APPEND func_impls_src table_types/UniformCubicHermiteTable.cpp table_types/UniformCubicPrecomputedInterpolationTable.cpp table_types/UniformCubicTaylorTable.cpp - table_types/UniformFailureProofCubicPITable.cpp - table_types/UniformFailureProofLinearPITable.cpp + table_types/UniformFailureProofTable.cpp table_types/UniformLinearInterpolationTable.cpp table_types/UniformLinearPrecomputedInterpolationTable.cpp table_types/UniformLinearTaylorTable.cpp @@ -55,7 +54,7 @@ if(FUNC_RECORD) endif() # TODO: Create a simplified public header? BTW every header is always being made -set_target_properties(func PROPERTIES PUBLIC_HEADER "func.hpp;func_impls.hpp;EvaluationFunctor.hpp;EvaluationImplementation.hpp;DirectEvaluation.hpp;ImplementationComparator.hpp;RngInterface.hpp;StdRng.hpp;Timer.hpp;UniformLookupTableGenerator.hpp;table_types/UniformArmadilloPrecomputedInterpolationTable.hpp;table_types/UniformConstantTaylorTable.hpp;table_types/UniformCubicHermiteTable.hpp;table_types/UniformCubicPrecomputedInterpolationTable.hpp;table_types/UniformCubicTaylorTable.hpp;table_types/UniformFailureProofCubicPITable.hpp;table_types/UniformFailureProofLinearPITable.hpp;table_types/UniformLinearInterpolationTable.hpp;table_types/UniformLinearPrecomputedInterpolationTable.hpp;table_types/UniformLinearTaylorTable.hpp;table_types/UniformLookupTable.hpp;table_types/UniformPadeTable.hpp;table_types/UniformQuadraticPrecomputedInterpolationTable.hpp;table_types/UniformQuadraticTaylorTable.hpp;table_types/UniformTables.hpp") +set_target_properties(func PROPERTIES PUBLIC_HEADER "func.hpp;func_impls.hpp;EvaluationFunctor.hpp;EvaluationImplementation.hpp;DirectEvaluation.hpp;ImplementationComparator.hpp;RngInterface.hpp;StdRng.hpp;Timer.hpp;UniformLookupTableGenerator.hpp;table_types/UniformArmadilloPrecomputedInterpolationTable.hpp;table_types/UniformConstantTaylorTable.hpp;table_types/UniformCubicHermiteTable.hpp;table_types/UniformCubicPrecomputedInterpolationTable.hpp;table_types/UniformCubicTaylorTable.hpp;table_types/UniformFailureProofTable.hpp;table_types/UniformLinearInterpolationTable.hpp;table_types/UniformLinearPrecomputedInterpolationTable.hpp;table_types/UniformLinearTaylorTable.hpp;table_types/UniformLookupTable.hpp;table_types/UniformPadeTable.hpp;table_types/UniformQuadraticPrecomputedInterpolationTable.hpp;table_types/UniformQuadraticTaylorTable.hpp;table_types/UniformTables.hpp") install(TARGETS func func_impls LIBRARY DESTINATION lib diff --git a/src/table_types/UniformFailureProofCubicPITable.cpp b/src/table_types/UniformFailureProofCubicPITable.cpp deleted file mode 100644 index bd16e82..0000000 --- a/src/table_types/UniformFailureProofCubicPITable.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* Implementation of a UniformPrecomputed Lookup table with linear interpolation */ -#include "UniformFailureProofCubicPITable.hpp" - -#ifdef NDEBUG - #define RECORD_ARG(x) - #define PRINT_ARGS(out) -#else - #include - #include - #define RECORD_ARG(x) m_args.push_back((x)) - // make sure we don't swallow the semicolon - #define PRINT_ARGS(out) \ - do { \ - if(!m_args.empty()){ \ - out << "args outside table range:" << std::endl; \ - out << m_args.front(); \ - m_args.erase(m_args.begin()); \ - for(auto x : m_args) \ - out << ", " << x; \ - out << std::endl; \ - } \ - } while(0) -#endif - -#define IMPL_NAME UniformFailureProofCubicPITable -REGISTER_ULUT_IMPL(IMPL_NAME); - -UniformFailureProofCubicPITable::UniformFailureProofCubicPITable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) -{ - - /* Base class default variables */ - m_name = STR(IMPL_NAME); - m_order = 4; - m_numTableEntries = m_numIntervals+1; - m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; - - /* Allocate and set table */ - m_table.reset(new polynomial<4,32>[m_numTableEntries]); - for (int ii=0;iim_maxArg){ - RECORD_ARG(x); - return (*mp_func)(x); - } - - // nondimensionalized x position, scaled by step size - double dx = m_stepSize_inv*(x-this->m_minArg); - // index of previous table entry - // unsigned x0 = (unsigned) floor(dx); - unsigned x0 = (unsigned) dx; - // value of table entries around x position - dx -= x0; - // cubic interpolation - return m_table[x0].coefs[0]+dx*(m_table[x0].coefs[1]+dx*(m_table[x0].coefs[2]+dx*m_table[x0].coefs[3])); -} - -UniformFailureProofCubicPITable::~UniformFailureProofCubicPITable() -{ - PRINT_ARGS(std::cerr); -} diff --git a/src/table_types/UniformFailureProofCubicPITable.hpp b/src/table_types/UniformFailureProofCubicPITable.hpp deleted file mode 100644 index ccf326a..0000000 --- a/src/table_types/UniformFailureProofCubicPITable.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - Cubic Interpolation LUT with uniform sampling (precomputed coefficients) - - Usage example: - UniformFailureProofCubicPITable look(&function,0,10,0.0001); - double val = look(0.87354); - - Notes: - - table precomputes and stores the linear coefficient so it doesn't have to - perform that operation every lookup (but does have to look it up) - - static data after constructor has been called - - evaluate by using parentheses, just like a function - - identical to the standard cubic table but samples from outside the - table's range are done with the original function - - if the NDEBUG flag is not specified then arguments outside the table's range - are recorded and printed by the table's destructor -*/ -#include "UniformLookupTable.hpp" - -#ifndef NDEBUG -#include -#endif - -class UniformFailureProofCubicPITable final : public UniformLookupTable -{ - REGISTER_ULUT(UniformFailureProofCubicPITable); - #ifndef NDEBUG - std::vector m_args; - #endif - __attribute__((aligned)) std::unique_ptr[]> m_table; -public: - UniformFailureProofCubicPITable(EvaluationFunctor *func, UniformLookupTableParameters par); - double operator()(double x) override; - ~UniformFailureProofCubicPITable(); -}; diff --git a/src/table_types/UniformFailureProofLinearPITable.cpp b/src/table_types/UniformFailureProofLinearPITable.cpp deleted file mode 100644 index 0547911..0000000 --- a/src/table_types/UniformFailureProofLinearPITable.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* Implementation of a UniformPrecomputed Lookup table with linear interpolation */ -#include "UniformFailureProofLinearPITable.hpp" - -// RECORD_ARG and PRINT_ARGS are null operators if NDEBUG is specified at compile time -#ifdef NDEBUG - #define RECORD_ARG(x) - #define PRINT_ARGS(out) -#else - #include - #define RECORD_ARG(x) m_args.push_back((x)) - // make sure we don't swallow the semicolon - #define PRINT_ARGS(out) \ - do { \ - if(!m_args.empty()){ \ - out << "args outside table range:" << std::endl; \ - out << m_args.front(); \ - m_args.erase(m_args.begin()); \ - for(auto x : m_args) \ - out << ", " << x; \ - out << std::endl; \ - } \ - } while(0) -#endif - -#define IMPL_NAME UniformFailureProofLinearPITable -REGISTER_ULUT_IMPL(IMPL_NAME); - -UniformFailureProofLinearPITable::UniformFailureProofLinearPITable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) -{ - - /* Base class default variables */ - m_name = STR(IMPL_NAME); - m_order = 2; - m_numTableEntries = m_numIntervals+1; - m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; - - /* Allocate and set table */ - m_table.reset(new polynomial<2,16>[m_numTableEntries]); - for (int ii=0;iim_maxArg){ - RECORD_ARG(x); - return (*mp_func)(x); - } - - // nondimensionalized x position, scaled by step size - double dx = m_stepSize_inv*(x-m_minArg); - // index of previous table entry - unsigned x0 = (unsigned) dx; - dx -= x0; - // linear interpolation - return m_table[x0].coefs[0]+dx*m_table[x0].coefs[1]; -} - -UniformFailureProofLinearPITable::~UniformFailureProofLinearPITable() -{ - PRINT_ARGS(std::cerr); -} diff --git a/src/table_types/UniformFailureProofLinearPITable.hpp b/src/table_types/UniformFailureProofLinearPITable.hpp deleted file mode 100644 index e02e87d..0000000 --- a/src/table_types/UniformFailureProofLinearPITable.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - Linear Interpolation LUT with uniform sampling (precomputed coefficients) - - Usage example: - UniformFailureProofLinearPITable look(&function,0,10,0.0001); - double val = look(0.87354); - - Notes: - - table precomputes and stores the linear coefficient so it doesn't have to - perform that operation every lookup (but does have to look it up) - - static data after constructor has been called - - evaluate by using parentheses, just like a function - - identical to the standard cubic table but samples from outside the - table's range are done with the original function - - if the NDEBUG flag is not specified then arguments outside the table's range - are recorded and printed by the table's destructor -*/ -#include "UniformLookupTable.hpp" - -#ifndef NDEBUG -#include -#endif - -class UniformFailureProofLinearPITable final : public UniformLookupTable -{ - REGISTER_ULUT(UniformFailureProofLinearPITable); - - #ifndef NDEBUG - std::vector m_args; - #endif - __attribute__((aligned)) std::unique_ptr[]> m_table; -public: - UniformFailureProofLinearPITable(EvaluationFunctor *func, UniformLookupTableParameters par); - double operator()(double x) override; - ~UniformFailureProofLinearPITable(); -}; diff --git a/src/table_types/UniformFailureProofTable.cpp b/src/table_types/UniformFailureProofTable.cpp new file mode 100644 index 0000000..7f1cd79 --- /dev/null +++ b/src/table_types/UniformFailureProofTable.cpp @@ -0,0 +1,62 @@ +#include "UniformFailureProofTable.hpp" + +#ifdef NDEBUG + #define RECORD_ARG(x) + #define PRINT_ARGS(out) +#else + #include + #include + #include + + // make sure we don't swallow the semicolon + #define RECORD_ARG(x) \ + do{ \ + const std::lock_guard \ + lock(m_args_mutex); \ + m_args.push_back((x)); \ + } while(0) + #define PRINT_ARGS(out) \ + do { \ + if(!m_args.empty()){ \ + out << "args outside table range:" << std::endl; \ + out << m_args.front(); \ + m_args.erase(m_args.begin()); \ + for(auto x : m_args) \ + out << ", " << x; \ + out << std::endl; \ + } \ + } while(0) +#endif + +// copy everything from the given LUT +UniformFailureProofTable::UniformFailureProofTable(std::unique_ptr LUT) : + mp_LUT(std::move(LUT)) +{ + mp_func = mp_LUT->function(); + m_minArg = mp_LUT->min_arg(); + m_maxArg = mp_LUT->max_arg(); + m_order = mp_LUT->order(); + m_name = mp_LUT->name(); + m_dataSize = mp_LUT->size(); +} + +double UniformFailureProofTable::operator()(double x) +{ + // check if x is in the range of the table + if(xm_maxArg){ + RECORD_ARG(x); + return (*mp_func)(x); + } + return (*mp_LUT)(x); +} + +void UniformFailureProofTable::print_details(std::ostream &out) +{ + mp_LUT->print_details(out); +} + +UniformFailureProofTable::~UniformFailureProofTable() +{ + // is a null op if iostream isn't included + PRINT_ARGS(std::cerr); +} diff --git a/src/table_types/UniformFailureProofTable.hpp b/src/table_types/UniformFailureProofTable.hpp new file mode 100644 index 0000000..699d67d --- /dev/null +++ b/src/table_types/UniformFailureProofTable.hpp @@ -0,0 +1,43 @@ +/* + A wrapper for a standard func table class. If an argument is outside a + table's range then the original function is used and the arg is recorded. + + Usage example: + UniformFailureProofTable failsafe(unique_ptr( + new UniformCubicPrecomputedInterpolationTable(&function,0,10,0.0001)) + ); + double val = failsafe(0.87354); + + Notes: + - ownership of the original table is moved to this class upon construction + - static data after constructor has been called + - evaluate by using parentheses, just like a function + - specify the NDEBUG flag to turn off argument recording for args outside + the table's range. + - Args outside the table's range are printed to stderr upon table destruction + (so you could redirect that output to a file with '2> foo.txt') +*/ +#pragma once +#include "EvaluationImplementation.hpp" +#include "UniformLookupTable.hpp" + +#ifndef NDEBUG + #include + #include +#endif + +class UniformFailureProofTable final : public EvaluationImplementation { + #ifndef NDEBUG + std::vector m_args; + std::mutex m_args_mutex; + #endif + + // the "UniformLookupTable" part can be changed when + // non-uniform tables are added + std::unique_ptr mp_LUT; +public: + UniformFailureProofTable(std::unique_ptr); + ~UniformFailureProofTable(); + double operator()(double) override; + void print_details(std::ostream &out) override; +}; diff --git a/src/table_types/UniformTables.hpp b/src/table_types/UniformTables.hpp index 6d1fa1a..3cae3f1 100644 --- a/src/table_types/UniformTables.hpp +++ b/src/table_types/UniformTables.hpp @@ -5,13 +5,10 @@ #include "UniformLinearInterpolationTable.hpp" #include "UniformLinearPrecomputedInterpolationTable.hpp" - #include "UniformQuadraticPrecomputedInterpolationTable.hpp" - #include "UniformCubicPrecomputedInterpolationTable.hpp" -#include "UniformFailureProofCubicPITable.hpp" -#include "UniformFailureProofLinearPITable.hpp" +#include "UniformFailureProofTable.hpp" #include "UniformConstantTaylorTable.hpp" #include "UniformLinearTaylorTable.hpp" From 5c5a7d34f4e68c81cfbc61b8b5f25aab9eef64d8 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Fri, 19 Jun 2020 16:37:13 -0600 Subject: [PATCH 06/21] Made ArgumentRecord threadsafe --- src/ArgumentRecord.cpp | 9 +++++++-- src/ArgumentRecord.hpp | 6 ++++++ src/table_types/UniformFailureProofTable.hpp | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ArgumentRecord.cpp b/src/ArgumentRecord.cpp index 4731e47..afb8dc2 100644 --- a/src/ArgumentRecord.cpp +++ b/src/ArgumentRecord.cpp @@ -7,7 +7,9 @@ ArgumentRecord::ArgumentRecord(unsigned int histSize, double min, double max) : { /* variables needed for recording function arguments */ this->mp_histogram=new unsigned int[histSize]; - // init the array to zeros so we can easily add 1 to each entry + this->mp_histogram_mutex.reset(new std::mutex[histSize]); + + // init the array to zeros so we can easily increment each entry std::fill(mp_histogram, mp_histogram+histSize, 0); this->m_peak=0; } @@ -15,7 +17,11 @@ ArgumentRecord::ArgumentRecord(unsigned int histSize, double min, double max) : void ArgumentRecord::record_arg(double x) { unsigned int index = CALC_INDEX(x); + // lock only exists for the scope of this function + std::lock_guard lock1(mp_histogram_mutex[index]); mp_histogram[index]++; + + std::lock_guard lock2(m_peak_mutex); unsigned int peak_index = CALC_INDEX(m_peak); if(mp_histogram[index]>mp_histogram[peak_index]) m_peak=x; @@ -68,4 +74,3 @@ ArgumentRecord::~ArgumentRecord() { delete mp_histogram; } - diff --git a/src/ArgumentRecord.hpp b/src/ArgumentRecord.hpp index ddee4d6..8427ac2 100644 --- a/src/ArgumentRecord.hpp +++ b/src/ArgumentRecord.hpp @@ -1,16 +1,22 @@ #pragma once #include // to_string() #include +#include // Store a histogram of each location a function has been sampled at class ArgumentRecord { unsigned int *mp_histogram; + unique_ptr mp_histogram_mutex; + unsigned int m_histSize; // min and max should always be the same as the table that contains the ArgumentRecord double m_min; double m_max; + + // statistic plus a mutex for locking double m_peak; + std::mutex m_peak_mutex; public: ArgumentRecord(unsigned int histSize, double min, double max); diff --git a/src/table_types/UniformFailureProofTable.hpp b/src/table_types/UniformFailureProofTable.hpp index 699d67d..d20b64a 100644 --- a/src/table_types/UniformFailureProofTable.hpp +++ b/src/table_types/UniformFailureProofTable.hpp @@ -10,6 +10,7 @@ Notes: - ownership of the original table is moved to this class upon construction + (not a problem since tables don't have move constructors for unique_ptr) - static data after constructor has been called - evaluate by using parentheses, just like a function - specify the NDEBUG flag to turn off argument recording for args outside From 744a19cacc463879859124c79ded517745c50df5 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Fri, 19 Jun 2020 20:50:27 -0600 Subject: [PATCH 07/21] small revisions --- CMakeLists.txt | 1 - src/ArgumentRecord.hpp | 2 +- src/DirectEvaluation.cpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94ef32c..e538d51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ if(ARMADILLO_FOUND) If you wish to use Armadillo (NEEDED FOR HIGHER ORDER AND PADE TABLES), reconfigure with -DUSE_ARMADILLO=ON") endif() - if(USE_ARMADILLO) message(STATUS "Found Armadillo incl: ${ARMADILLO_INCLUDE_DIR}") message(STATUS "Armadillo libs to link: ${ARMADILLO_LIBRARIES}") message(STATUS "Found Armadillo lib: ${ARMADILLO_LIBRARY_DIRS}") diff --git a/src/ArgumentRecord.hpp b/src/ArgumentRecord.hpp index 8427ac2..97338fd 100644 --- a/src/ArgumentRecord.hpp +++ b/src/ArgumentRecord.hpp @@ -7,7 +7,7 @@ class ArgumentRecord { unsigned int *mp_histogram; - unique_ptr mp_histogram_mutex; + std::unique_ptr mp_histogram_mutex; unsigned int m_histSize; // min and max should always be the same as the table that contains the ArgumentRecord diff --git a/src/DirectEvaluation.cpp b/src/DirectEvaluation.cpp index a35e2f8..d911874 100644 --- a/src/DirectEvaluation.cpp +++ b/src/DirectEvaluation.cpp @@ -45,7 +45,7 @@ void DirectEvaluation::print_details(std::ostream& out) { out<< m_name << " " << m_minArg << " " << m_maxArg; #ifdef FUNC_RECORD - out << endl; + out << std::endl; mp_recorder->print_details(out); #endif } From 34ac1e606b9e5ea026b146c639d044c5533e0fc4 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Fri, 19 Jun 2020 21:33:56 -0600 Subject: [PATCH 08/21] test --- src/RngDriver.cpp | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/RngDriver.cpp diff --git a/src/RngDriver.cpp b/src/RngDriver.cpp deleted file mode 100644 index 319da3e..0000000 --- a/src/RngDriver.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include - -#include "RngInterface.hpp" -#include "StdRng.hpp" - -// a dummy version of ImplementationComparator. Just samples points based on the -// type of RngInterface it's given -class Driver{ - RngInterface *mp_sampler; - public: - Driver(RngInterface *inRng=nullptr, unsigned int seed=2020) { - mp_sampler=inRng; - if(mp_sampler==nullptr) - mp_sampler=std::move(new StdRng> - (new std::uniform_real_distribution(0.0, 1.0))); - mp_sampler->init(seed); - } - - double samplePoints(){return mp_sampler->getPt();} - - ~Driver(){} -}; - - -int main(){ - // sample from a normal distribution - StdRng> standardRNG(new std::normal_distribution(-5.0, 1.0)); - Driver driver1(&standardRNG); - std::cout << driver1.samplePoints() << std::endl; - - // sample from the default uniform distribution - Driver driver2; - std::cout << driver2.samplePoints() << std::endl; -} - From f0ccb8d4d65ada50726a3767f3718d4e66dffe04 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 22 Jun 2020 15:15:00 -0600 Subject: [PATCH 09/21] Added autodiff types --- src/table_types/UniformLinearTaylorTable.cpp | 17 ++++++++++++----- src/table_types/UniformLinearTaylorTable.hpp | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/table_types/UniformLinearTaylorTable.cpp b/src/table_types/UniformLinearTaylorTable.cpp index 64bf0a9..5ac5946 100644 --- a/src/table_types/UniformLinearTaylorTable.cpp +++ b/src/table_types/UniformLinearTaylorTable.cpp @@ -1,11 +1,16 @@ /* Implementation of a Uniform Lookup table with linear interpolation */ #include "UniformLinearTaylorTable.hpp" +#include #define IMPL_NAME UniformLinearTaylorTable REGISTER_ULUT_IMPL(IMPL_NAME); -UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +template +UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + UniformLookupTable(func, par) { + using namespace boost::math::differentiation; + /* Base class variables */ m_name = STR(IMPL_NAME); m_order = 2; @@ -15,10 +20,12 @@ UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor[m_numTableEntries]); for (int ii=0; iideriv(x); + const double x = m_minArg + ii*m_stepSize; + m_grid[ii] = x; + // get every derivative up to the first + auto const y = (*mp_func)(make_fvar(x)); + m_table[ii].coefs[0] = y.derivative(0); + m_table[ii].coefs[1] = y.derivative(1); } } diff --git a/src/table_types/UniformLinearTaylorTable.hpp b/src/table_types/UniformLinearTaylorTable.hpp index c3e0c9c..cdda03e 100644 --- a/src/table_types/UniformLinearTaylorTable.hpp +++ b/src/table_types/UniformLinearTaylorTable.hpp @@ -18,6 +18,7 @@ class UniformLinearTaylorTable final : public UniformLookupTable __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformLinearTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); + template + UniformLinearTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); double operator()(double x) override; }; From d4e64b7bf902c4d44268a27b6240a4f1b5561610 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Thu, 25 Jun 2020 11:04:53 -0600 Subject: [PATCH 10/21] Initial AutoDiffTable --- src/table_types/UniformAutoDiffTable.cpp | 94 ++++++++++++++++++ src/table_types/UniformAutoDiffTable.hpp | 115 +++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/table_types/UniformAutoDiffTable.cpp create mode 100644 src/table_types/UniformAutoDiffTable.hpp diff --git a/src/table_types/UniformAutoDiffTable.cpp b/src/table_types/UniformAutoDiffTable.cpp new file mode 100644 index 0000000..0fa17e3 --- /dev/null +++ b/src/table_types/UniformAutoDiffTable.cpp @@ -0,0 +1,94 @@ +/* Implementation of a Uniform Lookup table */ +#include "UniformLookupTable.hpp" +#include + +#include +#include + +UniformLookupTable::UniformLookupTable(EvaluationFunctor *func, UniformLookupTableParameters par) : + mp_boost_func(func), EvaluationImplementation(new FuncWrapper(this),"uniform_lookup_table") +{ + //mp_func = new FuncWrapper(this); + + /* Base class variables */ + m_minArg = par.minArg; m_maxArg = par.maxArg; + + /* + Uniform Lookup Table variables + - corresponds to the grid + */ + m_stepSize = par.stepSize; + m_stepSize_inv = 1.0/m_stepSize; + m_numIntervals = (unsigned) ceil(m_stepSize_inv*(m_maxArg-m_minArg))+1; + /* + If the step size does not exactly divide the arg domain, the max + arg of the table is set to the nearest value above such that it + does. + */ + m_tableMaxArg = m_maxArg; + if ( m_tableMaxArg < m_minArg+m_stepSize*(m_numIntervals-1) ) + m_tableMaxArg = m_minArg+m_stepSize*(m_numIntervals-1); + m_grid.reset(new double[m_numIntervals]); +} + +std::pair UniformLookupTable::arg_bounds_of_interval(unsigned intervalNumber) +{ + return std::make_pair(m_grid[intervalNumber],m_grid[intervalNumber+1]); +} + +void UniformLookupTable::print_details(std::ostream &out) +{ + out << m_name << " " << m_minArg << " " << m_maxArg << " " + << m_stepSize << " " << m_numIntervals << " "; +} + +EvaluationFunctor *UniformLookupTable::fvar_function(){ return mp_boost_func; } + +//EvaluationFunctor *UniformLookupTable::fvar_to_double_functor(){ return NULL; } + +/* //////////////////////////////////////////////////////////////////////////// + Factory and registration management +//////////////////////////////////////////////////////////////////////////// */ +std::unique_ptr UniformLookupTableFactory::Create(std::string name, + EvaluationFunctor *f, + UniformLookupTableParameters par) +{ + // Create a UniformLookupTable + UniformLookupTable * instance = nullptr; + + // find the name in the registry and call factory method. + auto it = get_registry().find(name); + if(it != get_registry().end()) + instance = it->second(f,par); // TODO this line causes an exception for hermite tables + + // wrap instance in a unique ptr and return (if created) + if(instance == nullptr) + throw "Table name not found in registry."; // TODO better exception + return std::unique_ptr(instance); +} + +std::vector UniformLookupTableFactory::get_registry_keys() +{ + // copy all keys from the registry map into a vector + std::vector keys; + for (auto const& elem : get_registry() ) { + keys.push_back(elem.first); + } + return keys; +} + +void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, +std::function*,UniformLookupTableParameters)> classFactoryFunction) +{ + // register a derived class factory function + get_registry()[name] = classFactoryFunction; +} + +std::map*,UniformLookupTableParameters)>>& UniformLookupTableFactory::get_registry() +{ + // Get the singleton instance of the registry map + static std::map*,UniformLookupTableParameters)>> registry; + return registry; +} diff --git a/src/table_types/UniformAutoDiffTable.hpp b/src/table_types/UniformAutoDiffTable.hpp new file mode 100644 index 0000000..63dafc1 --- /dev/null +++ b/src/table_types/UniformAutoDiffTable.hpp @@ -0,0 +1,115 @@ +/* + Intermediate abstract class for LUTs with uniformly spaced grid points +*/ +#pragma once +#include "EvaluationImplementation.hpp" + +#include +#include +#include +#include +#include + +using boost::math::differentiation::autodiff_fvar; + +template +class UniformAutoDiffTable : public UniformLookupTable +{ + friend class func_wrapper; +protected: + + EvaluationFunctor, autodiff_fvar> *mp_boost_func; + + std::unique_ptr m_grid; // pointers to grid and evaluation data + // a LUT array needs to be provided by each implementation + + unsigned m_numIntervals; // sizes of grid and evaluation data + unsigned m_numTableEntries; + + double m_stepSize; // fixed grid spacing (and its inverse) + double m_stepSize_inv; + + double m_tableMaxArg; // > m_maxArg if (m_maxArg-m_minArg)/m_stepSize is non-integer + +public: + + UniformAutoDiffTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + virtual ~UniformAutoDiffTable(){}; + + /* public access of protected data */ + double step_size(){ return m_stepSize; }; + unsigned num_table_entries(){ return m_numTableEntries; }; + unsigned num_intervals(){ return m_numIntervals; }; + void print_details(std::ostream&) override; + std::pair arg_bounds_of_interval(unsigned); + EvaluationFunctor, autodiff_fvar> *fvar_function(); +}; + +/* This can probably be removed when we move to std::function */ +class FuncWrapper : public EvaluationFunctor +{ + public: + EvaluationFunctor,autodiff_fvar> *fvar_EvalFunctor; + FuncWrapper( *new_EvalFuntor){ fvar_EvalFunctor = new_EvalFunctor; } + double operator()(double x) override { return (double) (*fvar_EvalFunctor)(x); } +}; + +/* //////////////////////////////////////////////////////////////////////////// + Factory and registration management + + UniformLookupTableFactory: singleton class responsible for + - creating Derived classes of UniformAutoDiffTable + - keeping a registry of derived classes + I ASSUME THERE SHOULD ONLY BE ONE OF THESE +//////////////////////////////////////////////////////////////////////////// */ +class UniformLookupTableFactory +{ +public: + // Only ever hand out unique pointers + static std::unique_ptr Create(std::string name, + EvaluationFunctor,autodiff_fvar> *f, + UniformLookupTableParameters par); + // Actual registration function + static void RegisterFactoryFunction(std::string name, + std::function,autodiff_fvar>*,UniformLookupTableParameters)> classFactoryFunction); + // Get all keys from the registry + static std::vector get_registry_keys(void); + +private: + // the actual registry is private to this class + static std::map,autodiff_fvar>*,UniformLookupTableParameters)>>& get_registry(); + // Do NOT implement copy methods + UniformLookupTableFactory(){}; + UniformLookupTableFactory(UniformLookupTableFactory const& copy); + UniformLookupTableFactory& operator=(UniformLookupTableFactory const& copy); +}; + +/* + Helper class for registering Uniform LUT implementations + + NOTE: implementation defined in this header so that templates get + instantiated in derived LUT class files +*/ +template +class UniformLookupTableRegistrar { +public: + UniformLookupTableRegistrar(std::string className) + { + UniformLookupTableFactory::RegisterFactoryFunction(className, + [](EvaluationFunctor,autodiff_fvar> *f, UniformLookupTableParameters par) -> UniformAutoDiffTable * { return new T(f, par);}); + } +}; + +/* + Macros for class registration: + - REGISTER_ULUT goes inside class declaration in .hpp + - REGISTER_ULUT_IMPL goes inside .cpp implementation +*/ +#define REGISTER_ULUT(classname) \ +private: \ + static const UniformLookupTableRegistrar registrar; +#define STR_EXPAND(x...) #x +#define STR(x...) STR_EXPAND(x) +#define REGISTER_ULUT_IMPL(classname...) \ + const UniformLookupTableRegistrar classname::registrar(STR(classname)); From bbdafa0ca705227eb5d562827f0a23aedde2beec Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Thu, 25 Jun 2020 12:59:09 -0600 Subject: [PATCH 11/21] Templated ZeroFunction --- src/ZeroFunction.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ZeroFunction.hpp b/src/ZeroFunction.hpp index 6f88fd7..66bc304 100644 --- a/src/ZeroFunction.hpp +++ b/src/ZeroFunction.hpp @@ -2,19 +2,21 @@ #include "EvaluationFunctor.hpp" #define FUNC(x) 0.0 #define FUNCNAME "Zero" -class ZeroFunction final : public EvaluationFunctor + +template +class ZeroFunction final : public EvaluationFunctor { public: - double operator()(double x) override { return FUNC(X); } - double deriv(double x) override + T operator()(T x) override { return FUNC(X); } + T deriv(T x) override { return 0.0; } - double deriv2(double x) override + T deriv2(T x) override { return 0.0; } - double deriv3(double x) override + T deriv3(T x) override { return 0.0; } From f79dbf056c69636ca1503a2349ef1e31e3e2f5fd Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Fri, 26 Jun 2020 14:47:39 -0600 Subject: [PATCH 12/21] Failed experimental version of func. Will rework into a better implementation --- examples/chaste_log_function.hpp | 19 +-- examples/compute_max_err_of_tables.cpp | 2 +- examples/experiment.cpp | 42 ++++--- examples/experiment_best_worst.cpp | 2 +- examples/generate_tables_at_tol.cpp | 5 +- examples/test_function.hpp | 10 +- src/CMakeLists.txt | 6 +- src/FunctionHelper.hpp | 21 ++++ src/UniformLookupTableGenerator.cpp | 2 +- src/UniformLookupTableGenerator.hpp | 10 +- src/table_types/UniformAutoDiffTable.cpp | 94 --------------- src/table_types/UniformAutoDiffTable.hpp | 109 +++--------------- src/table_types/UniformCubicHermiteTable.cpp | 7 +- src/table_types/UniformCubicHermiteTable.hpp | 8 +- src/table_types/UniformCubicTaylorTable.cpp | 17 ++- src/table_types/UniformCubicTaylorTable.hpp | 9 +- src/table_types/UniformLinearTaylorTable.cpp | 12 +- src/table_types/UniformLinearTaylorTable.hpp | 9 +- src/table_types/UniformLookupTable.cpp | 86 +++++++------- src/table_types/UniformLookupTable.hpp | 77 +++++++++++-- src/table_types/UniformPadeTable.cpp | 20 ++-- src/table_types/UniformPadeTable.hpp | 9 +- .../UniformQuadraticTaylorTable.cpp | 14 ++- .../UniformQuadraticTaylorTable.hpp | 10 +- 24 files changed, 270 insertions(+), 330 deletions(-) create mode 100644 src/FunctionHelper.hpp delete mode 100644 src/table_types/UniformAutoDiffTable.cpp diff --git a/examples/chaste_log_function.hpp b/examples/chaste_log_function.hpp index cd36956..bed6181 100644 --- a/examples/chaste_log_function.hpp +++ b/examples/chaste_log_function.hpp @@ -4,35 +4,36 @@ #define FUNC(x) (7.7-13.0287*log(x)) #define FUNCNAME "(7.7-13.0287*log(x))" -class MyFunction final : public EvaluationFunctor +template +class MyFunction final : public EvaluationFunctor { public: - double operator()(double x) override { return FUNC(x); } - double deriv(double x) override + T operator()(T x) override { return FUNC(x); } + T deriv(T x) override { return -13.0287/x; } - double deriv2(double x) override + T deriv2(T x) override { return 13.0287/x/x; } - double deriv3(double x) override + T deriv3(T x) override { return -26.0574/x/x/x; } - double deriv4(double x) override + T deriv4(T x) override { return 78.1722/x/x/x/x; } - double deriv5(double x) override + T deriv5(T x) override { return -312.6888/x/x/x/x/x; } - double deriv6(double x) override + T deriv6(T x) override { return 1563.444/x/x/x/x/x/x; } - double deriv7(double x) override + T deriv7(T x) override { return -9380.664/x/x/x/x/x/x/x; } diff --git a/examples/compute_max_err_of_tables.cpp b/examples/compute_max_err_of_tables.cpp index 7b7ecf6..2c65142 100644 --- a/examples/compute_max_err_of_tables.cpp +++ b/examples/compute_max_err_of_tables.cpp @@ -14,7 +14,7 @@ int main() { using namespace std; - MyFunction func; + MyFunction func; /* Which implementations to use */ std::vector implNames {"UniformLinearInterpolationTable", diff --git a/examples/experiment.cpp b/examples/experiment.cpp index 10a3a8c..99009ac 100644 --- a/examples/experiment.cpp +++ b/examples/experiment.cpp @@ -44,7 +44,8 @@ int main(int argc, char* argv[]) int nEvals = std::stoi(argv[5]); unsigned int seed = std::stoi(argv[6]); - MyFunction func; + MyFunction func; + MyFunction double_func; double stepSize; /* Check which implementations are available */ @@ -58,35 +59,44 @@ int main(int argc, char* argv[]) std::vector> impls; /* Which LUT implementations to use */ - std::vector implNames {"UniformLinearInterpolationTable", - "UniformLinearPrecomputedInterpolationTable", - "UniformQuadraticPrecomputedInterpolationTable", + std::vector implNames { + //"UniformCubicHermiteTable", + //"UniformLinearInterpolationTable", + //"UniformLinearPrecomputedInterpolationTable", + //"UniformQuadraticPrecomputedInterpolationTable", "UniformCubicPrecomputedInterpolationTable", - "UniformArmadilloPrecomputedInterpolationTable<4>", - "UniformArmadilloPrecomputedInterpolationTable<5>", - "UniformArmadilloPrecomputedInterpolationTable<6>", - "UniformArmadilloPrecomputedInterpolationTable<7>", - "UniformPadeTable<1,1>", - "UniformPadeTable<2,2>", - "UniformPadeTable<3,3>", - "UniformPadeTable<4,3>", - "UniformLinearTaylorTable", - "UniformQuadraticTaylorTable", - "UniformCubicTaylorTable"}; + //"UniformArmadilloPrecomputedInterpolationTable<4>", + //"UniformArmadilloPrecomputedInterpolationTable<5>", + //"UniformArmadilloPrecomputedInterpolationTable<6>", + //"UniformArmadilloPrecomputedInterpolationTable<7>", + //"UniformPadeTable<1,1>", + //"UniformPadeTable<2,2>", + //"UniformPadeTable<3,3>", + //"UniformPadeTable<4,3>", + "UniformLinearTaylorTable" + //"UniformQuadraticTaylorTable", + //"UniformCubicTaylorTable" + }; UniformLookupTableGenerator gen(&func, tableMin, tableMax); + cout << "foo1" << endl; /* add implementations to vector */ // unique_ptr test = make_unique(&func,tableMin,tableMax); - impls.emplace_back(unique_ptr(new DirectEvaluation(&func,tableMin,tableMax))); + impls.emplace_back(unique_ptr(new DirectEvaluation(&double_func,tableMin,tableMax))); + cout << "foo4" << endl; for (auto itName : implNames) { impls.emplace_back(gen.generate_by_tol(itName,tableTol)); + cout << "foo6" << endl; } + cout << "foo2" << endl; /* Run comparator */ ImplementationComparator implCompare(impls, nEvals, seed); + cout << "foo3" << endl; implCompare.run_timings(nExperiments); + cout << "foo3" << endl; /* Summarize the results */ cout << "# Function: " << FUNCNAME << endl; diff --git a/examples/experiment_best_worst.cpp b/examples/experiment_best_worst.cpp index 5dfb26a..e005b56 100644 --- a/examples/experiment_best_worst.cpp +++ b/examples/experiment_best_worst.cpp @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) int nEvals = std::stoi(argv[3]); int seed = std::stoi(argv[4]); - ZeroFunction func; + ZeroFunction func; double stepSize; /* Which LUT implementations to use */ diff --git a/examples/generate_tables_at_tol.cpp b/examples/generate_tables_at_tol.cpp index 9361d2f..190fa1e 100644 --- a/examples/generate_tables_at_tol.cpp +++ b/examples/generate_tables_at_tol.cpp @@ -18,7 +18,10 @@ int main() { using namespace std; - MyFunction func; + MyFunction func; + MyFunction func; + MyFunction func; + MyFunction func; cout << "# Function: " << FUNCNAME << "\n"; cout << "# Tol: " << TOL << "\n"; diff --git a/examples/test_function.hpp b/examples/test_function.hpp index 0f60c81..4b366c6 100644 --- a/examples/test_function.hpp +++ b/examples/test_function.hpp @@ -4,19 +4,19 @@ #define FUNC(x) (7.7*x*exp(x)-13.0287*x*x*log(x)-x +13.0*x*x*x) #define FUNCNAME "(7.7*x*exp(x)-13.0287*x*x*log(x)-x +13.0*x*x*x)" -class MyFunction final : public EvaluationFunctor +class MyFunction final : public EvaluationFunctor { public: - double operator()(double x) override { return FUNC(x); } - double deriv(double x) override + boost_fvar operator()(boost_fvar x) override { return FUNC(x); } + boost_fvar deriv(boost_fvar x) override { return 7.7*exp(x)*(1.0+x) - 13.0287*(2.0*x*log(x)+x) - 1.0 + 39.0*x*x; } - double deriv2(double x) override + boost_fvar deriv2(boost_fvar x) override { return 7.7*exp(x)*(2.0+x) - 13.0287*(2.0*log(x)+3.0) + 78.0*x; } - double deriv3(double x) override + boost_fvar deriv3(boost_fvar x) override { return 7.7*exp(x)*(3.0+x) - 13.0287*(2.0/x) + 78.0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 959a5ba..ee91df6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,8 +26,8 @@ if(USE_ARMADILLO AND ARMADILLO_FOUND) list(APPEND func_impls_link_libs ${ARMADILLO_LIBRARIES}) list(APPEND func_impls_src - table_types/UniformArmadilloPrecomputedInterpolationTable.cpp - table_types/UniformPadeTable.cpp + #table_types/UniformArmadilloPrecomputedInterpolationTable.cpp + #table_types/UniformPadeTable.cpp ) endif() @@ -40,7 +40,7 @@ target_include_directories(func_impls PUBLIC ${func_impls_include_dirs}) add_library(func SHARED ImplementationComparator.cpp Timer.cpp - UniformLookupTableGenerator.cpp + #UniformLookupTableGenerator.cpp ) target_link_libraries(func PUBLIC ${QUADMATH_LIBRARIES} Boost::boost func_impls) diff --git a/src/FunctionHelper.hpp b/src/FunctionHelper.hpp new file mode 100644 index 0000000..5f1cd04 --- /dev/null +++ b/src/FunctionHelper.hpp @@ -0,0 +1,21 @@ +#include + +using boost::math::differentiation::autodiff_fvar; +typedef autodiff_fvar fvar1; +typedef autodiff_fvar fvar2; +typedef autodiff_fvar fvar3; +typedef autodiff_fvar fvar4; +typedef autodiff_fvar fvar5; +typedef autodiff_fvar fvar6; +typedef autodiff_fvar fvar7; + +struct FunctionHelper{ + EvaluationFunctor *double_func; + EvaluationFunctor *fvar1_func; + EvaluationFunctor *fvar2_func; + EvaluationFunctor *fvar3_func; + EvaluationFunctor *fvar4_func; + EvaluationFunctor *fvar5_func; + EvaluationFunctor *fvar6_func; + EvaluationFunctor *fvar7_func; +} diff --git a/src/UniformLookupTableGenerator.cpp b/src/UniformLookupTableGenerator.cpp index 4cbabaa..fff139a 100644 --- a/src/UniformLookupTableGenerator.cpp +++ b/src/UniformLookupTableGenerator.cpp @@ -112,7 +112,7 @@ struct UniformLookupTableGenerator::OptimalStepSizeFunctor /* UniformLookupTableGenerator functions */ -UniformLookupTableGenerator::UniformLookupTableGenerator(EvaluationFunctor *func, double minArg, double maxArg) : mp_func(func), m_min(minArg), m_max(maxArg) {} +UniformLookupTableGenerator::UniformLookupTableGenerator(EvaluationFunctor *func, double minArg, double maxArg) : mp_func(func), m_min(minArg), m_max(maxArg) {} UniformLookupTableGenerator::~UniformLookupTableGenerator() diff --git a/src/UniformLookupTableGenerator.hpp b/src/UniformLookupTableGenerator.hpp index 6453ca7..9d1c192 100644 --- a/src/UniformLookupTableGenerator.hpp +++ b/src/UniformLookupTableGenerator.hpp @@ -6,14 +6,14 @@ */ #pragma once #include "UniformLookupTable.hpp" - +#include #include class UniformLookupTableGenerator { private: + FunctionHelper *mp_func; - EvaluationFunctor *mp_func; double m_min; double m_max; @@ -25,7 +25,11 @@ class UniformLookupTableGenerator public: - UniformLookupTableGenerator(EvaluationFunctor *func, double minArg, double maxArg); + //TODO make this less rigid. Can you specify args out of order w/ dummy names? + UniformLookupTableGenerator(FunctionHelper *func, + double minArg, double maxArg, + ); + ~UniformLookupTableGenerator(); std::unique_ptr generate_by_step(std::string tableKey, double stepSize); std::unique_ptr generate_by_tol(std::string tableKey, double desiredTolerance); diff --git a/src/table_types/UniformAutoDiffTable.cpp b/src/table_types/UniformAutoDiffTable.cpp deleted file mode 100644 index 0fa17e3..0000000 --- a/src/table_types/UniformAutoDiffTable.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* Implementation of a Uniform Lookup table */ -#include "UniformLookupTable.hpp" -#include - -#include -#include - -UniformLookupTable::UniformLookupTable(EvaluationFunctor *func, UniformLookupTableParameters par) : - mp_boost_func(func), EvaluationImplementation(new FuncWrapper(this),"uniform_lookup_table") -{ - //mp_func = new FuncWrapper(this); - - /* Base class variables */ - m_minArg = par.minArg; m_maxArg = par.maxArg; - - /* - Uniform Lookup Table variables - - corresponds to the grid - */ - m_stepSize = par.stepSize; - m_stepSize_inv = 1.0/m_stepSize; - m_numIntervals = (unsigned) ceil(m_stepSize_inv*(m_maxArg-m_minArg))+1; - /* - If the step size does not exactly divide the arg domain, the max - arg of the table is set to the nearest value above such that it - does. - */ - m_tableMaxArg = m_maxArg; - if ( m_tableMaxArg < m_minArg+m_stepSize*(m_numIntervals-1) ) - m_tableMaxArg = m_minArg+m_stepSize*(m_numIntervals-1); - m_grid.reset(new double[m_numIntervals]); -} - -std::pair UniformLookupTable::arg_bounds_of_interval(unsigned intervalNumber) -{ - return std::make_pair(m_grid[intervalNumber],m_grid[intervalNumber+1]); -} - -void UniformLookupTable::print_details(std::ostream &out) -{ - out << m_name << " " << m_minArg << " " << m_maxArg << " " - << m_stepSize << " " << m_numIntervals << " "; -} - -EvaluationFunctor *UniformLookupTable::fvar_function(){ return mp_boost_func; } - -//EvaluationFunctor *UniformLookupTable::fvar_to_double_functor(){ return NULL; } - -/* //////////////////////////////////////////////////////////////////////////// - Factory and registration management -//////////////////////////////////////////////////////////////////////////// */ -std::unique_ptr UniformLookupTableFactory::Create(std::string name, - EvaluationFunctor *f, - UniformLookupTableParameters par) -{ - // Create a UniformLookupTable - UniformLookupTable * instance = nullptr; - - // find the name in the registry and call factory method. - auto it = get_registry().find(name); - if(it != get_registry().end()) - instance = it->second(f,par); // TODO this line causes an exception for hermite tables - - // wrap instance in a unique ptr and return (if created) - if(instance == nullptr) - throw "Table name not found in registry."; // TODO better exception - return std::unique_ptr(instance); -} - -std::vector UniformLookupTableFactory::get_registry_keys() -{ - // copy all keys from the registry map into a vector - std::vector keys; - for (auto const& elem : get_registry() ) { - keys.push_back(elem.first); - } - return keys; -} - -void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, -std::function*,UniformLookupTableParameters)> classFactoryFunction) -{ - // register a derived class factory function - get_registry()[name] = classFactoryFunction; -} - -std::map*,UniformLookupTableParameters)>>& UniformLookupTableFactory::get_registry() -{ - // Get the singleton instance of the registry map - static std::map*,UniformLookupTableParameters)>> registry; - return registry; -} diff --git a/src/table_types/UniformAutoDiffTable.hpp b/src/table_types/UniformAutoDiffTable.hpp index 63dafc1..5a8b18b 100644 --- a/src/table_types/UniformAutoDiffTable.hpp +++ b/src/table_types/UniformAutoDiffTable.hpp @@ -1,8 +1,9 @@ /* - Intermediate abstract class for LUTs with uniformly spaced grid points + Templated header only abstract class for uniform LUTs + using boosts automatic differentiation for construction */ #pragma once -#include "EvaluationImplementation.hpp" +#include "UniformLookupTable.hpp" #include #include @@ -12,104 +13,32 @@ using boost::math::differentiation::autodiff_fvar; +/* This can be reworked when we move to std::function */ template -class UniformAutoDiffTable : public UniformLookupTable -{ - friend class func_wrapper; -protected: - - EvaluationFunctor, autodiff_fvar> *mp_boost_func; - - std::unique_ptr m_grid; // pointers to grid and evaluation data - // a LUT array needs to be provided by each implementation - - unsigned m_numIntervals; // sizes of grid and evaluation data - unsigned m_numTableEntries; - - double m_stepSize; // fixed grid spacing (and its inverse) - double m_stepSize_inv; - - double m_tableMaxArg; // > m_maxArg if (m_maxArg-m_minArg)/m_stepSize is non-integer - -public: - - UniformAutoDiffTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); - virtual ~UniformAutoDiffTable(){}; - - /* public access of protected data */ - double step_size(){ return m_stepSize; }; - unsigned num_table_entries(){ return m_numTableEntries; }; - unsigned num_intervals(){ return m_numIntervals; }; - void print_details(std::ostream&) override; - std::pair arg_bounds_of_interval(unsigned); - EvaluationFunctor, autodiff_fvar> *fvar_function(); -}; - -/* This can probably be removed when we move to std::function */ class FuncWrapper : public EvaluationFunctor { public: + // TODO test if this can be simplified with friend + remove warning??? EvaluationFunctor,autodiff_fvar> *fvar_EvalFunctor; - FuncWrapper( *new_EvalFuntor){ fvar_EvalFunctor = new_EvalFunctor; } + FuncWrapper(EvaluationFunctor,autodiff_fvar> *new_EvalFunctor) + { fvar_EvalFunctor = new_EvalFunctor; } double operator()(double x) override { return (double) (*fvar_EvalFunctor)(x); } }; -/* //////////////////////////////////////////////////////////////////////////// - Factory and registration management - - UniformLookupTableFactory: singleton class responsible for - - creating Derived classes of UniformAutoDiffTable - - keeping a registry of derived classes - I ASSUME THERE SHOULD ONLY BE ONE OF THESE -//////////////////////////////////////////////////////////////////////////// */ -class UniformLookupTableFactory +template +class UniformAutoDiffTable : public UniformLookupTable { -public: - // Only ever hand out unique pointers - static std::unique_ptr Create(std::string name, - EvaluationFunctor,autodiff_fvar> *f, - UniformLookupTableParameters par); - // Actual registration function - static void RegisterFactoryFunction(std::string name, - std::function,autodiff_fvar>*,UniformLookupTableParameters)> classFactoryFunction); - // Get all keys from the registry - static std::vector get_registry_keys(void); - -private: - // the actual registry is private to this class - static std::map,autodiff_fvar>*,UniformLookupTableParameters)>>& get_registry(); - // Do NOT implement copy methods - UniformLookupTableFactory(){}; - UniformLookupTableFactory(UniformLookupTableFactory const& copy); - UniformLookupTableFactory& operator=(UniformLookupTableFactory const& copy); -}; + friend class func_wrapper; -/* - Helper class for registering Uniform LUT implementations +protected: + EvaluationFunctor, autodiff_fvar> *mp_boost_func; - NOTE: implementation defined in this header so that templates get - instantiated in derived LUT class files -*/ -template -class UniformLookupTableRegistrar { public: - UniformLookupTableRegistrar(std::string className) - { - UniformLookupTableFactory::RegisterFactoryFunction(className, - [](EvaluationFunctor,autodiff_fvar> *f, UniformLookupTableParameters par) -> UniformAutoDiffTable * { return new T(f, par);}); - } -}; + UniformAutoDiffTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + mp_boost_func(func), UniformLookupTable(new FuncWrapper(mp_boost_func),par){} -/* - Macros for class registration: - - REGISTER_ULUT goes inside class declaration in .hpp - - REGISTER_ULUT_IMPL goes inside .cpp implementation -*/ -#define REGISTER_ULUT(classname) \ -private: \ - static const UniformLookupTableRegistrar registrar; -#define STR_EXPAND(x...) #x -#define STR(x...) STR_EXPAND(x) -#define REGISTER_ULUT_IMPL(classname...) \ - const UniformLookupTableRegistrar classname::registrar(STR(classname)); + virtual ~UniformAutoDiffTable(){}; + + /* public access of protected data */ + EvaluationFunctor,autodiff_fvar> *fvar_function(){ return mp_boost_func; } +}; diff --git a/src/table_types/UniformCubicHermiteTable.cpp b/src/table_types/UniformCubicHermiteTable.cpp index 66dfef9..af020c1 100644 --- a/src/table_types/UniformCubicHermiteTable.cpp +++ b/src/table_types/UniformCubicHermiteTable.cpp @@ -1,12 +1,13 @@ /* Implementation of a UniformPrecomputed Lookup table with linear interpolation */ #include "UniformCubicHermiteTable.hpp" +#include #define IMPL_NAME UniformCubicHermiteTable -REGISTER_ULUT_IMPL(IMPL_NAME); +REGISTER_ULUT_IMPL_DIFF(1,IMPL_NAME); -UniformCubicHermiteTable::UniformCubicHermiteTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformCubicHermiteTable::UniformCubicHermiteTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + UniformAutoDiffTable(func, par) { - /* Base class default variables */ m_name = STR(IMPL_NAME); m_order = 4; diff --git a/src/table_types/UniformCubicHermiteTable.hpp b/src/table_types/UniformCubicHermiteTable.hpp index 5dc26ce..f46b087 100644 --- a/src/table_types/UniformCubicHermiteTable.hpp +++ b/src/table_types/UniformCubicHermiteTable.hpp @@ -11,14 +11,14 @@ - static data after constructor has been called - evaluate by using parentheses, just like a function */ -#include "UniformLookupTable.hpp" +#include "UniformAutoDiffTable.hpp" -class UniformCubicHermiteTable final : public UniformLookupTable +class UniformCubicHermiteTable final : public UniformAutoDiffTable<1> { - REGISTER_ULUT(UniformCubicHermiteTable); + REGISTER_ULUT_DIFF(1,UniformCubicHermiteTable); __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformCubicHermiteTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformCubicHermiteTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformCubicTaylorTable.cpp b/src/table_types/UniformCubicTaylorTable.cpp index 564ee75..cdc7121 100644 --- a/src/table_types/UniformCubicTaylorTable.cpp +++ b/src/table_types/UniformCubicTaylorTable.cpp @@ -1,10 +1,14 @@ /* Implementation of a Uniform Lookup table with linear interpolation */ #include "UniformCubicTaylorTable.hpp" +#include + +using boost::math::differentiation::make_fvar; #define IMPL_NAME UniformCubicTaylorTable -REGISTER_ULUT_IMPL(IMPL_NAME); +REGISTER_ULUT_IMPL_DIFF(3,IMPL_NAME); -UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + UniformAutoDiffTable(func, par) { /* Base class default variables */ m_name = STR(IMPL_NAME); @@ -17,10 +21,11 @@ UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctorderiv(x); - m_table[ii].coefs[2] = func->deriv2(x)/2; - m_table[ii].coefs[3] = func->deriv3(x)/6; + auto const y = (*mp_boost_func)(make_fvar(x)); + m_table[ii].coefs[0] = y.derivative(0); + m_table[ii].coefs[1] = y.derivative(1); + m_table[ii].coefs[2] = y.derivative(2)/2; + m_table[ii].coefs[3] = y.derivative(3)/6; } } diff --git a/src/table_types/UniformCubicTaylorTable.hpp b/src/table_types/UniformCubicTaylorTable.hpp index b8254ba..102bf0e 100644 --- a/src/table_types/UniformCubicTaylorTable.hpp +++ b/src/table_types/UniformCubicTaylorTable.hpp @@ -10,14 +10,15 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformLookupTable.hpp" +#include "UniformAutoDiffTable.hpp" +#include -class UniformCubicTaylorTable final : public UniformLookupTable +class UniformCubicTaylorTable final : public UniformAutoDiffTable<3> { - REGISTER_ULUT(UniformCubicTaylorTable); + REGISTER_ULUT_DIFF(3, UniformCubicTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformCubicTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformCubicTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformLinearTaylorTable.cpp b/src/table_types/UniformLinearTaylorTable.cpp index 5ac5946..8a76227 100644 --- a/src/table_types/UniformLinearTaylorTable.cpp +++ b/src/table_types/UniformLinearTaylorTable.cpp @@ -3,13 +3,13 @@ #include #define IMPL_NAME UniformLinearTaylorTable -REGISTER_ULUT_IMPL(IMPL_NAME); +REGISTER_ULUT_IMPL_DIFF(1,IMPL_NAME); -template -UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - UniformLookupTable(func, par) +using boost::math::differentiation::make_fvar; + +UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + UniformAutoDiffTable(func, par) { - using namespace boost::math::differentiation; /* Base class variables */ m_name = STR(IMPL_NAME); @@ -23,7 +23,7 @@ UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor(x)); + auto const y = (*mp_boost_func)(make_fvar(x)); m_table[ii].coefs[0] = y.derivative(0); m_table[ii].coefs[1] = y.derivative(1); } diff --git a/src/table_types/UniformLinearTaylorTable.hpp b/src/table_types/UniformLinearTaylorTable.hpp index cdda03e..78f6408 100644 --- a/src/table_types/UniformLinearTaylorTable.hpp +++ b/src/table_types/UniformLinearTaylorTable.hpp @@ -10,15 +10,14 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformLookupTable.hpp" +#include "UniformAutoDiffTable.hpp" -class UniformLinearTaylorTable final : public UniformLookupTable +class UniformLinearTaylorTable final : public UniformAutoDiffTable<1> { - REGISTER_ULUT(UniformLinearTaylorTable); + REGISTER_ULUT_DIFF(1,UniformLinearTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; public: - template - UniformLinearTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformLookupTable.cpp b/src/table_types/UniformLookupTable.cpp index a8de147..a35a19d 100644 --- a/src/table_types/UniformLookupTable.cpp +++ b/src/table_types/UniformLookupTable.cpp @@ -43,46 +43,46 @@ void UniformLookupTable::print_details(std::ostream &out) /* //////////////////////////////////////////////////////////////////////////// Factory and registration management //////////////////////////////////////////////////////////////////////////// */ -std::unique_ptr UniformLookupTableFactory::Create(std::string name, - EvaluationFunctor *f, - UniformLookupTableParameters par) -{ - // Create a UniformLookupTable - UniformLookupTable * instance = nullptr; - - // find the name in the registry and call factory method. - auto it = get_registry().find(name); - if(it != get_registry().end()) - instance = it->second(f,par); - - // wrap instance in a unique ptr and return (if created) - if(instance == nullptr) - throw "Table name not found in registry."; // TODO better exception - return std::unique_ptr(instance); -} - -std::vector UniformLookupTableFactory::get_registry_keys() -{ - // copy all keys from the registry map into a vector - std::vector keys; - for (auto const& elem : get_registry() ) { - keys.push_back(elem.first); - } - return keys; -} - -void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, -std::function*,UniformLookupTableParameters)> classFactoryFunction) -{ - // register a derived class factory function - get_registry()[name] = classFactoryFunction; -} - -std::map*,UniformLookupTableParameters)>>& UniformLookupTableFactory::get_registry() -{ - // Get the singleton instance of the registry map - static std::map*,UniformLookupTableParameters)>> registry; - return registry; -} +//std::unique_ptr UniformLookupTableFactory::Create(std::string name, +// EvaluationFunctor *f, +// UniformLookupTableParameters par) +//{ +// // Create a UniformLookupTable +// UniformLookupTable * instance = nullptr; +// +// // find the name in the registry and call factory method. +// auto it = get_registry().find(name); +// if(it != get_registry().end()) +// instance = it->second(f,par); // TODO fix? +// +// // wrap instance in a unique ptr and return (if created) +// if(instance == nullptr) +// throw "Table name not found in registry."; // TODO better exception +// return std::unique_ptr(instance); +//} +// +//std::vector UniformLookupTableFactory::get_registry_keys() +//{ +// // copy all keys from the registry map into a vector +// std::vector keys; +// for (auto const& elem : get_registry() ) { +// keys.push_back(elem.first); +// } +// return keys; +//} +// +//void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, +//std::function*,UniformLookupTableParameters)> classFactoryFunction) +//{ +// // register a derived class factory function +// get_registry()[name] = classFactoryFunction; +//} +// +//std::map*,UniformLookupTableParameters)>>& UniformLookupTableFactory::get_registry() +//{ +// // Get the singleton instance of the registry map +// static std::map*,UniformLookupTableParameters)>> registry; +// return registry; +//} diff --git a/src/table_types/UniformLookupTable.hpp b/src/table_types/UniformLookupTable.hpp index e3d6a74..e6109cb 100644 --- a/src/table_types/UniformLookupTable.hpp +++ b/src/table_types/UniformLookupTable.hpp @@ -3,6 +3,7 @@ */ #pragma once #include "EvaluationImplementation.hpp" +#include #include #include @@ -62,18 +63,56 @@ class UniformLookupTableFactory public: // Only ever hand out unique pointers static std::unique_ptr Create(std::string name, - EvaluationFunctor *f, - UniformLookupTableParameters par); + EvaluationFunctor *f, // make this a data type with 8 functions in it + UniformLookupTableParameters par) + { + // Create a UniformLookupTable + UniformLookupTable * instance = nullptr; + + // find the name in the registry and call factory method. + auto it = get_registry().find(name); + if(it != get_registry().end()){ + // find the index of the function in the function map + instance = it->second(f,par); + } + + // wrap instance in a unique ptr and return (if created) + if(instance == nullptr) + throw "Table name not found in registry."; // TODO better exception + return std::unique_ptr(instance); + + } + // Actual registration function static void RegisterFactoryFunction(std::string name, - std::function*,UniformLookupTableParameters)> classFactoryFunction); + std::function*,UniformLookupTableParameters)> classFactoryFunction) + { + // register a derived class factory function + get_registry()[name] = classFactoryFunction; + } + // Get all keys from the registry - static std::vector get_registry_keys(void); + static std::vector get_registry_keys(void) + { + // copy all keys from the registry map into a vector + std::vector keys; + for (auto const& elem : get_registry() ) { + keys.push_back(elem.first); + } + return keys; + } private: // the actual registry is private to this class static std::map*,UniformLookupTableParameters)>>& get_registry(); + EvaluationFunctor*,UniformLookupTableParameters)>>& get_registry() + { + // Get the singleton instance of the registry map + static std::map*,UniformLookupTableParameters)>> registry; + return registry; + } + // Do NOT implement copy methods UniformLookupTableFactory(){}; UniformLookupTableFactory(UniformLookupTableFactory const& copy); @@ -81,18 +120,28 @@ class UniformLookupTableFactory }; /* - Helper class for registering Uniform LUT implementations + Helper class for registering Uniform LUT implementations. + T is a class name and N is the number of differentiations T needs + in order to be built. NOTE: implementation defined in this header so that templates get instantiated in derived LUT class files */ -template +template class UniformLookupTableRegistrar { public: UniformLookupTableRegistrar(std::string className) { - UniformLookupTableFactory::RegisterFactoryFunction(className, - [](EvaluationFunctor *f, UniformLookupTableParameters par) -> UniformLookupTable * { return new T(f, par);}); + if(N==0){ + UniformLookupTableFactory::RegisterFactoryFunction(className, + [](EvaluationFunctor *f, UniformLookupTableParameters par) -> UniformLookupTable * { return new T(f, par);}); + }else{ + UniformLookupTableFactory::RegisterFactoryFunction(className, + [](EvaluationFunctor,autodiff_fvar> *f, UniformLookupTableParameters par) + -> UniformLookupTable * { return new T(f, par);}); + } + // set num_derivs map + UniformLookupTableFactory::RegisterFactoryFunctionDerivs(className,...); } }; @@ -100,6 +149,8 @@ class UniformLookupTableRegistrar { Macros for class registration: - REGISTER_ULUT goes inside class declaration in .hpp - REGISTER_ULUT_IMPL goes inside .cpp implementation + - *_DIFF are variants of these macros for registering the + differentiation tables (mind the order of args) */ #define REGISTER_ULUT(classname) \ private: \ @@ -108,3 +159,11 @@ private: \ #define STR(x...) STR_EXPAND(x) #define REGISTER_ULUT_IMPL(classname...) \ const UniformLookupTableRegistrar classname::registrar(STR(classname)); + +#define REGISTER_ULUT_DIFF(order,classname) \ +private: \ + static const UniformLookupTableRegistrar> registrar; +#define STR_EXPAND(x...) #x +#define STR(x...) STR_EXPAND(x) +#define REGISTER_ULUT_IMPL_DIFF(order,classname...) \ + const UniformLookupTableRegistrar> classname::registrar(STR(classname)); diff --git a/src/table_types/UniformPadeTable.cpp b/src/table_types/UniformPadeTable.cpp index d15b78c..05d9642 100644 --- a/src/table_types/UniformPadeTable.cpp +++ b/src/table_types/UniformPadeTable.cpp @@ -6,11 +6,11 @@ // The registration looks terrible so it's at the bottom of the class static double const fact[] = {1,1,2,6,24,120,720,5040}; -double (EvaluationFunctor::*derivs[7])(double); +double (EvaluationFunctor::*derivs[7])(double); template -UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, UniformLookupTableParameters par) : - UniformLookupTable(func, par) +UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, UniformLookupTableParameters par) : + UniformAutoDiffTable(func, par) { /* Base class default variables */ m_name = "UniformPadeTable<" + std::to_string(M) + "," + std::to_string(N) + ">"; @@ -19,13 +19,13 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; // assign the first 7 derivatives to the derivs array for easy enumeration - derivs[0]=&EvaluationFunctor::deriv; - derivs[1]=&EvaluationFunctor::deriv2; - derivs[2]=&EvaluationFunctor::deriv3; - derivs[3]=&EvaluationFunctor::deriv4; - derivs[4]=&EvaluationFunctor::deriv5; - derivs[5]=&EvaluationFunctor::deriv6; - derivs[6]=&EvaluationFunctor::deriv7; + derivs[0]=&EvaluationFunctor::deriv; + derivs[1]=&EvaluationFunctor::deriv2; + derivs[2]=&EvaluationFunctor::deriv3; + derivs[3]=&EvaluationFunctor::deriv4; + derivs[4]=&EvaluationFunctor::deriv5; + derivs[5]=&EvaluationFunctor::deriv6; + derivs[6]=&EvaluationFunctor::deriv7; /* Allocate and set table */ m_table.reset(new polynomial[m_numTableEntries]); diff --git a/src/table_types/UniformPadeTable.hpp b/src/table_types/UniformPadeTable.hpp index c4f3cb3..9cac021 100644 --- a/src/table_types/UniformPadeTable.hpp +++ b/src/table_types/UniformPadeTable.hpp @@ -11,19 +11,18 @@ perform that operation every lookup (but does have to look it up) - static data after constructor has been called - evaluate by using parentheses, just like a function - - Available template values are M such that 0 < N <= M and M+N<=7 and the EvaluationFunctor's M+Nth - derivative must be defined. + - Available template values are all M,N such that 0 < N <= M and M+N<=7 */ -#include "UniformLookupTable.hpp" +#include "UniformAutoDiffTable.hpp" template -class UniformPadeTable final : public UniformLookupTable +class UniformPadeTable final : public UniformAutoDiffTable { REGISTER_ULUT(UniformPadeTable); //this one will need some work __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformPadeTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformPadeTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformQuadraticTaylorTable.cpp b/src/table_types/UniformQuadraticTaylorTable.cpp index 7c1db8a..6f8c8a7 100644 --- a/src/table_types/UniformQuadraticTaylorTable.cpp +++ b/src/table_types/UniformQuadraticTaylorTable.cpp @@ -1,10 +1,13 @@ /* Implementation of a Uniform Lookup table with linear interpolation */ #include "UniformQuadraticTaylorTable.hpp" +using boost::math::differentiation::make_fvar; + #define IMPL_NAME UniformQuadraticTaylorTable -REGISTER_ULUT_IMPL(IMPL_NAME); +REGISTER_ULUT_IMPL_DIFF(2,IMPL_NAME); -UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : + UniformAutoDiffTable(func, par) { /* Base class default variables */ m_name = STR(IMPL_NAME); @@ -17,9 +20,10 @@ UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctorderiv(x); - m_table[ii].coefs[2] = func->deriv2(x)/2; + auto const y = (*mp_boost_func)(make_fvar(x)); + m_table[ii].coefs[0] = y.derivative(0); + m_table[ii].coefs[1] = y.derivative(1); + m_table[ii].coefs[2] = y.derivative(2)/2; } } diff --git a/src/table_types/UniformQuadraticTaylorTable.hpp b/src/table_types/UniformQuadraticTaylorTable.hpp index e116795..b11138e 100644 --- a/src/table_types/UniformQuadraticTaylorTable.hpp +++ b/src/table_types/UniformQuadraticTaylorTable.hpp @@ -10,16 +10,14 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformLookupTable.hpp" +#include "UniformAutoDiffTable.hpp" -#include - -class UniformQuadraticTaylorTable final : public UniformLookupTable +class UniformQuadraticTaylorTable final : public UniformAutoDiffTable<2> { - REGISTER_ULUT(UniformQuadraticTaylorTable); + REGISTER_ULUT_DIFF(2,UniformQuadraticTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformQuadraticTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformQuadraticTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); double operator()(double x) override; }; From 8b649aec7eb7f18f1c7bb25cfe86c3c5a0a7e876 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:23:24 -0600 Subject: [PATCH 13/21] Added a FunctionContainer class to EvaluationFunctor which can hold on to/give access to several copies of a user's math function --- src/EvaluationFunctor.hpp | 115 +++++++++++++++++++++++++++++++++----- src/FunctionHelper.hpp | 21 ------- 2 files changed, 102 insertions(+), 34 deletions(-) delete mode 100644 src/FunctionHelper.hpp diff --git a/src/EvaluationFunctor.hpp b/src/EvaluationFunctor.hpp index ba12d76..066592d 100644 --- a/src/EvaluationFunctor.hpp +++ b/src/EvaluationFunctor.hpp @@ -1,27 +1,116 @@ /* - Virtual base functor for evaluating a mathematical function + * will soon rename this file to FunctionContainer + Virtual base functor for evaluating a mathematical function along with + the data structure used to pass this - needed for combining evaluation and derivative(s) evaluation so that Taylor and Interpolation tables can have the same interface + - easy (though obtuse) to use if mathematical functions are templated + - copy and paste the following example code into a new file and use + the command :%s/new_name/foo/g in vim or (TODO something else) in emacs + to write your own function. + + Example usage: + #include EvaluationFunctor.hpp + // this could just be a function when we move to std::function + template + struct foo : EvaluationFunctor + { + T operator()(T x){ return x; } + }; + + int main(){ + // these 'new' memory allocations can be removed when we move to std::function + FunctionContainer foo_container{new foo, new foo, + new foo, new foo, new foo, + new foo, new foo, new foo}; + // or just + // FunctionContainer foo_container; + // foo_container.double_func = new foo; + // if you're not using any Taylor/Pade/Hermite tables + // (the compiler will warn you) + return 0; + } */ #pragma once +#include +#include +#include + +using boost::math::differentiation::autodiff_fvar; +typedef autodiff_fvar fvar1; +typedef autodiff_fvar fvar2; +typedef autodiff_fvar fvar3; +typedef autodiff_fvar fvar4; +typedef autodiff_fvar fvar5; +typedef autodiff_fvar fvar6; +typedef autodiff_fvar fvar7; -// TODO use a better exception type -#define NOT_DEFINED(ORDER) \ - throw ORDER" derivative not defined."; \ - return 0; +/* Used by each table type to check if the required function + * type has been provided. + * TODO decide whether or not to make this null for -DNDEBUG */ +#define __IS_NULLPTR(VAR) \ + if(VAR == nullptr) \ + throw std::invalid_argument(#VAR " is a nullptr") template class EvaluationFunctor { public: virtual OUT_TYPE operator()(IN_TYPE x) = 0; - /* Raise an exception in these by default? */ - virtual OUT_TYPE deriv(IN_TYPE x){ NOT_DEFINED("1st"); }; - virtual OUT_TYPE deriv2(IN_TYPE x){ NOT_DEFINED("2nd"); }; - virtual OUT_TYPE deriv3(IN_TYPE x){ NOT_DEFINED("3rd"); }; - virtual OUT_TYPE deriv4(IN_TYPE x){ NOT_DEFINED("4th"); }; - virtual OUT_TYPE deriv5(IN_TYPE x){ NOT_DEFINED("5th"); }; - virtual OUT_TYPE deriv6(IN_TYPE x){ NOT_DEFINED("6th"); }; - virtual OUT_TYPE deriv7(IN_TYPE x){ NOT_DEFINED("7th"); }; +}; + + +class FunctionContainer +{ + // create a set of structs so we can specify function signatures + // (ie, number of differentiaions needed) with an index + template + struct func_type{ + using type = EvaluationFunctor,autodiff_fvar>*; + }; + // special case for N=0 + template<> + struct func_type<0>{ + using type = EvaluationFunctor*; + }; + +public: + // will become 'std::function type_func' + EvaluationFunctor *double_func; + EvaluationFunctor *fvar1_func; + EvaluationFunctor *fvar2_func; + EvaluationFunctor *fvar3_func; + EvaluationFunctor *fvar4_func; + EvaluationFunctor *fvar5_func; + EvaluationFunctor *fvar6_func; + EvaluationFunctor *fvar7_func; + + // provide a method for accessing each member function uniformly + // call as 'get_nth_func()' for N auto derivatives + template typename func_type::type get_nth_func() + { + throw std::out_of_range("Template value must be in 0<=N<=7"); + }; + template<> typename func_type<0>::type get_nth_func<0>() { return double_func; }; + template<> typename func_type<1>::type get_nth_func<1>() { return fvar1_func; }; + template<> typename func_type<2>::type get_nth_func<2>() { return fvar2_func; }; + template<> typename func_type<3>::type get_nth_func<3>() { return fvar3_func; }; + template<> typename func_type<4>::type get_nth_func<4>() { return fvar4_func; }; + template<> typename func_type<5>::type get_nth_func<5>() { return fvar5_func; }; + template<> typename func_type<6>::type get_nth_func<6>() { return fvar6_func; }; + template<> typename func_type<7>::type get_nth_func<7>() { return fvar7_func; }; + + // some constructors + FunctionContainer(){} + + FunctionContainer(EvaluationFunctor *func, + EvaluationFunctor *func1, EvaluationFunctor *func2, + EvaluationFunctor *func3, EvaluationFunctor *func4, + EvaluationFunctor *func5, EvaluationFunctor *func6, + EvaluationFunctor *func7) : + double_func(func), fvar1_func(func1), + fvar2_func(func2), fvar3_func(func3), + fvar4_func(func4), fvar5_func(func5), + fvar6_func(func6), fvar7_func(func7) {} }; diff --git a/src/FunctionHelper.hpp b/src/FunctionHelper.hpp deleted file mode 100644 index 5f1cd04..0000000 --- a/src/FunctionHelper.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#include - -using boost::math::differentiation::autodiff_fvar; -typedef autodiff_fvar fvar1; -typedef autodiff_fvar fvar2; -typedef autodiff_fvar fvar3; -typedef autodiff_fvar fvar4; -typedef autodiff_fvar fvar5; -typedef autodiff_fvar fvar6; -typedef autodiff_fvar fvar7; - -struct FunctionHelper{ - EvaluationFunctor *double_func; - EvaluationFunctor *fvar1_func; - EvaluationFunctor *fvar2_func; - EvaluationFunctor *fvar3_func; - EvaluationFunctor *fvar4_func; - EvaluationFunctor *fvar5_func; - EvaluationFunctor *fvar6_func; - EvaluationFunctor *fvar7_func; -} From a69e3ecdddbf94ca278930f7fee484bee2384785 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:26:17 -0600 Subject: [PATCH 14/21] Table generation takes advantage of automatic differentiation --- .../UniformConstantTaylorTable.cpp | 4 +-- .../UniformConstantTaylorTable.hpp | 2 +- src/table_types/UniformCubicHermiteTable.cpp | 24 ++++++++----- src/table_types/UniformCubicHermiteTable.hpp | 10 +++--- src/table_types/UniformCubicTaylorTable.cpp | 21 ++++++----- src/table_types/UniformCubicTaylorTable.hpp | 11 +++--- src/table_types/UniformLinearTaylorTable.cpp | 19 +++++----- src/table_types/UniformLinearTaylorTable.hpp | 10 +++--- src/table_types/UniformPadeTable.cpp | 35 ++++++++----------- src/table_types/UniformPadeTable.hpp | 10 +++--- .../UniformQuadraticTaylorTable.cpp | 17 +++++---- .../UniformQuadraticTaylorTable.hpp | 10 +++--- 12 files changed, 96 insertions(+), 77 deletions(-) diff --git a/src/table_types/UniformConstantTaylorTable.cpp b/src/table_types/UniformConstantTaylorTable.cpp index f421aaf..02705ab 100644 --- a/src/table_types/UniformConstantTaylorTable.cpp +++ b/src/table_types/UniformConstantTaylorTable.cpp @@ -4,8 +4,8 @@ #define IMPL_NAME UniformConstantTaylorTable REGISTER_ULUT_IMPL(IMPL_NAME); - -UniformConstantTaylorTable::UniformConstantTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformConstantTaylorTable::UniformConstantTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ diff --git a/src/table_types/UniformConstantTaylorTable.hpp b/src/table_types/UniformConstantTaylorTable.hpp index 7c8648f..e72ea05 100644 --- a/src/table_types/UniformConstantTaylorTable.hpp +++ b/src/table_types/UniformConstantTaylorTable.hpp @@ -18,6 +18,6 @@ class UniformConstantTaylorTable final : public UniformLookupTable __attribute__((aligned)) std::unique_ptr m_table; public: - UniformConstantTaylorTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformConstantTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformCubicHermiteTable.cpp b/src/table_types/UniformCubicHermiteTable.cpp index af020c1..7f29c6a 100644 --- a/src/table_types/UniformCubicHermiteTable.cpp +++ b/src/table_types/UniformCubicHermiteTable.cpp @@ -3,27 +3,35 @@ #include #define IMPL_NAME UniformCubicHermiteTable -REGISTER_ULUT_IMPL_DIFF(1,IMPL_NAME); +REGISTER_ULUT_IMPL(IMPL_NAME); -UniformCubicHermiteTable::UniformCubicHermiteTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - UniformAutoDiffTable(func, par) +UniformCubicHermiteTable::UniformCubicHermiteTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { + using boost::math::differentiation::make_fvar; /* Base class default variables */ m_name = STR(IMPL_NAME); m_order = 4; m_numTableEntries = m_numIntervals+1; m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; + __IS_NULLPTR(func_container->fvar1_func); + mp_boost_func = func_container->fvar1_func; + /* Allocate and set table */ m_table.reset(new polynomial<4,32>[m_numTableEntries]); for (int ii=0; iideriv(x); - const double y1 = (*mp_func)(x+m_stepSize); - const double m1 = mp_func->deriv(x+m_stepSize); - m_table[ii].coefs[0] = y0; + + const auto derivs0 = (*mp_boost_func)(make_fvar(x)); + const double y0 = derivs0.derivative(0); + const double m0 = derivs0.derivative(1); + const auto derivs1 = (*mp_boost_func)(make_fvar(x+m_stepSize)); + const double y1 = derivs1.derivative(0); + const double m1 = derivs1.derivative(1); + + m_table[ii].coefs[0] = y0; m_table[ii].coefs[1] = m_stepSize*m0; m_table[ii].coefs[2] = -3*y0+3*y1-(2*m0+m1)*m_stepSize; m_table[ii].coefs[3] = 2*y0-2*y1+(m0+m1)*m_stepSize; diff --git a/src/table_types/UniformCubicHermiteTable.hpp b/src/table_types/UniformCubicHermiteTable.hpp index f46b087..e469bd9 100644 --- a/src/table_types/UniformCubicHermiteTable.hpp +++ b/src/table_types/UniformCubicHermiteTable.hpp @@ -11,14 +11,16 @@ - static data after constructor has been called - evaluate by using parentheses, just like a function */ -#include "UniformAutoDiffTable.hpp" +#include "UniformLookupTable.hpp" -class UniformCubicHermiteTable final : public UniformAutoDiffTable<1> +class UniformCubicHermiteTable final : public UniformLookupTable { - REGISTER_ULUT_DIFF(1,UniformCubicHermiteTable); + REGISTER_ULUT(UniformCubicHermiteTable); __attribute__((aligned)) std::unique_ptr[]> m_table; + EvaluationFunctor *mp_boost_func; public: - UniformCubicHermiteTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + UniformCubicHermiteTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; + EvaluationFunctor *boost_function(){ return mp_boost_func; } }; diff --git a/src/table_types/UniformCubicTaylorTable.cpp b/src/table_types/UniformCubicTaylorTable.cpp index cdc7121..7430a68 100644 --- a/src/table_types/UniformCubicTaylorTable.cpp +++ b/src/table_types/UniformCubicTaylorTable.cpp @@ -1,14 +1,13 @@ /* Implementation of a Uniform Lookup table with linear interpolation */ #include "UniformCubicTaylorTable.hpp" -#include using boost::math::differentiation::make_fvar; #define IMPL_NAME UniformCubicTaylorTable -REGISTER_ULUT_IMPL_DIFF(3,IMPL_NAME); +REGISTER_ULUT_IMPL(IMPL_NAME); -UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - UniformAutoDiffTable(func, par) +UniformCubicTaylorTable::UniformCubicTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ m_name = STR(IMPL_NAME); @@ -16,16 +15,20 @@ UniformCubicTaylorTable::UniformCubicTaylorTable(EvaluationFunctorfvar3_func); + mp_boost_func = func_container->fvar3_func; + /* Allocate and set table */ m_table.reset(new polynomial<4,32>[m_numTableEntries]); for (int ii=0;ii(x)); - m_table[ii].coefs[0] = y.derivative(0); - m_table[ii].coefs[1] = y.derivative(1); - m_table[ii].coefs[2] = y.derivative(2)/2; - m_table[ii].coefs[3] = y.derivative(3)/6; + auto const derivs = (*mp_boost_func)(make_fvar(x)); + + m_table[ii].coefs[0] = derivs.derivative(0); + m_table[ii].coefs[1] = derivs.derivative(1); + m_table[ii].coefs[2] = derivs.derivative(2)/2; + m_table[ii].coefs[3] = derivs.derivative(3)/6; } } diff --git a/src/table_types/UniformCubicTaylorTable.hpp b/src/table_types/UniformCubicTaylorTable.hpp index 102bf0e..fcfd7f8 100644 --- a/src/table_types/UniformCubicTaylorTable.hpp +++ b/src/table_types/UniformCubicTaylorTable.hpp @@ -10,15 +10,16 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformAutoDiffTable.hpp" -#include +#include "UniformLookupTable.hpp" -class UniformCubicTaylorTable final : public UniformAutoDiffTable<3> +class UniformCubicTaylorTable final : public UniformLookupTable { - REGISTER_ULUT_DIFF(3, UniformCubicTaylorTable); + REGISTER_ULUT(UniformCubicTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; + EvaluationFunctor *mp_boost_func; public: - UniformCubicTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + UniformCubicTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; + EvaluationFunctor *boost_function(){ return mp_boost_func; } }; diff --git a/src/table_types/UniformLinearTaylorTable.cpp b/src/table_types/UniformLinearTaylorTable.cpp index 8a76227..978b5ea 100644 --- a/src/table_types/UniformLinearTaylorTable.cpp +++ b/src/table_types/UniformLinearTaylorTable.cpp @@ -1,15 +1,13 @@ /* Implementation of a Uniform Lookup table with linear interpolation */ #include "UniformLinearTaylorTable.hpp" -#include #define IMPL_NAME UniformLinearTaylorTable -REGISTER_ULUT_IMPL_DIFF(1,IMPL_NAME); +REGISTER_ULUT_IMPL(IMPL_NAME); -using boost::math::differentiation::make_fvar; - -UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - UniformAutoDiffTable(func, par) +UniformLinearTaylorTable::UniformLinearTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { + using boost::math::differentiation::make_fvar; /* Base class variables */ m_name = STR(IMPL_NAME); @@ -17,15 +15,18 @@ UniformLinearTaylorTable::UniformLinearTaylorTable(EvaluationFunctorfvar1_func); + mp_boost_func = func_container->fvar1_func; + /* Allocate and set table */ m_table.reset(new polynomial<2,16>[m_numTableEntries]); for (int ii=0; ii(x)); - m_table[ii].coefs[0] = y.derivative(0); - m_table[ii].coefs[1] = y.derivative(1); + auto const derivs = (*mp_boost_func)(make_fvar(x)); + m_table[ii].coefs[0] = derivs.derivative(0); + m_table[ii].coefs[1] = derivs.derivative(1); } } diff --git a/src/table_types/UniformLinearTaylorTable.hpp b/src/table_types/UniformLinearTaylorTable.hpp index 78f6408..3818199 100644 --- a/src/table_types/UniformLinearTaylorTable.hpp +++ b/src/table_types/UniformLinearTaylorTable.hpp @@ -10,14 +10,16 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformAutoDiffTable.hpp" +#include "UniformLookupTable.hpp" -class UniformLinearTaylorTable final : public UniformAutoDiffTable<1> +class UniformLinearTaylorTable final : public UniformLookupTable { - REGISTER_ULUT_DIFF(1,UniformLinearTaylorTable); + REGISTER_ULUT(UniformLinearTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; + EvaluationFunctor *mp_boost_func; public: - UniformLinearTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + UniformLinearTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; + EvaluationFunctor *boost_function(){ return mp_boost_func; } }; diff --git a/src/table_types/UniformPadeTable.cpp b/src/table_types/UniformPadeTable.cpp index 05d9642..1040f4f 100644 --- a/src/table_types/UniformPadeTable.cpp +++ b/src/table_types/UniformPadeTable.cpp @@ -2,15 +2,16 @@ #include "UniformPadeTable.hpp" #include #include +#include // The registration looks terrible so it's at the bottom of the class +using boost::math::differentiation::make_fvar; static double const fact[] = {1,1,2,6,24,120,720,5040}; -double (EvaluationFunctor::*derivs[7])(double); template -UniformPadeTable::UniformPadeTable(EvaluationFunctor *func, UniformLookupTableParameters par) : - UniformAutoDiffTable(func, par) +UniformPadeTable::UniformPadeTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ m_name = "UniformPadeTable<" + std::to_string(M) + "," + std::to_string(N) + ">"; @@ -18,14 +19,8 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor m_numTableEntries = m_numIntervals+1; m_dataSize = (unsigned) sizeof(m_table[0]) * m_numTableEntries; - // assign the first 7 derivatives to the derivs array for easy enumeration - derivs[0]=&EvaluationFunctor::deriv; - derivs[1]=&EvaluationFunctor::deriv2; - derivs[2]=&EvaluationFunctor::deriv3; - derivs[3]=&EvaluationFunctor::deriv4; - derivs[4]=&EvaluationFunctor::deriv5; - derivs[5]=&EvaluationFunctor::deriv6; - derivs[6]=&EvaluationFunctor::deriv7; + __IS_NULLPTR(func_container->get_nth_func()); // the least descriptive exception + mp_boost_func = func_container->get_nth_func(); /* Allocate and set table */ m_table.reset(new polynomial[m_numTableEntries]); @@ -36,24 +31,24 @@ UniformPadeTable::UniformPadeTable(EvaluationFunctor // build the matrix of taylor coefficients arma::mat T = arma::zeros(M+N+1, N+1); - T(0,0) = (*func)(x); - for(unsigned int i=1; i*(derivs[i-1]))(x)/(fact[i]); - + const auto derivs = (*mp_boost_func)(make_fvar(x)); + for(unsigned int i=0; i 1){ // Arma could throw an exception if Q isn't a vector but this is more descriptive - throw "Pade table of order [" + std::to_string(M) + "/" + std::to_string(N) + "] does not exist."; + arma::mat Q = arma::null(T.rows(M+1, M+N)); + // TODO check if this is useful + if(Q.n_cols > 1){ // Arma could throw an exception if Q isn't a vector but this is more descriptive TODO better exception + throw std::domain_error("Pade table of order [" + std::to_string(M) + "/" + std::to_string(N) + "] does not exist."); return; } // scale Q such that its first entry equals 1. - Q=Q/Q[0]; + Q=Q/Q[0]; // find the coefficients of P arma::vec P = T.rows(0,M)*Q; diff --git a/src/table_types/UniformPadeTable.hpp b/src/table_types/UniformPadeTable.hpp index 9cac021..69c2847 100644 --- a/src/table_types/UniformPadeTable.hpp +++ b/src/table_types/UniformPadeTable.hpp @@ -13,16 +13,18 @@ - evaluate by using parentheses, just like a function - Available template values are all M,N such that 0 < N <= M and M+N<=7 */ -#include "UniformAutoDiffTable.hpp" +#include "UniformLookupTable.hpp" template -class UniformPadeTable final : public UniformAutoDiffTable +class UniformPadeTable final : public UniformLookupTable { REGISTER_ULUT(UniformPadeTable); - //this one will need some work + // mind the lesser than sign -> | __attribute__((aligned)) std::unique_ptr[]> m_table; + EvaluationFunctor,autodiff_fvar> *mp_boost_func; public: - UniformPadeTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + UniformPadeTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; + EvaluationFunctor,autodiff_fvar> *boost_function(){ return mp_boost_func; } }; diff --git a/src/table_types/UniformQuadraticTaylorTable.cpp b/src/table_types/UniformQuadraticTaylorTable.cpp index 6f8c8a7..7a20bfb 100644 --- a/src/table_types/UniformQuadraticTaylorTable.cpp +++ b/src/table_types/UniformQuadraticTaylorTable.cpp @@ -4,10 +4,10 @@ using boost::math::differentiation::make_fvar; #define IMPL_NAME UniformQuadraticTaylorTable -REGISTER_ULUT_IMPL_DIFF(2,IMPL_NAME); +REGISTER_ULUT_IMPL(IMPL_NAME); -UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - UniformAutoDiffTable(func, par) +UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ m_name = STR(IMPL_NAME); @@ -15,15 +15,18 @@ UniformQuadraticTaylorTable::UniformQuadraticTaylorTable(EvaluationFunctorfvar2_func); + mp_boost_func = func_container->fvar2_func; + /* Allocate and set table */ m_table.reset(new polynomial<3,32>[m_numTableEntries]); for (int ii=0;ii(x)); - m_table[ii].coefs[0] = y.derivative(0); - m_table[ii].coefs[1] = y.derivative(1); - m_table[ii].coefs[2] = y.derivative(2)/2; + auto const derivs = (*mp_boost_func)(make_fvar(x)); + m_table[ii].coefs[0] = derivs.derivative(0); + m_table[ii].coefs[1] = derivs.derivative(1); + m_table[ii].coefs[2] = derivs.derivative(2)/2; } } diff --git a/src/table_types/UniformQuadraticTaylorTable.hpp b/src/table_types/UniformQuadraticTaylorTable.hpp index b11138e..e689ffe 100644 --- a/src/table_types/UniformQuadraticTaylorTable.hpp +++ b/src/table_types/UniformQuadraticTaylorTable.hpp @@ -10,14 +10,16 @@ - evaluate by using parentheses, just like a function */ #pragma once -#include "UniformAutoDiffTable.hpp" +#include "UniformLookupTable.hpp" -class UniformQuadraticTaylorTable final : public UniformAutoDiffTable<2> +class UniformQuadraticTaylorTable final : public UniformLookupTable { - REGISTER_ULUT_DIFF(2,UniformQuadraticTaylorTable); + REGISTER_ULUT(UniformQuadraticTaylorTable); __attribute__((aligned)) std::unique_ptr[]> m_table; + EvaluationFunctor *mp_boost_func; public: - UniformQuadraticTaylorTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par); + UniformQuadraticTaylorTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; + EvaluationFunctor *boost_function(){ return mp_boost_func; } }; From a973f56564cfcedd02dd08e1a3892e32e4657abc Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:28:57 -0600 Subject: [PATCH 15/21] Now takes FunctionContainer as an arg, plus better exceptions added --- src/table_types/UniformLookupTable.cpp | 90 +++++++++++++------------- src/table_types/UniformLookupTable.hpp | 77 +++------------------- 2 files changed, 55 insertions(+), 112 deletions(-) diff --git a/src/table_types/UniformLookupTable.cpp b/src/table_types/UniformLookupTable.cpp index a35a19d..e8b2880 100644 --- a/src/table_types/UniformLookupTable.cpp +++ b/src/table_types/UniformLookupTable.cpp @@ -3,8 +3,10 @@ #include #include +#include -UniformLookupTable::UniformLookupTable(EvaluationFunctor *func, UniformLookupTableParameters par) : EvaluationImplementation(func, "uniform_lookup_table") +UniformLookupTable::UniformLookupTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + EvaluationImplementation(func_container->double_func, "uniform_lookup_table") { /* Base class variables */ @@ -43,46 +45,46 @@ void UniformLookupTable::print_details(std::ostream &out) /* //////////////////////////////////////////////////////////////////////////// Factory and registration management //////////////////////////////////////////////////////////////////////////// */ -//std::unique_ptr UniformLookupTableFactory::Create(std::string name, -// EvaluationFunctor *f, -// UniformLookupTableParameters par) -//{ -// // Create a UniformLookupTable -// UniformLookupTable * instance = nullptr; -// -// // find the name in the registry and call factory method. -// auto it = get_registry().find(name); -// if(it != get_registry().end()) -// instance = it->second(f,par); // TODO fix? -// -// // wrap instance in a unique ptr and return (if created) -// if(instance == nullptr) -// throw "Table name not found in registry."; // TODO better exception -// return std::unique_ptr(instance); -//} -// -//std::vector UniformLookupTableFactory::get_registry_keys() -//{ -// // copy all keys from the registry map into a vector -// std::vector keys; -// for (auto const& elem : get_registry() ) { -// keys.push_back(elem.first); -// } -// return keys; -//} -// -//void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, -//std::function*,UniformLookupTableParameters)> classFactoryFunction) -//{ -// // register a derived class factory function -// get_registry()[name] = classFactoryFunction; -//} -// -//std::map*,UniformLookupTableParameters)>>& UniformLookupTableFactory::get_registry() -//{ -// // Get the singleton instance of the registry map -// static std::map*,UniformLookupTableParameters)>> registry; -// return registry; -//} +std::unique_ptr UniformLookupTableFactory::Create(std::string name, + FunctionContainer *fc, + UniformLookupTableParameters par) +{ + // Create a UniformLookupTable + UniformLookupTable * instance = nullptr; + + // find the name in the registry and call factory method. + auto it = get_registry().find(name); + if(it != get_registry().end()) + instance = it->second(fc,par); + + // wrap instance in a unique ptr and return (if created) + if(instance == nullptr) + throw std::invalid_argument(name + " not found in registry."); + return std::unique_ptr(instance); +} + +std::vector UniformLookupTableFactory::get_registry_keys() +{ + // copy all keys from the registry map into a vector + std::vector keys; + for (auto const& elem : get_registry() ) { + keys.push_back(elem.first); + } + return keys; +} + +void UniformLookupTableFactory::RegisterFactoryFunction(std::string name, +std::function classFactoryFunction) +{ + // register a derived class factory function + get_registry()[name] = classFactoryFunction; +} + +std::map>& UniformLookupTableFactory::get_registry() +{ + // Get the singleton instance of the registry map + static std::map> registry; + return registry; +} diff --git a/src/table_types/UniformLookupTable.hpp b/src/table_types/UniformLookupTable.hpp index e6109cb..9d0cb07 100644 --- a/src/table_types/UniformLookupTable.hpp +++ b/src/table_types/UniformLookupTable.hpp @@ -3,7 +3,6 @@ */ #pragma once #include "EvaluationImplementation.hpp" -#include #include #include @@ -40,7 +39,7 @@ class UniformLookupTable : public EvaluationImplementation public: - UniformLookupTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformLookupTable(FunctionContainer *func_container, UniformLookupTableParameters par); virtual ~UniformLookupTable(){}; /* public access of protected data */ @@ -63,56 +62,18 @@ class UniformLookupTableFactory public: // Only ever hand out unique pointers static std::unique_ptr Create(std::string name, - EvaluationFunctor *f, // make this a data type with 8 functions in it - UniformLookupTableParameters par) - { - // Create a UniformLookupTable - UniformLookupTable * instance = nullptr; - - // find the name in the registry and call factory method. - auto it = get_registry().find(name); - if(it != get_registry().end()){ - // find the index of the function in the function map - instance = it->second(f,par); - } - - // wrap instance in a unique ptr and return (if created) - if(instance == nullptr) - throw "Table name not found in registry."; // TODO better exception - return std::unique_ptr(instance); - - } - + FunctionContainer *fc, + UniformLookupTableParameters par); // Actual registration function static void RegisterFactoryFunction(std::string name, - std::function*,UniformLookupTableParameters)> classFactoryFunction) - { - // register a derived class factory function - get_registry()[name] = classFactoryFunction; - } - + std::function classFactoryFunction); // Get all keys from the registry - static std::vector get_registry_keys(void) - { - // copy all keys from the registry map into a vector - std::vector keys; - for (auto const& elem : get_registry() ) { - keys.push_back(elem.first); - } - return keys; - } + static std::vector get_registry_keys(void); private: // the actual registry is private to this class static std::map*,UniformLookupTableParameters)>>& get_registry() - { - // Get the singleton instance of the registry map - static std::map*,UniformLookupTableParameters)>> registry; - return registry; - } - + FunctionContainer*,UniformLookupTableParameters)>>& get_registry(); // Do NOT implement copy methods UniformLookupTableFactory(){}; UniformLookupTableFactory(UniformLookupTableFactory const& copy); @@ -121,27 +82,17 @@ class UniformLookupTableFactory /* Helper class for registering Uniform LUT implementations. - T is a class name and N is the number of differentiations T needs - in order to be built. NOTE: implementation defined in this header so that templates get instantiated in derived LUT class files */ -template +template class UniformLookupTableRegistrar { public: UniformLookupTableRegistrar(std::string className) { - if(N==0){ - UniformLookupTableFactory::RegisterFactoryFunction(className, - [](EvaluationFunctor *f, UniformLookupTableParameters par) -> UniformLookupTable * { return new T(f, par);}); - }else{ - UniformLookupTableFactory::RegisterFactoryFunction(className, - [](EvaluationFunctor,autodiff_fvar> *f, UniformLookupTableParameters par) - -> UniformLookupTable * { return new T(f, par);}); - } - // set num_derivs map - UniformLookupTableFactory::RegisterFactoryFunctionDerivs(className,...); + UniformLookupTableFactory::RegisterFactoryFunction(className, + [](FunctionContainer *fc, UniformLookupTableParameters par) -> UniformLookupTable * { return new T(fc, par);}); } }; @@ -149,8 +100,6 @@ class UniformLookupTableRegistrar { Macros for class registration: - REGISTER_ULUT goes inside class declaration in .hpp - REGISTER_ULUT_IMPL goes inside .cpp implementation - - *_DIFF are variants of these macros for registering the - differentiation tables (mind the order of args) */ #define REGISTER_ULUT(classname) \ private: \ @@ -159,11 +108,3 @@ private: \ #define STR(x...) STR_EXPAND(x) #define REGISTER_ULUT_IMPL(classname...) \ const UniformLookupTableRegistrar classname::registrar(STR(classname)); - -#define REGISTER_ULUT_DIFF(order,classname) \ -private: \ - static const UniformLookupTableRegistrar> registrar; -#define STR_EXPAND(x...) #x -#define STR(x...) STR_EXPAND(x) -#define REGISTER_ULUT_IMPL_DIFF(order,classname...) \ - const UniformLookupTableRegistrar> classname::registrar(STR(classname)); From be302bc981c05d6ab7885431935935be8612de02 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:30:21 -0600 Subject: [PATCH 16/21] Now take FunctionContainer instead of EvaluationFunctor as constructor arg --- ...ormArmadilloPrecomputedInterpolationTable.cpp | 6 +++--- ...ormArmadilloPrecomputedInterpolationTable.hpp | 2 +- ...UniformCubicPrecomputedInterpolationTable.cpp | 3 ++- ...UniformCubicPrecomputedInterpolationTable.hpp | 2 +- src/table_types/UniformFailureProofTable.cpp | 16 ++++++++-------- .../UniformLinearInterpolationTable.cpp | 3 ++- .../UniformLinearInterpolationTable.hpp | 2 +- ...niformLinearPrecomputedInterpolationTable.cpp | 3 ++- ...niformLinearPrecomputedInterpolationTable.hpp | 2 +- ...ormQuadraticPrecomputedInterpolationTable.cpp | 3 ++- ...ormQuadraticPrecomputedInterpolationTable.hpp | 4 +--- 11 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp index 881b57d..dfa1ce4 100644 --- a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.cpp @@ -2,7 +2,7 @@ #include "UniformArmadilloPrecomputedInterpolationTable.hpp" #include -#define SOLVE_OPTS arma::solve_opts::refine +#define SOLVE_OPTS arma::solve_opts::none // Template substitution happens way after the preprocessor does it's work so // we'll register all the available template values this way @@ -12,8 +12,8 @@ template<>REGISTER_ULUT_IMPL(UniformArmadilloPrecomputedInterpolationTable<6>); template<>REGISTER_ULUT_IMPL(UniformArmadilloPrecomputedInterpolationTable<7>); template -UniformArmadilloPrecomputedInterpolationTable::UniformArmadilloPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : - UniformLookupTable(func, par) +UniformArmadilloPrecomputedInterpolationTable::UniformArmadilloPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ m_name = "UniformArmadilloPrecomputedInterpolationTable<" + std::to_string(N) + ">"; diff --git a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp index 5233721..d74f77b 100644 --- a/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp +++ b/src/table_types/UniformArmadilloPrecomputedInterpolationTable.hpp @@ -23,6 +23,6 @@ class UniformArmadilloPrecomputedInterpolationTable final : public UniformLookup __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformArmadilloPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformArmadilloPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp b/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp index 4a64d35..eca984e 100644 --- a/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformCubicPrecomputedInterpolationTable.cpp @@ -4,7 +4,8 @@ #define IMPL_NAME UniformCubicPrecomputedInterpolationTable REGISTER_ULUT_IMPL(IMPL_NAME); -UniformCubicPrecomputedInterpolationTable::UniformCubicPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformCubicPrecomputedInterpolationTable::UniformCubicPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ diff --git a/src/table_types/UniformCubicPrecomputedInterpolationTable.hpp b/src/table_types/UniformCubicPrecomputedInterpolationTable.hpp index 797a8d9..57392a7 100644 --- a/src/table_types/UniformCubicPrecomputedInterpolationTable.hpp +++ b/src/table_types/UniformCubicPrecomputedInterpolationTable.hpp @@ -19,6 +19,6 @@ class UniformCubicPrecomputedInterpolationTable final : public UniformLookupTabl __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformCubicPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformCubicPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformFailureProofTable.cpp b/src/table_types/UniformFailureProofTable.cpp index 7f1cd79..d1bc7c6 100644 --- a/src/table_types/UniformFailureProofTable.cpp +++ b/src/table_types/UniformFailureProofTable.cpp @@ -4,8 +4,8 @@ #define RECORD_ARG(x) #define PRINT_ARGS(out) #else - #include #include + #include #include // make sure we don't swallow the semicolon @@ -29,15 +29,15 @@ #endif // copy everything from the given LUT -UniformFailureProofTable::UniformFailureProofTable(std::unique_ptr LUT) : +UniformFailureProofTable::UniformFailureProofTable(std::unique_ptr LUT) : mp_LUT(std::move(LUT)) { - mp_func = mp_LUT->function(); - m_minArg = mp_LUT->min_arg(); - m_maxArg = mp_LUT->max_arg(); - m_order = mp_LUT->order(); - m_name = mp_LUT->name(); - m_dataSize = mp_LUT->size(); + mp_func = mp_LUT->function(); + m_minArg = mp_LUT->min_arg(); + m_maxArg = mp_LUT->max_arg(); + m_order = mp_LUT->order(); + m_name = mp_LUT->name(); + m_dataSize = mp_LUT->size(); } double UniformFailureProofTable::operator()(double x) diff --git a/src/table_types/UniformLinearInterpolationTable.cpp b/src/table_types/UniformLinearInterpolationTable.cpp index c22f71c..4d74b04 100644 --- a/src/table_types/UniformLinearInterpolationTable.cpp +++ b/src/table_types/UniformLinearInterpolationTable.cpp @@ -4,7 +4,8 @@ #define IMPL_NAME UniformLinearInterpolationTable REGISTER_ULUT_IMPL(IMPL_NAME); -UniformLinearInterpolationTable::UniformLinearInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformLinearInterpolationTable::UniformLinearInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class variables */ m_name = STR(IMPL_NAME); diff --git a/src/table_types/UniformLinearInterpolationTable.hpp b/src/table_types/UniformLinearInterpolationTable.hpp index 7c51203..743134c 100644 --- a/src/table_types/UniformLinearInterpolationTable.hpp +++ b/src/table_types/UniformLinearInterpolationTable.hpp @@ -18,6 +18,6 @@ class UniformLinearInterpolationTable final : public UniformLookupTable __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformLinearInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformLinearInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp b/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp index 3b3fb9b..8242c71 100644 --- a/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformLinearPrecomputedInterpolationTable.cpp @@ -4,7 +4,8 @@ #define IMPL_NAME UniformLinearPrecomputedInterpolationTable REGISTER_ULUT_IMPL(IMPL_NAME); -UniformLinearPrecomputedInterpolationTable::UniformLinearPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformLinearPrecomputedInterpolationTable::UniformLinearPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ diff --git a/src/table_types/UniformLinearPrecomputedInterpolationTable.hpp b/src/table_types/UniformLinearPrecomputedInterpolationTable.hpp index 994b406..029b5e0 100644 --- a/src/table_types/UniformLinearPrecomputedInterpolationTable.hpp +++ b/src/table_types/UniformLinearPrecomputedInterpolationTable.hpp @@ -19,6 +19,6 @@ class UniformLinearPrecomputedInterpolationTable final : public UniformLookupTab __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformLinearPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformLinearPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; diff --git a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp index 426e166..b102fca 100644 --- a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp +++ b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.cpp @@ -4,7 +4,8 @@ #define IMPL_NAME UniformQuadraticPrecomputedInterpolationTable REGISTER_ULUT_IMPL(IMPL_NAME); -UniformQuadraticPrecomputedInterpolationTable::UniformQuadraticPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par) : UniformLookupTable(func, par) +UniformQuadraticPrecomputedInterpolationTable::UniformQuadraticPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) { /* Base class default variables */ diff --git a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.hpp b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.hpp index 32fb80a..8b5f301 100644 --- a/src/table_types/UniformQuadraticPrecomputedInterpolationTable.hpp +++ b/src/table_types/UniformQuadraticPrecomputedInterpolationTable.hpp @@ -14,14 +14,12 @@ #pragma once #include "UniformLookupTable.hpp" -#include - class UniformQuadraticPrecomputedInterpolationTable final : public UniformLookupTable { REGISTER_ULUT(UniformQuadraticPrecomputedInterpolationTable); __attribute__((aligned)) std::unique_ptr[]> m_table; public: - UniformQuadraticPrecomputedInterpolationTable(EvaluationFunctor *func, UniformLookupTableParameters par); + UniformQuadraticPrecomputedInterpolationTable(FunctionContainer *func_container, UniformLookupTableParameters par); double operator()(double x) override; }; From f6b32a37cfd38cd8e0980f668e4c665c77a8b9d3 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:30:55 -0600 Subject: [PATCH 17/21] Currently unused. Will most likely delete --- src/table_types/UniformAutoDiffTable.hpp | 27 +++++------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/table_types/UniformAutoDiffTable.hpp b/src/table_types/UniformAutoDiffTable.hpp index 5a8b18b..f023e8c 100644 --- a/src/table_types/UniformAutoDiffTable.hpp +++ b/src/table_types/UniformAutoDiffTable.hpp @@ -5,37 +5,20 @@ #pragma once #include "UniformLookupTable.hpp" -#include -#include -#include -#include -#include - using boost::math::differentiation::autodiff_fvar; -/* This can be reworked when we move to std::function */ -template -class FuncWrapper : public EvaluationFunctor -{ - public: - // TODO test if this can be simplified with friend + remove warning??? - EvaluationFunctor,autodiff_fvar> *fvar_EvalFunctor; - FuncWrapper(EvaluationFunctor,autodiff_fvar> *new_EvalFunctor) - { fvar_EvalFunctor = new_EvalFunctor; } - double operator()(double x) override { return (double) (*fvar_EvalFunctor)(x); } -}; - template class UniformAutoDiffTable : public UniformLookupTable { - friend class func_wrapper; - protected: EvaluationFunctor, autodiff_fvar> *mp_boost_func; public: - UniformAutoDiffTable(EvaluationFunctor,autodiff_fvar> *func, UniformLookupTableParameters par) : - mp_boost_func(func), UniformLookupTable(new FuncWrapper(mp_boost_func),par){} + UniformAutoDiffTable(FunctionContainer *func_container, UniformLookupTableParameters par) : + UniformLookupTable(func_container, par) + { + // select, check for null, and set appropriate boost function with modification to FunctionContainer + } virtual ~UniformAutoDiffTable(){}; From 7a69f289cde466e83ec8907a4ec0385931ba1a02 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:31:29 -0600 Subject: [PATCH 18/21] Re-enabled generation of every table type --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee91df6..a4860e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,8 +26,8 @@ if(USE_ARMADILLO AND ARMADILLO_FOUND) list(APPEND func_impls_link_libs ${ARMADILLO_LIBRARIES}) list(APPEND func_impls_src - #table_types/UniformArmadilloPrecomputedInterpolationTable.cpp - #table_types/UniformPadeTable.cpp + table_types/UniformArmadilloPrecomputedInterpolationTable.cpp + table_types/UniformPadeTable.cpp ) endif() @@ -40,7 +40,7 @@ target_include_directories(func_impls PUBLIC ${func_impls_include_dirs}) add_library(func SHARED ImplementationComparator.cpp Timer.cpp - #UniformLookupTableGenerator.cpp + UniformLookupTableGenerator.cpp ) target_link_libraries(func PUBLIC ${QUADMATH_LIBRARIES} Boost::boost func_impls) From b83a4587933f9b1ffaab5b9e521e728788f83066 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:34:50 -0600 Subject: [PATCH 19/21] Now build a FunctionContainer to pass to the UniformLookupTableGenerator --- examples/chaste_log_function.hpp | 28 ----------------- examples/compute_max_err_of_tables.cpp | 8 +++-- examples/experiment.cpp | 43 ++++++++++++++------------ examples/experiment_best_worst.cpp | 9 ++++-- examples/generate_tables_at_tol.cpp | 11 ++++--- examples/plot_impl.cpp | 5 +-- examples/test_function.hpp | 17 ++-------- src/ZeroFunction.hpp | 12 ------- 8 files changed, 48 insertions(+), 85 deletions(-) diff --git a/examples/chaste_log_function.hpp b/examples/chaste_log_function.hpp index bed6181..5d68c9a 100644 --- a/examples/chaste_log_function.hpp +++ b/examples/chaste_log_function.hpp @@ -9,32 +9,4 @@ class MyFunction final : public EvaluationFunctor { public: T operator()(T x) override { return FUNC(x); } - T deriv(T x) override - { - return -13.0287/x; - } - T deriv2(T x) override - { - return 13.0287/x/x; - } - T deriv3(T x) override - { - return -26.0574/x/x/x; - } - T deriv4(T x) override - { - return 78.1722/x/x/x/x; - } - T deriv5(T x) override - { - return -312.6888/x/x/x/x/x; - } - T deriv6(T x) override - { - return 1563.444/x/x/x/x/x/x; - } - T deriv7(T x) override - { - return -9380.664/x/x/x/x/x/x/x; - } }; diff --git a/examples/compute_max_err_of_tables.cpp b/examples/compute_max_err_of_tables.cpp index 2c65142..1190d9e 100644 --- a/examples/compute_max_err_of_tables.cpp +++ b/examples/compute_max_err_of_tables.cpp @@ -14,7 +14,11 @@ int main() { using namespace std; - MyFunction func; + FunctionContainer func_container; + func_container.double_func = new MyFunction; + func_container.fvar1_func = new MyFunction; + func_container.fvar2_func = new MyFunction; + func_container.fvar3_func = new MyFunction; /* Which implementations to use */ std::vector implNames {"UniformLinearInterpolationTable", @@ -24,7 +28,7 @@ int main() "UniformQuadraticTaylorTable", "UniformCubicTaylorTable"}; - UniformLookupTableGenerator gen(&func, MIN_ARG, MAX_ARG); + UniformLookupTableGenerator gen(&func_container, MIN_ARG, MAX_ARG); cout << "# Function: " << FUNCNAME << endl; cout << "# h "; diff --git a/examples/experiment.cpp b/examples/experiment.cpp index 99009ac..ed856ef 100644 --- a/examples/experiment.cpp +++ b/examples/experiment.cpp @@ -44,8 +44,9 @@ int main(int argc, char* argv[]) int nEvals = std::stoi(argv[5]); unsigned int seed = std::stoi(argv[6]); - MyFunction func; - MyFunction double_func; + FunctionContainer func_container{new MyFunction, new MyFunction, + new MyFunction, new MyFunction, new MyFunction, + new MyFunction, new MyFunction, new MyFunction}; double stepSize; /* Check which implementations are available */ @@ -60,43 +61,45 @@ int main(int argc, char* argv[]) /* Which LUT implementations to use */ std::vector implNames { - //"UniformCubicHermiteTable", //"UniformLinearInterpolationTable", //"UniformLinearPrecomputedInterpolationTable", //"UniformQuadraticPrecomputedInterpolationTable", - "UniformCubicPrecomputedInterpolationTable", + //"UniformCubicPrecomputedInterpolationTable", //"UniformArmadilloPrecomputedInterpolationTable<4>", //"UniformArmadilloPrecomputedInterpolationTable<5>", //"UniformArmadilloPrecomputedInterpolationTable<6>", //"UniformArmadilloPrecomputedInterpolationTable<7>", - //"UniformPadeTable<1,1>", - //"UniformPadeTable<2,2>", - //"UniformPadeTable<3,3>", - //"UniformPadeTable<4,3>", - "UniformLinearTaylorTable" - //"UniformQuadraticTaylorTable", - //"UniformCubicTaylorTable" + "UniformPadeTable<1,1>", + "UniformPadeTable<2,1>", + "UniformPadeTable<3,1>", + "UniformPadeTable<4,1>", + "UniformPadeTable<5,1>", + "UniformPadeTable<6,1>", + "UniformPadeTable<3,2>", + "UniformPadeTable<4,2>", + "UniformPadeTable<5,2>", + "UniformPadeTable<2,2>", + "UniformPadeTable<3,3>", + "UniformPadeTable<4,3>", + "UniformLinearTaylorTable", + "UniformQuadraticTaylorTable", + "UniformCubicTaylorTable", + "UniformCubicHermiteTable" }; - UniformLookupTableGenerator gen(&func, tableMin, tableMax); - cout << "foo1" << endl; + UniformLookupTableGenerator gen(&func_container, tableMin, tableMax); /* add implementations to vector */ // unique_ptr test = make_unique(&func,tableMin,tableMax); - impls.emplace_back(unique_ptr(new DirectEvaluation(&double_func,tableMin,tableMax))); - cout << "foo4" << endl; + impls.emplace_back(unique_ptr(new DirectEvaluation(&func_container,tableMin,tableMax))); for (auto itName : implNames) { - impls.emplace_back(gen.generate_by_tol(itName,tableTol)); - cout << "foo6" << endl; + impls.emplace_back(new UniformFailureProofTable(gen.generate_by_tol(itName,tableTol))); } - cout << "foo2" << endl; /* Run comparator */ ImplementationComparator implCompare(impls, nEvals, seed); - cout << "foo3" << endl; implCompare.run_timings(nExperiments); - cout << "foo3" << endl; /* Summarize the results */ cout << "# Function: " << FUNCNAME << endl; diff --git a/examples/experiment_best_worst.cpp b/examples/experiment_best_worst.cpp index e005b56..ec64bf9 100644 --- a/examples/experiment_best_worst.cpp +++ b/examples/experiment_best_worst.cpp @@ -43,7 +43,12 @@ int main(int argc, char* argv[]) int nEvals = std::stoi(argv[3]); int seed = std::stoi(argv[4]); - ZeroFunction func; + FunctionContainer func_container; + func_container.double_func = new ZeroFunction; + func_container.fvar1_func = new ZeroFunction; + func_container.fvar2_func = new ZeroFunction; + func_container.fvar3_func = new ZeroFunction; + double stepSize; /* Which LUT implementations to use */ @@ -68,7 +73,7 @@ int main(int argc, char* argv[]) std::cout << "\n# impls using ~ " << percentRam <<"% of RAM\n"; cout << "# Function: " << FUNCNAME << endl << endl; - UniformLookupTableGenerator gen(&func, 0, 1); + UniformLookupTableGenerator gen(&func_container, 0, 1); /* Fill in the implementations */ std::vector> impls; diff --git a/examples/generate_tables_at_tol.cpp b/examples/generate_tables_at_tol.cpp index 190fa1e..d030310 100644 --- a/examples/generate_tables_at_tol.cpp +++ b/examples/generate_tables_at_tol.cpp @@ -18,10 +18,11 @@ int main() { using namespace std; - MyFunction func; - MyFunction func; - MyFunction func; - MyFunction func; + FunctionContainer func_container; + func_container.double_func = new MyFunction; + func_container.fvar1_func = new MyFunction; + func_container.fvar2_func = new MyFunction; + func_container.fvar3_func = new MyFunction; cout << "# Function: " << FUNCNAME << "\n"; cout << "# Tol: " << TOL << "\n"; @@ -37,7 +38,7 @@ int main() "UniformCubicTaylorTable"}; - UniformLookupTableGenerator gen(&func, MIN_ARG, MAX_ARG); + UniformLookupTableGenerator gen(&func_container, MIN_ARG, MAX_ARG); for (auto itName : implNames) { std::cout << "\nGenerating " << itName << ":" << std::endl; diff --git a/examples/plot_impl.cpp b/examples/plot_impl.cpp index 89d9b7f..b47a1bc 100644 --- a/examples/plot_impl.cpp +++ b/examples/plot_impl.cpp @@ -16,7 +16,8 @@ int main() { using namespace std; - MyFunction func; + FunctionContainer func_container; + func_container.double_func = new MyFunction; cout << "# Function: " << FUNCNAME << endl; cout << "# h"; @@ -25,7 +26,7 @@ int main() // UniformLookupTableGenerator // gen(&func,MIN_ARG,MAX_ARG,0.0); - UniformLookupTableGenerator gen(&func,MIN_ARG,MAX_ARG); + UniformLookupTableGenerator gen(&func_container,MIN_ARG,MAX_ARG); gen.plot_implementation_at_step_size("UniformLinearInterpolationTable",STEP); diff --git a/examples/test_function.hpp b/examples/test_function.hpp index 4b366c6..ab34c6e 100644 --- a/examples/test_function.hpp +++ b/examples/test_function.hpp @@ -4,20 +4,9 @@ #define FUNC(x) (7.7*x*exp(x)-13.0287*x*x*log(x)-x +13.0*x*x*x) #define FUNCNAME "(7.7*x*exp(x)-13.0287*x*x*log(x)-x +13.0*x*x*x)" -class MyFunction final : public EvaluationFunctor +template +class MyFunction final : public EvaluationFunctor { public: - boost_fvar operator()(boost_fvar x) override { return FUNC(x); } - boost_fvar deriv(boost_fvar x) override - { - return 7.7*exp(x)*(1.0+x) - 13.0287*(2.0*x*log(x)+x) - 1.0 + 39.0*x*x; - } - boost_fvar deriv2(boost_fvar x) override - { - return 7.7*exp(x)*(2.0+x) - 13.0287*(2.0*log(x)+3.0) + 78.0*x; - } - boost_fvar deriv3(boost_fvar x) override - { - return 7.7*exp(x)*(3.0+x) - 13.0287*(2.0/x) + 78.0; - } + T operator()(T x) override { return FUNC(x); } }; diff --git a/src/ZeroFunction.hpp b/src/ZeroFunction.hpp index 66bc304..5990890 100644 --- a/src/ZeroFunction.hpp +++ b/src/ZeroFunction.hpp @@ -8,16 +8,4 @@ class ZeroFunction final : public EvaluationFunctor { public: T operator()(T x) override { return FUNC(X); } - T deriv(T x) override - { - return 0.0; - } - T deriv2(T x) override - { - return 0.0; - } - T deriv3(T x) override - { - return 0.0; - } }; From bc1f268b11cfdd10f9e561a31495bd9cc8a2e8f1 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:39:00 -0600 Subject: [PATCH 20/21] Added a comment about the classes inheriting from EvaluationImplementation --- src/EvaluationImplementation.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EvaluationImplementation.hpp b/src/EvaluationImplementation.hpp index 849135c..5c066d1 100644 --- a/src/EvaluationImplementation.hpp +++ b/src/EvaluationImplementation.hpp @@ -27,6 +27,7 @@ class EvaluationImplementation public: + // Every class inheriting from this one use a FunctionContainer as their first arg (aside from UniformFailureProofTable) EvaluationImplementation(EvaluationFunctor *func = NULL, std::string name = ""); virtual ~EvaluationImplementation(){}; From fcc99c74d2fcd9ad977c5638aaff99eadd1f8893 Mon Sep 17 00:00:00 2001 From: Shawn Samuel Carl McAdam Date: Mon, 29 Jun 2020 12:39:53 -0600 Subject: [PATCH 21/21] Now use FunctionContainer to pass around a user generated function --- src/DirectEvaluation.cpp | 4 ++-- src/DirectEvaluation.hpp | 2 +- src/UniformLookupTableGenerator.cpp | 19 ++++++++++--------- src/UniformLookupTableGenerator.hpp | 9 ++------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/DirectEvaluation.cpp b/src/DirectEvaluation.cpp index d911874..0c5dd26 100644 --- a/src/DirectEvaluation.cpp +++ b/src/DirectEvaluation.cpp @@ -6,8 +6,8 @@ #include "ArgumentRecord.hpp" #endif -DirectEvaluation::DirectEvaluation(EvaluationFunctor *func, double min, double max, unsigned int histSize) : - EvaluationImplementation(func, "DirectEvaluation") +DirectEvaluation::DirectEvaluation(FunctionContainer *func_container, double min, double max, unsigned int histSize) : + EvaluationImplementation(func_container->double_func, "DirectEvaluation") { /* Base class default variables */ this->m_minArg = min; this->m_maxArg = max; diff --git a/src/DirectEvaluation.hpp b/src/DirectEvaluation.hpp index 7f33a71..1964a4e 100644 --- a/src/DirectEvaluation.hpp +++ b/src/DirectEvaluation.hpp @@ -26,7 +26,7 @@ class DirectEvaluation final : public EvaluationImplementation std::unique_ptr mp_recorder; #endif public: - DirectEvaluation(EvaluationFunctor *func, double min = 0, double max = 1, unsigned int histSize = 10); + DirectEvaluation(FunctionContainer *func_container, double min = 0, double max = 1, unsigned int histSize = 10); double operator()(double x) override; void print_details(std::ostream& out) override; void print_details_json(std::ostream& out); diff --git a/src/UniformLookupTableGenerator.cpp b/src/UniformLookupTableGenerator.cpp index fff139a..652c485 100644 --- a/src/UniformLookupTableGenerator.cpp +++ b/src/UniformLookupTableGenerator.cpp @@ -59,7 +59,7 @@ struct UniformLookupTableGenerator::OptimalStepSizeFunctor par.minArg = m_parent.m_min; par.maxArg = m_parent.m_max; par.stepSize = stepSize; - auto impl = UniformLookupTableFactory::Create(m_tableKey, m_parent.mp_func, par); + auto impl = UniformLookupTableFactory::Create(m_tableKey, m_parent.mp_func_container, par); boost::uintmax_t max_it = 20; @@ -112,7 +112,8 @@ struct UniformLookupTableGenerator::OptimalStepSizeFunctor /* UniformLookupTableGenerator functions */ -UniformLookupTableGenerator::UniformLookupTableGenerator(EvaluationFunctor *func, double minArg, double maxArg) : mp_func(func), m_min(minArg), m_max(maxArg) {} +UniformLookupTableGenerator::UniformLookupTableGenerator(FunctionContainer *func_container, double minArg, double maxArg) : + mp_func_container(func_container), m_min(minArg), m_max(maxArg) {} UniformLookupTableGenerator::~UniformLookupTableGenerator() @@ -125,7 +126,7 @@ std::unique_ptr UniformLookupTableGenerator::generate_by_ste par.minArg = m_min; par.maxArg = m_max; par.stepSize = stepSize; - return UniformLookupTableFactory::Create(tableKey, mp_func, par); + return UniformLookupTableFactory::Create(tableKey, mp_func_container, par); } std::unique_ptr UniformLookupTableGenerator::generate_by_impl_size(std::string tableKey, unsigned long desiredSize) @@ -145,9 +146,9 @@ std::unique_ptr UniformLookupTableGenerator::generate_by_imp par2.stepSize = step2; std::unique_ptr impl1 = - UniformLookupTableFactory::Create(tableKey, mp_func, par1); + UniformLookupTableFactory::Create(tableKey, mp_func_container, par1); std::unique_ptr impl2 = - UniformLookupTableFactory::Create(tableKey, mp_func, par2); + UniformLookupTableFactory::Create(tableKey, mp_func_container, par2); unsigned long size1 = impl1->size(); unsigned long size2 = impl2->size(); @@ -160,7 +161,7 @@ std::unique_ptr UniformLookupTableGenerator::generate_by_imp (assuming linear relationship of num_intervals to size */ par1.stepSize = 1.0/((double)((N2-N1)*(desiredSize-size1)/(size2-size1) + N1)); - return UniformLookupTableFactory::Create(tableKey, mp_func, par1); + return UniformLookupTableFactory::Create(tableKey, mp_func_container, par1); } std::unique_ptr UniformLookupTableGenerator::generate_by_tol(std::string tableKey, double desiredTolerance) @@ -171,7 +172,7 @@ std::unique_ptr UniformLookupTableGenerator::generate_by_tol par.stepSize = (m_max-m_min)/1000.0; /* generate a first approximation for the implementation */ auto impl = - UniformLookupTableFactory::Create(tableKey, mp_func, par); + UniformLookupTableFactory::Create(tableKey, mp_func_container, par); /* And initialize the functor used for refinement */ OptimalStepSizeFunctor f(*this,tableKey,0); double stepSize = impl->step_size(); @@ -264,7 +265,7 @@ std::unique_ptr UniformLookupTableGenerator::generate_by_tol /* Finally, return the implementation with the desired stepSize*/ par.stepSize = r.first; - return UniformLookupTableFactory::Create(tableKey,mp_func,par); + return UniformLookupTableFactory::Create(tableKey,mp_func_container,par); } @@ -292,7 +293,7 @@ void UniformLookupTableGenerator::plot_implementation_at_step_size(std::string t par.maxArg = m_max; par.stepSize = stepSize; auto impl = - UniformLookupTableFactory::Create(tableKey, mp_func, par); + UniformLookupTableFactory::Create(tableKey, mp_func_container, par); std::cout << "# x func impl" << std::endl; for (double x=impl->min_arg(); diff --git a/src/UniformLookupTableGenerator.hpp b/src/UniformLookupTableGenerator.hpp index 9d1c192..e4e3a4c 100644 --- a/src/UniformLookupTableGenerator.hpp +++ b/src/UniformLookupTableGenerator.hpp @@ -6,13 +6,12 @@ */ #pragma once #include "UniformLookupTable.hpp" -#include #include class UniformLookupTableGenerator { private: - FunctionHelper *mp_func; + FunctionContainer *mp_func_container; double m_min; double m_max; @@ -24,11 +23,7 @@ class UniformLookupTableGenerator struct OptimalStepSizeFunctor; public: - - //TODO make this less rigid. Can you specify args out of order w/ dummy names? - UniformLookupTableGenerator(FunctionHelper *func, - double minArg, double maxArg, - ); + UniformLookupTableGenerator(FunctionContainer *func_container, double minArg, double maxArg); ~UniformLookupTableGenerator(); std::unique_ptr generate_by_step(std::string tableKey, double stepSize);