summaryrefslogtreecommitdiff
path: root/hybrids.c
diff options
context:
space:
mode:
Diffstat (limited to 'hybrids.c')
-rw-r--r--hybrids.c48
1 files changed, 46 insertions, 2 deletions
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 */
@@ -38,6 +38,20 @@ opReduceLast(Datum *lefto, Array *left, Array *right)
}
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)
{
if(left)
@@ -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