module math import math.internal fn poly_n_eval(c []f64, n int, x f64) f64 { if c.len == 0 { panic('coeficients can not be empty') } len := int(min(c.len, n)) mut ans := c[len - 1] for e in c[..len - 1] { ans = e + x * ans } return ans } fn poly_n_1_eval(c []f64, n int, x f64) f64 { if c.len == 0 { panic('coeficients can not be empty') } len := int(min(c.len, n)) - 1 mut ans := c[len - 1] for e in c[..len - 1] { ans = e + x * ans } return ans } [inline] fn poly_eval(c []f64, x f64) f64 { return poly_n_eval(c, c.len, x) } [inline] fn poly_1_eval(c []f64, x f64) f64 { return poly_n_1_eval(c, c.len, x) } // data for a Chebyshev series over a given interval struct ChebSeries { pub: c []f64 // coefficients order int // order of expansion a f64 // lower interval point b f64 // upper interval point } fn (cs ChebSeries) eval_e(x f64) (f64, f64) { mut d := 0.0 mut dd := 0.0 y := (2.0 * x - cs.a - cs.b) / (cs.b - cs.a) y2 := 2.0 * y mut e_ := 0.0 mut temp := 0.0 for j := cs.order; j >= 1; j-- { temp = d d = y2 * d - dd + cs.c[j] e_ += abs(y2 * temp) + abs(dd) + abs(cs.c[j]) dd = temp } temp = d d = y * d - dd + 0.5 * cs.c[0] e_ += abs(y * temp) + abs(dd) + 0.5 * abs(cs.c[0]) return d, f64(internal.f64_epsilon) * e_ + abs(cs.c[cs.order]) }