summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h8
-rw-r--r--array.c38
-rw-r--r--functions.c126
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, /* ! */
@@ -189,6 +189,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)
{
USED(right);