// Derived from SciPy's special/cephes/polevl.h // https://github.com/scipy/scipy/blob/master/scipy/special/cephes/polevl.h // Made freely available by Stephen L. Moshier without support or guarantee. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Copyright ©1984, ©1987, ©1988 by Stephen L. Moshier // Portions Copyright ©2016 The Gonum Authors. All rights reserved. package cephes import "math" // polevl evaluates a polynomial of degree N // y = c_0 + c_1 x_1 + c_2 x_2^2 ... // where the coefficients are stored in reverse order, i.e. coef[0] = c_n and // coef[n] = c_0. func polevl(x float64, coef []float64, n int) float64 { ans := coef[0] for i := 1; i <= n; i++ { ans = ans*x + coef[i] } return ans } // p1evl is the same as polevl, except c_n is assumed to be 1 and is not included // in the slice. func p1evl(x float64, coef []float64, n int) float64 { ans := x + coef[0] for i := 1; i <= n-1; i++ { ans = ans*x + coef[i] } return ans } // ratevl evaluates a rational function func ratevl(x float64, num []float64, m int, denom []float64, n int) float64 { // Source: Holin et. al., "Polynomial and Rational Function Evaluation", // http://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/roots/rational.html absx := math.Abs(x) var dir, idx int var y float64 if absx > 1 { // Evaluate as a polynomial in 1/x dir = -1 idx = m y = 1 / x } else { dir = 1 idx = 0 y = x } // Evaluate the numerator numAns := num[idx] idx += dir for i := 0; i < m; i++ { numAns = numAns*y + num[idx] idx += dir } // Evaluate the denominator if absx > 1 { idx = n } else { idx = 0 } denomAns := denom[idx] idx += dir for i := 0; i < n; i++ { denomAns = denomAns*y + denom[idx] idx += dir } if absx > 1 { pow := float64(n - m) return math.Pow(x, pow) * numAns / denomAns } return numAns / denomAns }