summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-18 02:34:02 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-18 02:34:02 +0000
commit1cc5b2f1a0317bb4aedf9ae6d319eb1f77170a65 (patch)
tree55b22125ce859e24280fe171cc9841311a46e376 /functions.c
parent235f448cfdf7b6c1f1664cd32fa769670bdd0d6c (diff)
Add monadic ⍉ transpose
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c37
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 *