From 2d498de6c105e57c32c9048e5901955556ab38bf Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Thu, 13 Jan 2022 20:33:51 +0000 Subject: =?UTF-8?q?Implement=20dyadic=20(integer=20only)=20version=20of=20?= =?UTF-8?q?+=20-=20=C3=97=20=C3=B7=20*=20=E2=8D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apl9.h | 8 ++++ array.c | 38 ++++++++++++++++++ functions.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 166 insertions(+), 6 deletions(-) diff --git a/apl9.h b/apl9.h index 7c44980..63b6d7a 100644 --- a/apl9.h +++ b/apl9.h @@ -116,6 +116,8 @@ Array *mkscalarint(vlong); Array *duparray(Array *); int simplearray(Array *); int simplescalar(Array *); +Array *extend(Array *, Array *); +int scalarextend(Array *, Array *, Array **, Array **); /* eval.c */ Datum *eval(Statement *); @@ -141,6 +143,12 @@ Array *fnRavel(Array *); Array *fnShape(Array *); /* Dyadic functions from functions.h */ +Array *fnPlus(Array *, Array *); +Array *fnMinus(Array *, Array *); +Array *fnTimes(Array *, Array *); +Array *fnDivide(Array *, Array *); +Array *fnPower(Array *, Array *); +Array *fnLogarithm(Array *, Array *); Array *fnLeft(Array *, Array *); Array *fnRight(Array *, Array *); Array *fnCatenateFirst(Array *, Array *); diff --git a/array.c b/array.c index 4913112..a2afc44 100644 --- a/array.c +++ b/array.c @@ -41,3 +41,41 @@ simplescalar(Array *a) { return simplearray(a) && a->rank == 0; } + +Array * +extend(Array *a, Array *b) +{ + /* extend the singleton a to the shape of b */ + Array *shape = fnShape(b); + Array *res = fnReshape(shape, a); + freearray(shape); + return res; +} + +int +scalarextend(Array *a, Array *b, Array **aa, Array **bb) +{ + /* Extend the arrays a and b to have the same shape. + The resulting arrays are stored in aa and bb, + except when the ranks don't match or extension can't + happen, in which case the function returns 0 and + aa and bb are unchanged. + */ + + if(a->size == 1 && b->size != 1){ + *aa = extend(a, b); + *bb = fnSame(b); + }else if(b->size == 1 && a->size != 1){ + *aa = fnSame(a); + *bb = extend(b, a); + }else if(a->size == b->size && a->rank == b->rank){ + /* Check that each dimension matches */ + for(int i = 0; i < a->rank; i++) + if(a->shape[i] != b->shape[i]) + return 0; + *aa = fnSame(a); + *bb = fnSame(b); + }else + return 0; + return 1; +} \ No newline at end of file diff --git a/functions.c b/functions.c index bbac1a9..db9fe01 100644 --- a/functions.c +++ b/functions.c @@ -62,12 +62,12 @@ fnmonad monadfunctiondefs[] = { }; fndyad dyadfunctiondefs[] = { - 0, /* + */ - 0, /* - */ - 0, /* × */ - 0, /* ÷ */ - 0, /* * */ - 0, /* ⍟ */ + fnPlus, /* + */ + fnMinus, /* - */ + fnTimes, /* × */ + fnDivide, /* ÷ */ + fnPower, /* * */ + fnLogarithm, /* ⍟ */ 0, /* ⌹ */ 0, /* ○ */ 0, /* ! */ @@ -188,6 +188,120 @@ fnShape(Array *right) /* Dyadic functions */ +Array * +fnPlus(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] += rightarr->intdata[i]; + freearray(leftarr); + freearray(rightarr); + return res; +} + +Array * +fnMinus(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] -= rightarr->intdata[i]; + freearray(leftarr); + freearray(rightarr); + return res; +} + +Array * +fnTimes(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] *= rightarr->intdata[i]; + freearray(leftarr); + freearray(rightarr); + return res; +} + +Array * +fnDivide(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] /= rightarr->intdata[i]; + freearray(leftarr); + freearray(rightarr); + return res; +} + +Array * +fnPower(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] = pow(res->intdata[i], rightarr->intdata[i]); + freearray(leftarr); + freearray(rightarr); + return res; +} + +Array * +fnLogarithm(Array *left, Array *right) +{ + Array *leftarr; + Array *rightarr; + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + + Array *res = duparray(leftarr); + for(int i = 0; i < leftarr->size; i++) + res->intdata[i] = log(rightarr->intdata[i])/log(res->intdata[i]); + freearray(leftarr); + freearray(rightarr); + return res; +} + Array * fnLeft(Array *left, Array *right) { -- cgit v1.2.3