From 6eca24ce0a263192793eebbe03ea8429a77c92bc Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 26 Jun 2024 08:40:49 -0400 Subject: [PATCH] =?UTF-8?q?Special=20code=20for=20=E2=88=BE=CB=9D=CB=98=20?= =?UTF-8?q?and=20fold-cells=20of=20empty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/cells.c | 16 ++++++++++++---- src/builtins/fold.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/builtins/cells.c b/src/builtins/cells.c index c484ddd0..c6ddcca4 100644 --- a/src/builtins/cells.c +++ b/src/builtins/cells.c @@ -7,8 +7,13 @@ B fne_c1(B, B); B shape_c2(B, B, B); B transp_c2(B, B, B); -B fold_rows(Md1D* d, B x); // from fold.c -B fold_rows_bit(Md1D* d, B x, usz n, usz m); // from fold.c + +// from fold.c: +B fold_rows(Md1D* d, B x); +B fold_rows_bit(Md1D* d, B x, usz n, usz m); +B insert_cells_join(B x, usz* xsh, ur cr, ur k); +B insert_cells_identity(B x, B f, usz* xsh, ur xr, ur k, u8 rtid); + B scan_rows_bit(u8, B x, usz m); // from scan.c B takedrop_highrank(bool take, B w, B x); // from sfns.c B try_interleave_cells(B w, B x, ur xr, ur xk, usz* xsh); // from transpose.c @@ -485,9 +490,12 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr case n_const: f=fd->f; goto const_f; case n_cell: cr-= cr>0; return for_cells_c1(fd->f, xr, cr, xr-cr, x, U'˘'); case n_fold: if (cr != 1) break; // else fall through - case n_insert: if (TI(x,elType)!=el_B && isFun(fd->f) && xsh[k]>0) { - usz m = xsh[k]; + case n_insert: if (cr>0 && isFun(fd->f)) { u8 frtid = v(fd->f)->flags-1; + if (frtid==n_join && rtid==n_insert) return insert_cells_join(x, xsh, cr, k); + usz m = xsh[k]; + if (m==0) return insert_cells_identity(x, fd->f, xsh, xr, k, rtid); + if (TI(x,elType)==el_B) break; if (m==1 || frtid==n_ltack) return select_cells(0 , x, cam, k, false); if ( frtid==n_rtack) return select_cells(m-1, x, cam, k, false); if (isPervasiveDyExt(fd->f) && 1==shProd(xsh, k+1, xr)) { diff --git a/src/builtins/fold.c b/src/builtins/fold.c index 1030c1cd..251b0683 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -14,7 +14,8 @@ // Insert with rank (˝˘ or ˝⎉k), or fold on flat array // SHOULD optimize dyadic insert with rank // Length 1, ⊣⊢: implemented as ⊏˘ -// SHOULD reshape identity for fast ˝˘ on empty rows +// ∾˝ with rank: reshape argument +// Arithmetic on empty: reshape identity // Boolean operand, cell size 1: // +: popcount // Rows length ≤64: extract rows, popcount each @@ -451,6 +452,38 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f; return insert_base(f, x, 1, w); } +B insert_cells_join(B x, usz* xsh, ur cr, ur k) { + assert(k > 0); + if (cr <= 1) { + if (xsh[k]==0) thrM("˝: Identity does not exist"); + return x; + } + ur rr = k+cr-1; // result rank (>1) + ShArr* rsh; + rsh = m_shArr(rr); + shcpy(rsh->a, xsh, k); + rsh->a[k] = xsh[k] * xsh[k+1]; + shcpy(rsh->a+k+1, xsh+k+2, cr-2); + Arr* r = TI(x,slice)(x, 0, IA(x)); + arr_shSetUG(r, rr, rsh); + decG(x); return taga(r); +} +B insert_cells_identity(B x, B f, usz* xsh, ur xr, ur k, u8 rtid) { + B id; + if (!isFun(f) || q_N(id = TI(f,identity)(f))) thrF("%c: Identity not found", rtid==n_fold? U'´' : U'˝'); + bool cs = !isArr(id); // if x cell shape is used (not table) + usz ria = shProd(xsh, 0, k); + if (cs) ria*= shProd(xsh, k+1, xr); + Arr* r = reshape_one(ria, id); + ur rr = cs? xr-1 : k; + if (rr == 1) arr_shVec(r); else { + usz* rsh = arr_shAlloc(r, rr); + shcpy(rsh, xsh, k); + if (cs) shcpy(rsh+k, xsh+k+1, rr-k); + } + decG(x); return taga(r); +} + // Arithmetic fold/insert on rows of flat rank-2 array x B transp_c1(B, B); B join_c2(B, B, B);