summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-29 23:04:14 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-29 23:04:14 +0000
commit6b775194811823b84e2694c20c036506d5855215 (patch)
tree28113bc428c5ad85272fd7554892d1c7acc8cb88
parent25995ac6b7e60c9d6d012a2d3c6c3d2859e33623 (diff)
Add two very incomplete implementations of factorial and binomial (!Y and X!Y)
-rw-r--r--apl9.h2
-rw-r--r--functions.c47
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, /* ⌈ */
@@ -324,6 +324,32 @@ fnPiTimes(Array *right)
}
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)
{
Array *result = nil;
@@ -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)
{