Sfoglia il codice sorgente

lolremez: greatly improve root search times by using simple regula falsi.

undefined
Sam Hocevar 10 anni fa
parent
commit
0e71596def
1 ha cambiato i file con 24 aggiunte e 13 eliminazioni
  1. +24
    -13
      tools/lolremez/solver.cpp

+ 24
- 13
tools/lolremez/solver.cpp Vedi File

@@ -179,28 +179,39 @@ void RemezSolver::FindZeroes()
* place as the absolute error! */ * place as the absolute error! */
for (int i = 0; i < m_order + 1; i++) for (int i = 0; i < m_order + 1; i++)
{ {
struct { real value, error; } left, right, mid; struct { real value, error; } a, b, c;


left.value = m_control[i]; a.value = m_control[i];
left.error = EvalEstimate(left.value) - EvalFunc(left.value); a.error = EvalEstimate(a.value) - EvalFunc(a.value);
right.value = m_control[i + 1]; b.value = m_control[i + 1];
right.error = EvalEstimate(right.value) - EvalFunc(right.value); b.error = EvalEstimate(b.value) - EvalFunc(b.value);


static real limit = ldexp((real)1, -500); static real limit = ldexp((real)1, -500);
static real zero = (real)0; static real zero = (real)0;
while (fabs(left.value - right.value) > limit) while (fabs(a.value - b.value) > limit)
{ {
mid.value = (left.value + right.value) / 2; /* Interpolate linearly instead of taking the midpoint, this
mid.error = EvalEstimate(mid.value) - EvalFunc(mid.value); * leads to far better convergence (6:1 speedups). */
real t = abs(b.error) / (abs(a.error) + abs(b.error));
real newc = b.value + t * (a.value - b.value);

/* If the third point didn't change since last iteration,
* we may be at an inflection point. Use the midpoint to get
* out of this situation. */
c.value = newc == c.value ? (a.value + b.value) / 2 : newc;
c.error = EvalEstimate(c.value) - EvalFunc(c.value);

if (c.error == zero)
break;


if ((left.error <= zero && mid.error <= zero) if ((a.error < zero && c.error < zero)
|| (left.error >= zero && mid.error >= zero)) || (a.error > zero && c.error > zero))
left = mid; a = c;
else else
right = mid; b = c;
} }


m_zeroes[i] = mid.value; m_zeroes[i] = c.value;
} }


printf(" -:- times for zeroes: estimate %f func %f weight %f\n", printf(" -:- times for zeroes: estimate %f func %f weight %f\n",


||||||
x
 
000:0
Caricamento…
Annulla
Salva