𝕨⥊𝕩 implementation refactoring & testing

This commit is contained in:
dzaima 2025-05-29 22:32:22 +03:00
parent 4e0957f668
commit 541e5a805e
3 changed files with 64 additions and 26 deletions

View File

@ -198,65 +198,72 @@ B shape_c1(B t, B x) {
}
B shape_c2(B t, B w, B x) {
usz xia = isArr(x)? IA(x) : 1;
usz nia = 1;
ur nr;
ShArr* sh;
if (isF64(w)) {
nia = o2s(w);
usz tmp;
if (q_usz(w)) {
nia = o2sG(w);
nr = 1;
sh = NULL;
} else {
if (RARE(isAtm(w))) w = m_unit(w);
if (RNK(w)>1) thrM("𝕨⥊𝕩: 𝕨 must have rank at most 1");
if (IA(w)>UR_MAX) thrM("𝕨⥊𝕩: Result rank too large");
if (RNK(w) > 1) thrF("𝕨⥊𝕩: 𝕨 must be a list or unit (%i ≡ =𝕩)", RNK(w));
if (IA(w) > UR_MAX) thrF("𝕨⥊𝕩: Result rank too large (%i ≡ ≠𝕨)", IA(w));
nr = IA(w);
sh = nr<=1? NULL : m_shArr(nr);
sh = nr<=1? RFLD(&tmp,ShArr,a) : m_shArr(nr);
SGetU(w)
i32 unkPos = -1;
i32 unkInd ONLY_GCC(=0);
i32 unkID ONLY_GCC(=0);
usz xia ONLY_GCC(=0);
bool bad=false, good=false;
for (i32 i = 0; i < nr; i++) {
B c = GetU(w, i);
if (isF64(c)) {
usz v = o2s(c);
if (sh) sh->a[i] = v;
bad|= mulOn(nia, v);
if (q_usz(c)) {
usz v = o2sG(c);
sh->a[i] = v;
if (RARE(mulOn(nia, v))) bad = true;
good|= v==0;
} else {
if (isArr(c) || !isVal(c)) thrM("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑");
if (RARE(!isPrim(c))) {
if (isF64(c)) thrF("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained %B)", c);
else thrF("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained %S)", genericDesc(c));
}
if (unkPos!=-1) thrM("𝕨⥊𝕩: 𝕨 contained multiple computed axes");
unkPos = i;
if (!isPrim(c)) thrM("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑");
unkInd = RTID(c);
good|= xia==0 | unkInd==n_floor;
unkID = RTID(c);
xia = isArr(x)? IA(x) : 1;
good|= xia==0 | unkID==n_floor;
}
}
if (bad && !good) thrM("𝕨⥊𝕩: 𝕨 too large");
if (unkPos!=-1) {
if (unkInd!=n_atop & unkInd!=n_floor & unkInd!=n_reverse & unkInd!=n_take) thrM("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑");
if (unkID!=n_atop & unkID!=n_floor & unkID!=n_reverse & unkID!=n_take) thrF("𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained %B)", GetU(w,unkPos));
if (nia==0) thrM("𝕨⥊𝕩: Can't compute axis when the rest of the shape is empty");
i64 div = xia/nia;
i64 mod = xia%nia;
usz div = xia/nia;
usz mod = xia%nia;
usz item;
bool fill = false;
if (unkInd == n_atop) {
if (mod!=0) thrM("𝕨⥊𝕩: Shape must be exact when reshaping with ∘");
if (unkID == n_atop) {
if (mod!=0) thrF("𝕨⥊𝕩: Shape must be exact when reshaping with ∘ (%H ≡ ≢𝕩, %s is the product of non-computed axis)", x, nia);
item = div;
} else if (unkInd == n_floor) {
} else if (unkID == n_floor) {
item = div;
} else if (unkInd == n_reverse) {
} else if (unkID == n_reverse) {
item = mod? div+1 : div;
} else if (unkInd == n_take) {
} else if (unkID == n_take) {
item = mod? div+1 : div;
fill = true;
} else UD;
if (sh) sh->a[unkPos] = item;
sh->a[unkPos] = item;
nia = uszMul(nia, item);
if (fill) {
if (!isArr(x)) x = m_unit(x);
x = taga(arr_shVec(take_impl(nia, x)));
xia = nia;
decG(w);
return truncReshape(x, nia, nia, nr, sh); // could be improved
}
}
decG(w);
@ -264,6 +271,7 @@ B shape_c2(B t, B w, B x) {
Arr* r;
if (isArr(x)) {
usz xia = IA(x);
if (nia <= xia) {
return truncReshape(x, xia, nia, nr, sh);
} else {

View File

@ -53,6 +53,8 @@
2 'a'+¨ 1 %% "b "
2 {} 'a'+¨ 1 %% "b "
•internal.HasFill "ab""cde" %% 0
# TODO:
# ⟨↑‿3⥊↕10 ⋄ ↑‿3⥊<¨↕10 ⋄ ↑‿3⥊<˘↕10⟩
# 5‿¯5↑⌜⟨↕2 ⋄ "ab" ⋄ <¨↕2 ⋄ <˘↕2⟩

View File

@ -379,9 +379,37 @@ b←1↓1∾a←"hello" ⋄ b ⌽⎊'e' ⥊⟜1⍟2 5 ⋄ a ≡○•Hash b %% 1
0 %% 0
# 𝕨⥊𝕩
!"𝕨⥊𝕩: Result rank too large" % (03002)0
!"𝕨⥊𝕩: Result rank too large (301 ≡ ≠𝕨)" % (03002)0
!"Out of memory" % %USE eqerr {(𝕩2) 1.1}¨_eqerr 63-10
!"Out of memory" % %USE eqerr {(𝕩2) 71.1}¨_eqerr 63-10
1e81e81e81e85 %% 1e81e801e81e80
{1e81e8𝕩1e81e80}¨ %% 1e81e801e81e80
!"𝕨⥊𝕩: 𝕨 too large" % %USE eqerr {1e81e8𝕩1e81e8"foo"}_eqerr
!"𝕨⥊𝕩: 𝕨 must be a list or unit (4 ≡ =𝕩)" % %USE eqerr 31412 _eqerr 10, 0, 4
!"𝕨⥊𝕩: Empty 𝕩 and non-empty result" % 10100
!"𝕨⥊𝕩: Shape must be exact when reshaping with ∘ (⟨42⟩ ≡ ≢𝕩, 10 is the product of non-computed axis)" % 25 42
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained namespace)" % %USE eqerr ({𝕩,𝕩,1𝕩} {}) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained function)" % %USE eqerr ({𝕩,𝕩,1𝕩}{+¨}) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained function)" % %USE eqerr ({𝕩,𝕩,1𝕩}•out) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained ¨)" % %USE eqerr ({𝕩,𝕩,1𝕩} {¨}) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained ∧)" % %USE eqerr ({𝕩,𝕩,1𝕩} {}) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained 1e40)" % %USE eqerr ({𝕩,𝕩,1𝕩}1e40) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained ¯10)" % %USE eqerr ({𝕩,𝕩,1𝕩} ¯10) _eqerr 0, 1, 10
!"𝕨⥊𝕩: 𝕨 must consist of natural numbers or ∘ ⌊ ⌽ ↑ (contained 10.5)" % %USE eqerr ({𝕩,𝕩,1𝕩}10.5) _eqerr 0, 1, 10
!"𝕨⥊𝕩: Can't compute axis when the rest of the shape is empty" % %USE eqerr {4𝕨0 𝕩}_eqerr 1, 0
¨ %%
1¨ %% 1
"hello"¨ %% "hello"
!"𝕨⥊𝕩: 𝕨 contained multiple computed axes" % 1
!"𝕨⥊𝕩: 𝕨 contained multiple computed axes" % 1
%USE eqvarv 4 _eqvarv_"i" 9 %% [0123, 4567, 8000]
%USE eqvar 4 _eqvar 9 %% [0123, 4567, 8012]
%USE eqvar 4 _eqvar 9 %% [0123, 4567]
%USE eqvarv 4 _eqvarv_"i" "abcde" %% ["abcd", "e "]
%USE eqvar 4 _eqvar "abcde" %% ["abcd", "eabc"]
%USE eqvar 4 _eqvar "abcde" %% ["abcd"]
# 𝕨⍷𝕩
%USE eqvar "ab" _eqvar "" %%