From 12e1d1fe6464964b2bee1b83b8524445fc2bbe2c Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 21 Jan 2022 22:37:18 +0000 Subject: =?UTF-8?q?Implement=20scans=20=E2=8D=80=20and=20\?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apl9.h | 2 ++ hybrids.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/apl9.h b/apl9.h index 6e6574e..92a5127 100644 --- a/apl9.h +++ b/apl9.h @@ -274,7 +274,9 @@ Array *opOver(Datum *, Datum *, Array *, Array *); /* Monadic operators from hybrids.c */ Array *opReduceLast(Datum *, Array *, Array *); +Array *opScanLast(Datum *, Array *, Array *); Array *opReduceFirst(Datum *, Array *, Array *); +Array *opScanFirst(Datum *, Array *, Array *); /* Global variables */ extern int traceeval; /* eval.c */ diff --git a/hybrids.c b/hybrids.c index 39f3f7a..00977da 100644 --- a/hybrids.c +++ b/hybrids.c @@ -15,9 +15,9 @@ fndyad hybridfunctiondefs[] = { opmonad hybridoperatordefs[] = { opReduceLast, /* / */ - 0, /* \ */ + opScanLast, /* \ */ opReduceFirst, /* ⌿ */ - 0, /* ⍀ */ + opScanFirst, /* ⍀ */ }; /* function definitions */ @@ -37,6 +37,20 @@ opReduceLast(Datum *lefto, Array *left, Array *right) return res; } +Array * +opScanLast(Datum *lefto, Array *left, Array *right) +{ + if(left) + throwerror(L"f\ doesn't take a left argument", ESyntax); + + right = fnTranspose(right); + Array *tmp = opScanFirst(lefto, left, right); + Array *res = fnTranspose(tmp); + freearray(right); + freearray(tmp); + return res; +} + Array * opReduceFirst(Datum *lefto, Array *left, Array *right) { @@ -80,5 +94,35 @@ opReduceFirst(Datum *lefto, Array *left, Array *right) index->arraydata[index->size-1]->intdata[0]++; } freearray(index); + return result; } + +Array * +opScanFirst(Datum *lefto, Array *left, Array *right) +{ + if(left) + throwerror(L"f⍀ doesn't take a left argument", ESyntax); + + Array *result = allocarray(AtypeArray, right->rank, right->size); + for(int i = 0; i < right->rank; i++) + result->shape[i] = right->shape[i]; + + int n = result->shape[0]; + int m = result->size / n; + for(int i = 0; i < n; i++){ + Array *len = mkscalarint(i + 1); + Array *index = fnIndexGenerator(len); + Array *ix = fnEnclose(index); + Array *subarr = fnIndex(ix, right); + Array *subres = opReduceFirst(lefto, left, subarr); + for(int j = 0; j < m; j++) + result->arraydata[i*m + j] = arrayitem(subres, j); + freearray(len); + freearray(index); + freearray(ix); + freearray(subarr); + freearray(subres); + } + return result; +} \ No newline at end of file -- cgit v1.2.3