/* Implementation of the Horner method of polynomial evaluation Copyright (C) 2011 Darko Veberic, darko.veberic@ijs.si This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _utl_Horner_h_ #define _utl_Horner_h_ namespace utl { template struct Polynomial { static inline Float Coeff(); static inline Float Coeff(const Float x); }; template struct Horner { static Float Recurse(const Float term, const Float x) { return Horner::Recurse(term*x + Polynomial::Coeff(), x); } static Float RecurseAlt(const Float term, const Float x) { return Horner::RecurseAlt(Polynomial::Coeff() + x*term, x); } static Float Eval(const Float x) { return Horner::Recurse(Polynomial::Coeff(), x); } static Float EvalAlt(const Float x) { return Horner::RecurseAlt(Polynomial::Coeff(), x); } // static Float Recurse(const Float term, const Float x, const Float y) { return Horner::Recurse(term*x + Polynomial::Coeff(y), x, y); } static Float Eval(const Float x, const Float y) { return Horner::Recurse(Polynomial::Coeff(y), x, y); } }; template struct Horner { static Float Recurse(const Float term, const Float x) { return term*x + Polynomial::Coeff(); } static Float Eval(const Float x) { return Polynomial::Coeff(); } // static Float Recurse(const Float term, const Float x, const Float y) { return term*x + Polynomial::Coeff(y); } static Float Eval(const Float x, const Float y) { return Polynomial::Coeff(y); } }; #define HORNER_COEFF(_Tag_, _i_, _c_) \ template struct Polynomial { static Float Coeff() { return Float(_c_); } } #define HORNER_COEFF2(_Tag_, _i_, _c_y_) \ template struct Polynomial { static Float Coeff(const Float y) { return Float(_c_y_); } } #define HORNER0(F, x, c0) (F)(c0) #define HORNER1(F, x, c1, c0) HORNER0(F, x, (F)(c1)*(x) + (F)(c0) ) #define HORNER2(F, x, c2, c1, c0) HORNER1(F, x, (F)(c2)*(x) + (F)(c1), c0) #define HORNER3(F, x, c3, c2, c1, c0) HORNER2(F, x, (F)(c3)*(x) + (F)(c2), c1, c0) #define HORNER4(F, x, c4, c3, c2, c1, c0) HORNER3(F, x, (F)(c4)*(x) + (F)(c3), c2, c1, c0) #define HORNER5(F, x, c5, c4, c3, c2, c1, c0) HORNER4(F, x, (F)(c5)*(x) + (F)(c4), c3, c2, c1, c0) #define HORNER6(F, x, c6, c5, c4, c3, c2, c1, c0) HORNER5(F, x, (F)(c6)*(x) + (F)(c5), c4, c3, c2, c1, c0) #define HORNER7(F, x, c7, c6, c5, c4, c3, c2, c1, c0) HORNER6(F, x, (F)(c7)*(x) + (F)(c6), c5, c4, c3, c2, c1, c0) #define HORNER8(F, x, c8, c7, c6, c5, c4, c3, c2, c1, c0) HORNER7(F, x, (F)(c8)*(x) + (F)(c7), c6, c5, c4, c3, c2, c1, c0) #define HORNER9(F, x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0) HORNER8(F, x, (F)(c9)*(x) + (F)(c8), c7, c6, c5, c4, c3, c2, c1, c0) } #endif