summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h1
-rw-r--r--functions.c37
2 files changed, 37 insertions, 1 deletions
diff --git a/apl9.h b/apl9.h
index 8ec4e78..4bb1296 100644
--- a/apl9.h
+++ b/apl9.h
@@ -203,6 +203,7 @@ Array *fnTable(Array *);
Array *fnShape(Array *);
Array *fnReverseLast(Array *);
Array *fnReverseFirst(Array *);
+Array *fnTranspose(Array *);
/* Dyadic functions from function.c */
Array *fnPlus(Array *, Array *);
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 *