summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-28 23:46:45 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-28 23:46:45 +0000
commitc1c3b27543305ed24a52d852fd4d0d5b9855f349 (patch)
treeac492183aad5c0d5fb6024c97fcb06926f3712f5 /functions.c
parentc5d0ef8e53608da468f89837a12ab10ecc401978 (diff)
Implement index of (X⍳Y)
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/functions.c b/functions.c
index 997c1b4..6e0c6b6 100644
--- a/functions.c
+++ b/functions.c
@@ -100,7 +100,7 @@ fndyad dyadfunctiondefs[] = {
fnIndex, /* ⌷ */
0, /* ⍋ */
0, /* ⍒ */
- 0, /* ⍳ */
+ fnIndexOf, /* ⍳ */
0, /* ⍸ */
fnMembership, /* ∊ */
0, /* ⍷ */
@@ -1165,6 +1165,64 @@ fnIndex(Array *left, Array *right)
}
Array *
+fnIndexOf(Array *left, Array *right)
+{
+ if(left->rank < 1)
+ throwerror(nil, ERank);
+ if(right->rank < left->rank-1)
+ throwerror(nil, ERank);
+ int i, j;
+ for(i = 0; i < left->rank-1; i++)
+ if(left->shape[left->rank-1-i] != right->shape[right->rank-1-i])
+ throwerror(nil, EShape);
+
+ int rank = right->rank + 1 - left->rank;
+ int size = 1;
+ int io = globalIO();
+ int n = left->shape[0];
+ for(i = 0; i < rank; i++)
+ size *= right->shape[i];
+
+ Array *result = allocarray(AtypeInt, rank, size);
+ for(i = 0; i < rank; i++)
+ result->shape[i] = right->shape[i];
+
+ /* Reshape Y to allow easy picking of sub-arrays */
+ Array *rightshape = allocarray(AtypeInt, 1, right->rank - rank + 1);
+ rightshape->shape[0] = rightshape->size;
+ rightshape->intdata[0] = size;
+ for(i = 0; i < rightshape->size - 1; i++)
+ rightshape->intdata[rightshape->size-1-i] = right->shape[right->rank-1-i];
+ right = fnReshape(rightshape, right);
+
+ Array **lefts = malloc(sizeof(Array *) * n);
+ Array *index = mkscalarint(io);
+ for(i = 0; i < n; i++){
+ index->intdata[0] = i+io;
+ lefts[i] = fnIndex(index, left);
+ }
+ for(i = 0; i < size; i++){
+ index->intdata[0] = i+io;
+ Array *target = fnIndex(index, right);
+ for(j = 0; j < n; j++)
+ if(comparearray(lefts[j], target, 1) == 0){
+ result->intdata[i] = j+io;
+ break;
+ }
+ if(j == n)
+ result->intdata[i] = n+io;
+ freearray(target);
+ }
+
+ for(i = 0; i < n; i++)
+ freearray(lefts[i]);
+ free(lefts);
+ freearray(rightshape);
+ freearray(right);
+ return result;
+}
+
+Array *
fnMembership(Array *left, Array *right)
{
/* TODO avoid outer product */