Browse Source

lolremez: simplify the solver class.

undefined
Sam Hocevar 11 years ago
parent
commit
d0ebacf545
3 changed files with 35 additions and 55 deletions
  1. +2
    -2
      tools/lolremez/lolremez.cpp
  2. +20
    -38
      tools/lolremez/solver.cpp
  3. +13
    -15
      tools/lolremez/solver.h

+ 2
- 2
tools/lolremez/lolremez.cpp View File

@@ -35,8 +35,8 @@ int main(int argc, char **argv)
{ {
UNUSED(argc, argv); UNUSED(argc, argv);


RemezSolver<real> solver;
solver.Run(4, 40, -1, 1, f, g);
RemezSolver solver(4, 40);
solver.Run(-1, 1, f, g);


return 0; return 0;
} }


+ 20
- 38
tools/lolremez/solver.cpp View File

@@ -21,33 +21,25 @@


using lol::real; using lol::real;


/* Some forward declarations first. */
template<> void RemezSolver<real>::Init();
template<> void RemezSolver<real>::FindZeroes();
template<> real RemezSolver<real>::FindExtrema();
template<> void RemezSolver<real>::Step();
template<> int RemezSolver<real>::Cheby(int n, int k);
template<> void RemezSolver<real>::PrintPoly();
template<> real RemezSolver<real>::EvalFunc(real const &x);
template<> real RemezSolver<real>::Weight(real const &x);


template<>
void RemezSolver<real>::Run(int order, int decimals, real a, real b,
RemezSolver<real>::RealFunc *func,
RemezSolver<real>::RealFunc *weight)
RemezSolver::RemezSolver(int order, int decimals)
: m_order(order),
m_decimals(decimals)
{
}

void RemezSolver::Run(real a, real b,
RemezSolver::RealFunc *func,
RemezSolver::RealFunc *weight)
{ {
using std::printf; using std::printf;


m_order = order;
m_func = func; m_func = func;
m_weight = weight; m_weight = weight;
m_k1 = (b + a) / 2; m_k1 = (b + a) / 2;
m_k2 = (b - a) / 2; m_k2 = (b - a) / 2;
m_invk2 = re(m_k2); m_invk2 = re(m_k2);
m_invk1 = -m_k1 * m_invk2; m_invk1 = -m_k1 * m_invk2;
m_decimals = decimals;
m_epsilon = pow((real)10, (real)-(decimals + 2));
m_epsilon = pow((real)10, (real)-(m_decimals + 2));


Init(); Init();


@@ -76,8 +68,7 @@ void RemezSolver<real>::Run(int order, int decimals, real a, real b,
PrintPoly(); PrintPoly();
} }


template<>
real RemezSolver<real>::EvalCheby(real const &x)
real RemezSolver::EvalCheby(real const &x)
{ {
real ret = 0.0, xn = 1.0; real ret = 0.0, xn = 1.0;


@@ -93,8 +84,7 @@ real RemezSolver<real>::EvalCheby(real const &x)
return ret; return ret;
} }


template<>
void RemezSolver<real>::Init()
void RemezSolver::Init()
{ {
/* m_order + 1 Chebyshev coefficients, plus 1 error value */ /* m_order + 1 Chebyshev coefficients, plus 1 error value */
m_coeff.Resize(m_order + 2); m_coeff.Resize(m_order + 2);
@@ -146,8 +136,7 @@ void RemezSolver<real>::Init()
} }
} }


template<>
void RemezSolver<real>::FindZeroes()
void RemezSolver::FindZeroes()
{ {
/* Find m_order + 1 zeroes of the error function. No need to /* Find m_order + 1 zeroes of the error function. No need to
* compute the relative error: its zeroes are at the same * compute the relative error: its zeroes are at the same
@@ -179,8 +168,7 @@ void RemezSolver<real>::FindZeroes()
} }
} }


template<>
real RemezSolver<real>::FindExtrema()
real RemezSolver::FindExtrema()
{ {
using std::printf; using std::printf;


@@ -248,8 +236,7 @@ real RemezSolver<real>::FindExtrema()
return final; return final;
} }


template<>
void RemezSolver<real>::Step()
void RemezSolver::Step()
{ {
/* Pick up x_i where error will be 0 and compute f(x_i) */ /* Pick up x_i where error will be 0 and compute f(x_i) */
real fxn[m_order + 2]; real fxn[m_order + 2];
@@ -298,8 +285,7 @@ void RemezSolver<real>::Step()
error += mat.m(m_order + 1, i) * fxn[i]; error += mat.m(m_order + 1, i) * fxn[i];
} }


