aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/math/poly.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/math/poly.v')
-rw-r--r--v_windows/v/vlib/math/poly.v65
1 files changed, 65 insertions, 0 deletions
diff --git a/v_windows/v/vlib/math/poly.v b/v_windows/v/vlib/math/poly.v
new file mode 100644
index 0000000..2b62638
--- /dev/null
+++ b/v_windows/v/vlib/math/poly.v
@@ -0,0 +1,65 @@
+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])
+}