summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-09-05 06:04:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-09-05 06:04:21 -0700
commit2a99dce03f1e4c0662e945280ed0dc4c919272df (patch)
tree298e0a784b91191e98f33330ecbb8cae176ab338 /arith.c
parent0f429919165a9b097c61ecb9c6e36111c379489a (diff)
downloadtxr-2a99dce03f1e4c0662e945280ed0dc4c919272df.tar.gz
txr-2a99dce03f1e4c0662e945280ed0dc4c919272df.tar.bz2
txr-2a99dce03f1e4c0662e945280ed0dc4c919272df.zip
New functions for polynomial evaluation.
* arith.c (poly, rpoly): New functions. (arith_init): Registered intrinsics poly and rpoly. * arith.h (poly, rpoly): Declared. * txr.1: Documented.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/arith.c b/arith.c
index 917973c8..7b87a6ef 100644
--- a/arith.c
+++ b/arith.c
@@ -2970,6 +2970,92 @@ val digits(val n, val base)
return digcommon(0, lit("digits"), n, base);
}
+val poly(val x, val seq)
+{
+ val self = lit("rpoly");
+ val acc = zero;
+ seq_info_t si = seq_info(seq);
+
+ if (!numberp(x))
+ uw_throwf(error_s, lit("~a: bad argument ~s; number required"),
+ self, x, nao);
+
+ switch (si.kind) {
+ case SEQ_NIL:
+ return acc;
+ case SEQ_LISTLIKE:
+ while (consp(seq)) {
+ val coeff = pop(&seq);
+ acc = plus(mul(acc, x), coeff);
+ }
+
+ (void) endp(seq);
+ return acc;
+ case SEQ_VECLIKE:
+ {
+ cnum len = c_num(length(seq)), i = 0;
+
+ while (i < len) {
+ val coeff = ref(seq, num(i++));
+ acc = plus(mul(acc, x), coeff);
+ }
+
+ return acc;
+ }
+ default:
+ uw_throwf(error_s, lit("~a: bad argument ~s; poly wants a sequence!"),
+ self, seq, nao);
+
+ }
+}
+
+val rpoly(val x, val seq)
+{
+ val self = lit("poly");
+ val acc = zero;
+ val pow = x;
+ seq_info_t si = seq_info(seq);
+
+ if (!numberp(x))
+ uw_throwf(error_s, lit("~a: bad argument ~s; poly wants a number!"),
+ self, x, nao);
+
+ switch (si.kind) {
+ case SEQ_NIL:
+ return acc;
+ case SEQ_LISTLIKE:
+ if (consp(seq))
+ acc = pop(&seq);
+
+ while (consp(seq)) {
+ val coeff = pop(&seq);
+ acc = plus(acc, mul(pow, coeff));
+ if (seq)
+ pow = mul(pow, x);
+ }
+
+ (void) endp(seq);
+ return acc;
+ case SEQ_VECLIKE:
+ {
+ cnum len = c_num(length(seq)), i = len;
+
+ while (i > 0) {
+ val coeff = ref(seq, num(--i));
+ acc = plus(mul(acc, x), coeff);
+ }
+
+ return acc;
+ }
+ default:
+ uw_throwf(error_s, lit("~a: bad argument ~s; poly wants a sequence!"),
+ self, seq, nao);
+
+ }
+
+ return acc;
+}
+
void arith_init(void)
{
mp_init(&NUM_MAX_MP);
@@ -3007,6 +3093,8 @@ void arith_init(void)
reg_fun(intern(lit("bits"), system_package), func_n1(bits));
reg_fun(intern(lit("digpow"), user_package), func_n2o(digpow, 1));
reg_fun(intern(lit("digits"), user_package), func_n2o(digits, 1));
+ reg_fun(intern(lit("poly"), user_package), func_n2(poly));
+ reg_fun(intern(lit("rpoly"), user_package), func_n2(rpoly));
}
void arith_free_all(void)