Просмотр исходного кода

lolremez: allow spaces in arithmetic expressions.

undefined
Sam Hocevar 10 лет назад
Родитель
Сommit
50c2b4b46e
3 измененных файлов: 38 добавлений и 15 удалений
  1. +27
    -11
      tools/lolremez/expression.h
  2. +2
    -0
      tools/lolremez/lolremez.cpp
  3. +9
    -4
      tools/lolremez/solver.cpp

+ 27
- 11
tools/lolremez/expression.h Просмотреть файл

@@ -226,21 +226,32 @@ private:

struct r_expr;

// Rule for unary function calls
// r_ <- <blank> *
struct _ : star<space> {};

// r_call_unary <- <unary_op> "(" r_expr ")"
template<op OP>
struct r_call_unary : ifapply<seq<r_call_string<OP>,
_,
one<'('>,
_,
r_expr,
_,
one<')'>>,
do_op<OP>> {};

// Rule for binary function calls
// r_call_binary <- <binary_op> "(" r_expr "," r_expr ")"
template<op OP>
struct r_call_binary : ifapply<seq<r_call_string<OP>,
_,
one<'('>,
_,
r_expr,
_,
one<','>,
_,
r_expr,
_,
one<')'>>,
do_op<OP>> {};

@@ -250,8 +261,7 @@ private:
// r_var <- "x"
struct r_var : ifapply<one<'x'>, do_op<op::x>> {};

// r_call <- <unary_op> "(" r_expr ")"
// / <binary_op> "(" r_expr "," r_expr ")"
// r_call <- r_call_unary / r_call_binary
struct r_call : sor<r_call_unary<op::sqrt>,
r_call_unary<op::cbrt>,
r_call_unary<op::exp>,
@@ -274,7 +284,11 @@ private:
r_call_binary<op::max>> {};

// r_parentheses <- "(" r_expr ")"
struct r_parentheses : seq<one<'('>, r_expr, one<')'>> {};
struct r_parentheses : seq<one<'('>,
_,
r_expr,
_,
one<')'>> {};

// r_terminal <- r_call / r_var / r_constant / r_parentheses
struct r_terminal : sor<r_call,
@@ -284,7 +298,9 @@ private:

// r_exponent <- ( "^" | "**" ) r_terminal
// r_factor <- r_terminal ( r_exponent ) *
struct r_exponent : ifapply<seq<sor<one<'^'>, string<'*', '*'>>,
struct r_exponent : ifapply<seq<_,
sor<one<'^'>, string<'*', '*'>>,
_,
r_terminal>, do_op<op::pow>> {};
struct r_factor : seq<r_terminal,
star<r_exponent>> {};
@@ -292,21 +308,21 @@ private:
// r_mul <- "*" r_factor
// r_div <- "/" r_factor
// term <- r_factor ( r_mul / r_div ) *
struct r_mul : ifapply<seq<one<'*'>, r_factor>, do_op<op::mul>> {};
struct r_div : ifapply<seq<one<'/'>, r_factor>, do_op<op::div>> {};
struct r_mul : ifapply<seq<_, one<'*'>, _, r_factor>, do_op<op::mul>> {};
struct r_div : ifapply<seq<_, one<'/'>, _, r_factor>, do_op<op::div>> {};
struct r_term : seq<r_factor,
star<sor<r_mul, r_div>>> {};

// add <- "+" r_term
// sub <- "-" r_term
// r_expr <- r_term ( add / sub ) *
struct r_add : ifapply<seq<one<'+'>, r_term>, do_op<op::add>> {};
struct r_sub : ifapply<seq<one<'-'>, r_term>, do_op<op::sub>> {};
struct r_add : ifapply<seq<_, one<'+'>, _, r_term>, do_op<op::add>> {};
struct r_sub : ifapply<seq<_, one<'-'>, _, r_term>, do_op<op::sub>> {};
struct r_expr : seq<r_term,
star<sor<r_add, r_sub>>> {};

// stmt <- r_expr <end>
struct r_stmt : ifapply<seq<r_expr, eof>, do_success> {};
struct r_stmt : ifapply<seq<_, r_expr, _, eof>, do_success> {};
};

} /* namespace grammar */


+ 2
- 0
tools/lolremez/lolremez.cpp Просмотреть файл

@@ -28,9 +28,11 @@ void FAIL()
{
printf("Usage:\n");
printf(" lolremez [-d degree] [-i xmin xmax] x-expression [x-error]\n");
printf("\n");
printf("Example:\n");
printf(" lolremez -d 4 -i -1 1 \"atan(exp(1+x))\"\n");
printf(" lolremez -d 4 -i -1 1 \"atan(exp(1+x))\" \"exp(1+x)\"\n");
printf("\n");

exit(EXIT_FAILURE);
}


+ 9
- 4
tools/lolremez/solver.cpp Просмотреть файл

@@ -58,7 +58,7 @@ void RemezSolver::Run(real a, real b, char const *func, char const *weight)
for (int n = 0; ; n++)
{
real newerror = FindExtrema();
printf("Step %i error: ", n);
printf(" -:- error at step %i: ", n);
newerror.print(m_decimals);
printf("\n");

@@ -172,6 +172,8 @@ void RemezSolver::Step()

void RemezSolver::FindZeroes()
{
m_stats_cheby = m_stats_func = m_stats_weight = 0.f;

/* Find m_order + 1 zeroes of the error function. No need to
* compute the relative error: its zeroes are at the same
* place as the absolute error! */
@@ -200,6 +202,9 @@ void RemezSolver::FindZeroes()

m_zeroes[i] = mid.value;
}

printf(" -:- times for zeroes: estimate %f func %f weight %f\n",
m_stats_cheby, m_stats_func, m_stats_weight);
}

/* XXX: this is the real costly function */
@@ -272,9 +277,9 @@ real RemezSolver::FindExtrema()
}
}

printf("Iterations: Rounds %d Evals %d\n", rounds, evals);
printf("Times: Estimate %f Func %f EvalWeight %f\n",
printf(" -:- times for extrema: estimate %f func %f weight %f\n",
m_stats_cheby, m_stats_func, m_stats_weight);
printf(" -:- calls: %d rounds, %d evals\n", rounds, evals);

return final;
}
@@ -289,7 +294,7 @@ void RemezSolver::PrintPoly()
polynomial<real> q ({ -m_k1 / m_k2, real(1) / m_k2 });
polynomial<real> r = m_estimate.eval(q);

printf("Polynomial estimate: ");
printf("\n");
for (int j = 0; j < m_order + 1; j++)
{
if (j)


Загрузка…
Отмена
Сохранить