diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-29 23:04:14 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-29 23:04:14 +0000 |
commit | 6b775194811823b84e2694c20c036506d5855215 (patch) | |
tree | 28113bc428c5ad85272fd7554892d1c7acc8cb88 | |
parent | 25995ac6b7e60c9d6d012a2d3c6c3d2859e33623 (diff) |
Add two very incomplete implementations of factorial and binomial (!Y and X!Y)
-rw-r--r-- | apl9.h | 2 | ||||
-rw-r--r-- | functions.c | 47 |
2 files changed, 47 insertions, 2 deletions
@@ -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) { |