diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-18 02:34:02 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-18 02:34:02 +0000 |
commit | 1cc5b2f1a0317bb4aedf9ae6d319eb1f77170a65 (patch) | |
tree | 55b22125ce859e24280fe171cc9841311a46e376 /functions.c | |
parent | 235f448cfdf7b6c1f1664cd32fa769670bdd0d6c (diff) |
Add monadic ⍉ transpose
Diffstat (limited to 'functions.c')
-rw-r--r-- | functions.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/functions.c b/functions.c index eff944f..353ad88 100644 --- a/functions.c +++ b/functions.c @@ -56,7 +56,7 @@ fnmonad monadfunctiondefs[] = { fnShape, /* ⍴ */ fnReverseLast, /* ⌽ */ fnReverseFirst, /* ⊖ */ - 0, /* ⍉ */ + fnTranspose, /* ⍉ */ 0, /* ⍎ */ 0, /* ⍕ */ }; @@ -277,6 +277,41 @@ fnReverseFirst(Array *right) return res; } +Array * +fnTranspose(Array *right) +{ + Array *res = duparray(right); + for(int i = 0; i < res->rank; i++) + res->shape[i] = right->shape[res->rank - 1 - i]; + + int from, to; + int *sizesFrom = malloc(sizeof(int) * right->rank); + int *sizesTo = malloc(sizeof(int) * right->rank); + int accFrom = 1, accTo = 1; + for(int i = 0; i < right->rank; i++){ + sizesFrom[i] = accFrom; + sizesTo[i] = accTo; + accFrom *= res->shape[i]; + accTo *= right->shape[i]; + } + + for(from = 0; from < right->size; from++){ + to = 0; + int tmp = from; + for(int i = right->rank-1; i >= 0; i--){ + to += sizesTo[right->rank-1-i] * (tmp / sizesFrom[i]); + tmp = tmp % sizesFrom[i]; + } + memcpy( + res->rawdata + to * datasizes[res->type], + right->rawdata + from * datasizes[res->type], + datasizes[res->type]); + } + free(sizesFrom); + free(sizesTo); + return res; +} + /* Dyadic functions */ Array * |