From 6b775194811823b84e2694c20c036506d5855215 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Sat, 29 Jan 2022 23:04:14 +0000 Subject: Add two very incomplete implementations of factorial and binomial (!Y and X!Y) --- apl9.h | 2 ++ functions.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/apl9.h b/apl9.h index 0bfa6e9..cf2c352 100644 --- a/apl9.h +++ b/apl9.h @@ -290,6 +290,7 @@ Array *fnRecip(Array *); Array *fnExponent(Array *); Array *fnNaturalLog(Array *); Array *fnPiTimes(Array *); +Array *fnFactorial(Array *); Array *fnRoll(Array *); Array *fnMagnitude(Array *); Array *fnCeiling(Array *); @@ -326,6 +327,7 @@ Array *fnTimes(Array *, Array *); Array *fnDivide(Array *, Array *); Array *fnPower(Array *, Array *); Array *fnLogarithm(Array *, Array *); +Array *fnBinomial(Array *, Array *); Array *fnDeal(Array *, Array *); Array *fnResidue(Array *, Array *); Array *fnMaximum(Array *, Array *); diff --git a/functions.c b/functions.c index 1645e77..0f40a9a 100644 --- a/functions.c +++ b/functions.c @@ -15,7 +15,7 @@ fnmonad monadfunctiondefs[] = { fnNaturalLog, /* ⍟ */ 0, /* ⌹ */ fnPiTimes, /* ○ */ - 0, /* ! */ + fnFactorial, /* ! */ fnRoll, /* ? */ fnMagnitude, /* | */ fnCeiling, /* ⌈ */ @@ -71,7 +71,7 @@ fndyad dyadfunctiondefs[] = { fnLogarithm, /* ⍟ */ 0, /* ⌹ */ 0, /* ○ */ - 0, /* ! */ + fnBinomial, /* ! */ fnDeal, /* ? */ fnResidue, /* | */ fnMaximum, /* ⌈ */ @@ -323,6 +323,32 @@ fnPiTimes(Array *right) return res; } +Array * +fnFactorial(Array *right) +{ + Array *result = nil; + if(right->type == AtypeArray){ + result = duparrayshape(right, AtypeArray); + for(int i = 0; i < right->size; i++) + result->arraydata[i] = fnFactorial(right->arraydata[i]); + }else if(right->type == AtypeInt){ + result = duparrayshape(right, AtypeFloat); + for(int i = 0; i < result->size; i++){ + double x = 1; + vlong n = right->intdata[i]; + if(n < 0) + throwerror(nil, EDomain); + for(int j = 1; j <= n; j++) + x *= j; + result->floatdata[i] = x; + } + }else if(right->type == AtypeFloat) + throwerror(L"Factorial of floating values", ENotImplemented); + else + throwerror(nil, EType); + return result; +} + Array * fnRoll(Array *right) { @@ -906,6 +932,23 @@ SCALAR_FUNCTION_2(fnLogarithm, 1, left->type, break; ) +SCALAR_FUNCTION_2(fnBinomial, 0, AtypeFloat, + case AtypeInt: + if(left->intdata[i] > right->intdata[i]) + res->floatdata[i] = 0; + else{ + Array *a = mkscalarint(left->intdata[i]); + Array *w = mkscalarint(right->intdata[i]); + Array *x = rundfn(L"(!⍵)÷(!⍺)×!⍵-⍺", nil, nil, a, w); + res->floatdata[i] = x->floatdata[0]; + freearray(a); + freearray(w); + freearray(x); + /* TODO horrible */ + } + break; +) + Array * fnDeal(Array *left, Array *right) { -- cgit v1.2.3