diff --git a/src/builtins/transpose.c b/src/builtins/transpose.c index 6855e6a2..2a724507 100644 --- a/src/builtins/transpose.c +++ b/src/builtins/transpose.c @@ -25,7 +25,10 @@ // COULD convert boolean to integer for some axis reorderings // SHOULD have a small-subarray transposer using one or a few shuffles -// Transpose inverse ⍉⁼𝕩: data movement of ⍉ with different shape logic +// ⍉⁼𝕩: data movement of ⍉ with different shape logic +// 𝕨⍉⁼𝕩: compute inverse 𝕨, length 1+βŒˆΒ΄π•¨ +// Under Transpose supports invertible cases +// SHOULD implement Under with duplicate axes, maybe as Under Select // COULD implement fast β‰βŸn // SHOULD convert ⍉ with rank to a Reorder Axes call @@ -379,10 +382,8 @@ B transp_uc1(B t, B o, B x) { return transp_im(m_f64(0), c1(o, transp_c1(t, x))); } -B transp_ix(B t, B w, B x) { - if (isAtm(x)) thrM("⍉⁼: 𝕩 must not be an atom"); - ur xr=RNK(x); - +// Consumes w; return bi_N if w contained duplicates +static B invert_transp_w(B w, ur xr) { if (isAtm(w)) { if (xr<1) thrM("⍉⁼: Length of 𝕨 must be at most rank of 𝕩"); usz a=o2s(w); @@ -392,7 +393,7 @@ B transp_ix(B t, B w, B x) { } else { if (RNK(w)>1) thrM("⍉⁼: 𝕨 must have rank at most 1"); usz wia = IA(w); - if (wia==0) { decG(w); return x; } + if (wia==0) return w; if (xr=xr) thrF("⍉⁼: Axis %s does not exist (%i≑=𝕩)", a, xr); - if (p[i]!=xr) thrM("⍉⁼: Duplicate axes"); + if (p[a]!=xr) { TFREE(p); decG(w); return bi_N; } // Handled by caller max = a>max? a : max; p[a] = i; } @@ -411,11 +412,25 @@ B transp_ix(B t, B w, B x) { for (usz i=0, j=wia; iim = transp_im; c(BFn,bi_transp)->ix = transp_ix; c(BFn,bi_transp)->uc1 = transp_uc1; + c(BFn,bi_transp)->ucw = transp_ucw; }