template<>
int RemezSolver<real>::Cheby(int n, int k)
int RemezSolver::Cheby(int n, int k)
{ {
if (k > n || k < 0) if (k > n || k < 0)
return 0; return 0;
@@ -308,16 +294,14 @@ int RemezSolver<real>::Cheby(int n, int k)
return 2 * Cheby(n - 1, k - 1) - Cheby(n - 2, k); return 2 * Cheby(n - 1, k - 1) - Cheby(n - 2, k);
} }


template<>
int RemezSolver<real>::Comb(int n, int k)
int RemezSolver::Comb(int n, int k)
{ {
if (k == 0 || k == n) if (k == 0 || k == n)
return 1; return 1;
return Comb(n - 1, k - 1) + Comb(n - 1, k); return Comb(n - 1, k - 1) + Comb(n - 1, k);
} }


template<>
void RemezSolver<real>::PrintPoly()
void RemezSolver::PrintPoly()
{ {
using std::printf; using std::printf;


@@ -361,14 +345,12 @@ void RemezSolver<real>::PrintPoly()
printf("\n\n"); printf("\n\n");
} }


template<>
real RemezSolver<real>::EvalFunc(real const &x)
real RemezSolver::EvalFunc(real const &x)
{ {
return m_func(x * m_k2 + m_k1); return m_func(x * m_k2 + m_k1);
} }


template<>
real RemezSolver<real>::Weight(real const &x)
real RemezSolver::Weight(real const &x)
{ {
if (m_weight) if (m_weight)
return m_weight(x * m_k2 + m_k1); return m_weight(x * m_k2 + m_k1);


+ 13
- 15
tools/lolremez/solver.h View File

@@ -17,41 +17,39 @@


#include <cstdio> #include <cstdio>


template<typename NUMERIC_T> class RemezSolver
class RemezSolver
{ {
public: public:
typedef NUMERIC_T RealFunc(NUMERIC_T const &x);
typedef lol::real RealFunc(lol::real const &x);


inline RemezSolver()
: m_order(0)
{
}
RemezSolver(int order, int decimals);


void Run(int order, int decimals, NUMERIC_T a, NUMERIC_T b,
void Run(lol::real a, lol::real b,
RealFunc *func, RealFunc *weight = nullptr); RealFunc *func, RealFunc *weight = nullptr);


NUMERIC_T EvalCheby(NUMERIC_T const &x);
private:
lol::real EvalCheby(lol::real const &x);
void Init(); void Init();
void FindZeroes(); void FindZeroes();
NUMERIC_T FindExtrema();
lol::real FindExtrema();
void Step(); void Step();


int Cheby(int n, int k); int Cheby(int n, int k);
int Comb(int n, int k); int Comb(int n, int k);


void PrintPoly(); void PrintPoly();
NUMERIC_T EvalFunc(NUMERIC_T const &x);
NUMERIC_T Weight(NUMERIC_T const &x);
lol::real EvalFunc(lol::real const &x);
lol::real Weight(lol::real const &x);


private: private:
int m_order; int m_order;


lol::Array<NUMERIC_T> m_coeff;
lol::Array<NUMERIC_T> m_zeroes;
lol::Array<NUMERIC_T> m_control;
lol::Array<lol::real> m_coeff;
lol::Array<lol::real> m_zeroes;
lol::Array<lol::real> m_control;


RealFunc *m_func, *m_weight; RealFunc *m_func, *m_weight;
NUMERIC_T m_k1, m_k2, m_invk1, m_invk2, m_epsilon;
lol::real m_k1, m_k2, m_invk1, m_invk2, m_epsilon;
int m_decimals; int m_decimals;
}; };



Loading…
Cancel
Save