From b63ca926df347798ea113d7b197192bd28399f5a Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Thu, 20 Jan 2022 22:53:30 +0000 Subject: =?UTF-8?q?Implement=20guards,=20and=20start=20work=20on=20?= =?UTF-8?q?=E2=86=91=20and=20=E2=86=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-) (limited to 'functions.c') diff --git a/functions.c b/functions.c index 9649e27..7d8b46c 100644 --- a/functions.c +++ b/functions.c @@ -36,8 +36,8 @@ fnmonad monadfunctiondefs[] = { 0, /* ∧ */ 0, /* ⍲ */ 0, /* ⍱ */ - 0, /* ↑ */ - 0, /* ↓ */ + fnMix, /* ↑ */ + fnSplit, /* ↓ */ fnEnclose, /* ⊂ */ 0, /* ⊃ */ fnNest, /* ⊆ */ @@ -91,7 +91,7 @@ fndyad dyadfunctiondefs[] = { 0, /* ∧ */ 0, /* ⍲ */ 0, /* ⍱ */ - 0, /* ↑ */ + fnTake, /* ↑ */ 0, /* ↓ */ 0, /* ⊂ */ 0, /* ⊃ */ @@ -156,6 +156,15 @@ runfunc(Function f, Array *left, Array *right) } } +Array * +rundfn(Rune *code, Array *left, Array *right) +{ + Function dfn; + dfn.type = FunctypeDfn; + dfn.dfn = code; + return runfunc(dfn, left, right); +} + /* Monadic functions */ Array * @@ -171,6 +180,110 @@ fnTally(Array *right) return mkscalarint(right->rank==0 ? 1 : right->shape[0]); } +Array * +fnMix(Array *right) +{ + if(right->type != AtypeArray || right->size == 0) + return fnSame(right); + + int commonrank = 0; + int i,j; + for(i = 0; i < right->size; i++) + if(right->arraydata[i]->rank > commonrank) + commonrank = right->arraydata[i]->rank; + + Array *commonshape = allocarray(AtypeInt, 1, commonrank); + commonshape->shape[0] = commonrank; + for(i = 0; i < commonrank; i++) + commonshape->intdata[i] = 0; + + for(i = 0; i < right->size; i++){ + Array *a = right->arraydata[i]; + for(j = 0; j < a->rank; j++){ + if(a->shape[a->rank-1-j] > commonshape->intdata[commonrank-1-j]) + commonshape->intdata[commonrank-1-j] = a->shape[a->rank-1-j]; + } + } + + int size = 1; + int commonsize = 1; + for(i = 0; i < right->rank; i++) + size *= right->shape[i]; + for(i = 0; i < commonshape->size; i++){ + size *= commonshape->intdata[i]; + commonsize *= commonshape->intdata[i]; + } + + /* TODO: think about types */ + Array *result = allocarray(right->arraydata[0]->type, right->rank + commonrank, size); + for(i = 0; i < right->rank; i++) + result->shape[i] = right->shape[i]; + for(j = 0; j < commonshape->size; j++) + result->shape[i+j] = commonshape->intdata[j]; + + int *index = malloc(sizeof(int) * commonrank); + int offset; + for(i = 0; i < size/commonsize; i++){ + print("COPY CELL %d\n", i); + Array *a = right->arraydata[i]; + Array *fill = fillelement(a); + if(a->rank == 0){ + print("Copy scalar :-)\n"); + memcpy( + result->rawdata + i * commonsize * datasizes[a->type], + a->rawdata, datasizes[a->type]); + if(a->type == AtypeArray) + incref(a->arraydata[0]); + for(j = 1; j < commonsize; j++){ + memcpy(result->rawdata + (i * commonsize + j) * datasizes[a->type], + fill->rawdata, datasizes[a->type]); + if(fill->type == AtypeArray) + incref(fill->arraydata[0]); + } + }else{ + for(j = 0; j < commonrank; j++) + index[j] = 0; + for(j = 0, offset = 0; offset < commonsize; j++){ + for(int k = 0; index[commonrank-1-k] == a->shape[a->rank-1-k]; k++){ + int nfill = commonshape->intdata[commonrank-1-k] - a->shape[a->rank-1-k]; + if(nfill) + print("Adding %d fills\n", nfill); + while(nfill--){ + memcpy(result->rawdata + (i * commonsize + offset) * datasizes[a->type], + fill->rawdata, datasizes[a->type]); + if(fill->type == AtypeArray) + incref(fill->arraydata[0]); + offset++; + } + index[commonrank-1-k] = 0; + index[commonrank-2-k]++; + } + if(offset < commonsize){ + print("Copying from %d to %d\n", j, commonsize*i+offset); + memcpy( + result->rawdata + (i * commonsize + offset) * datasizes[a->type], + a->rawdata + j * datasizes[a->type], datasizes[a->type]); + if(a->type == AtypeArray) + incref(a->arraydata[j]); + offset++; + index[commonrank-1]++; + } + } + } + freearray(fill); + } + free(index); + free(commonshape); + return result; +} + +Array * +fnSplit(Array *right) +{ + Rune *code = L"0≡≢⍴⍵: ⍵ ⋄ (⊂⍵)⌷⍨¨⍳≢⍵"; + return rundfn(code, nil, right); +} + Array * fnEnclose(Array *right) { @@ -564,6 +677,66 @@ fnMatch(Array *left, Array *right) return mkscalarint(cmp == 0); } +Array * +fnTake(Array *left, Array *right) +{ + if(left->type != AtypeInt || left->rank > 1 || left->size > right->rank){ + print("Invalid left arg to ↑\n"); + exits(nil); + } + + int i; + if(left->size == right->rank) + left = fnSame(left); + else{ + Array *old = left; + left = fnShape(right); + for(i = 0; i < old->size; i++) + left->intdata[i] = old->intdata[i]; + } + + if(right->rank == 0){ + Array *leftshape = fnShape(left); + right = fnReshape(leftshape, right); + freearray(leftshape); + } + right = fnSame(right); + + int *shape = malloc(sizeof(int) * left->size); + int size = 1; + for(i = 0; i < left->size; i++){ + int s = left->intdata[i]; + shape[i] = s < 0 ? -s : s; + size *= shape[i]; + } + + Array *result = allocarray(right->type, right->rank, size); + for(i = 0; i < right->rank; i++) + result->shape[i] = shape[i]; + + int *index = mallocz(sizeof(int) * left->size, 1); + int offset; + for(i = 0, offset = 0; offset < size; i++){ + for(int j = left->size-1; index[j] == shape[j]; j--){ + index[j] = 0; + index[j-1]++; + } + print("Result Index: "); + for(int j = 0; j < left->size; j++) + print("%d ", index[j]); + print("\n"); + + /* if index is part of left vector, select those places */ + + offset++; + index[left->size-1]++; + } + + freearray(left); + freearray(right); + return result; +} + Array * fnIndex(Array *left, Array *right) { -- cgit v1.2.3