66 lines
1.3 KiB
V
66 lines
1.3 KiB
V
|
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])
|
||
|
}
|