-
Notifications
You must be signed in to change notification settings - Fork 3
[#144] Add: test coverage for reverse primitive #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Magnus-Mage
wants to merge
5
commits into
Dyalog:main
Choose a base branch
from
Magnus-Mage:tests/reverse-tests
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
80d2aed
Add: test coverage for reverse primitive
Magnus-Mage bbdcae6
Add: reverse test suite
Magnus-Mage 81fd84b
Adding more tests for extreme array boundaries, decimal points, mixed…
Magnus-Mage 96ac974
Nested arrays tests
Magnus-Mage 5c0291c
add: bracket-axis reverse support(commented out for now)
Magnus-Mage File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,301 @@ | ||
| :Namespace reverse | ||
| Assert←#.unittest.Assert | ||
| isDyalogClassic←#.utils.isClassic | ||
|
|
||
| ⍝ Model implements reverse via rank operator and arithmetic indexing | ||
| ⍝ Does not use ⌽, providing a truly independent implementation for verification | ||
| ⍝ Guard handles rank-0 scalars where ⍤1 cannot operate | ||
| modelReverse←{ | ||
| 0=≢⍴⍵:⍵ | ||
| ⎕IO←1 ⍝ Index generation (⍳) requires ⎕IO←1 | ||
| n←(≢⍴⍵)⊃⍴⍵ | ||
| ({⍵[(n+1)-⍳n]}⍤1)⍵ | ||
| } | ||
|
|
||
| ⍝ Model for bracket-axis reverse ⌽[k] | ||
| ⍝ Implements reverse along a specified axis using Squad indexing (⌷) | ||
| ⍝ ⍺ is the axis to reverse (1-indexed, per bracket-axis notation) | ||
| ⍝ Uses vector of index vectors with Squad to reverse the specified axis | ||
| ⍝ bracket-axis tests below are also commented | ||
| ⍝modelReverseBracket←{ | ||
| ⍝ 0=≢⍴⍵:⍵ | ||
| ⍝ ⎕IO←1 | ||
| ⍝ axis←⍺ | ||
| ⍝ n←axis⊃⍴⍵ | ||
| ⍝ ⍝ Build index vectors for each axis | ||
| ⍝ idxs←⍳¨⍴⍵ | ||
| ⍝ ⍝ Reverse the specified axis | ||
| ⍝ idxs[axis]←⊂(n+1)-⍳n | ||
| ⍝ ⍝ Use Squad indexing (⌷) with enclosed indices | ||
| ⍝ idxs⌷⍵ | ||
| ⍝} | ||
|
|
||
| ∇ r←testDesc | ||
| r←'for ',case | ||
| ∇ | ||
|
|
||
| ∇ {r}←test_reverse;bool;i1;i2;i3;dbl;Hdbl;fl;Hfl;cmplx;Hcmplx;char0;char1;char2;char3;case;data;desc;scalar;empty;matrix;array3d;empty2d;empty3d;largeData;hashedData;RunVariations;data_rand_i1;data_rand_i2;data_rand_i4;data_rand_char1;data_rand_char2;quadparams;len;rows;cols;size;i1_min;i1_max;i2_min;i2_max;i4_min;i4_max;dbl_small;dbl_boundary;fl_small;fl_boundary | ||
| r←⍬ | ||
|
|
||
| ⍝ Monadic reverse has no implicit system variable dependencies | ||
| ⍝ quadparams are set to defaults as required by RunVariations | ||
| quadparams←(#.utils.ct_default) (#.utils.dct_default) (#.utils.fr_dbl) 1 (#.utils.div_0) | ||
|
|
||
| RunVariations←modelReverse #.testfns._RunVariationsWithModel_ ⌽ | ||
|
|
||
| data_rand_i1←1000 #.random.Ints 8 | ||
| data_rand_i2←1000 #.random.Ints 16 | ||
| data_rand_i4←1000 #.random.Ints 32 | ||
|
|
||
| :If ~isDyalogClassic | ||
| data_rand_char1←1000 #.random.Chars 8 | ||
| data_rand_char2←1000 #.random.Chars 16 | ||
| :EndIf | ||
|
|
||
| bool←0 1 | ||
| i1←{⍵,-⍵}⍳120 | ||
| i2←{⍵,-⍵}10000+⍳1000 | ||
| i3←{⍵,-⍵}100000+⍳100 | ||
|
|
||
| char0←⎕AV | ||
| :If ~isDyalogClassic | ||
| char1←⎕UCS⍳255 | ||
| char2←⎕UCS(1000+⍳100) | ||
| char3←⎕UCS(100000+⍳100) | ||
| :EndIf | ||
|
|
||
| dbl←{⍵,-⍵}1000.5+⍳100 | ||
| Hdbl←{⍵,-⍵}100000000000000+(2×⍳50) | ||
|
|
||
| ⍝ Decimal floating point data requires ⎕FR←1287 | ||
| ⎕FR←#.utils.fr_decf | ||
| fl←{⍵,-⍵}1000.5+⍳100 | ||
| Hfl←{⍵,-⍵}200000000000000000000000000000+(10000000000000000×⍳10) | ||
| ⎕FR←#.utils.fr_dbl | ||
|
|
||
| cmplx←{⍵,-⍵}(0J1×⍳100)+⌽⍳100 | ||
| Hcmplx←{⍵,-⍵}(100000000000000J100000000000000×⍳20) | ||
|
|
||
| ⍝ Extreme value testing: boundary values for each type | ||
| i1_min←¯128 | ||
| i1_max←127 | ||
| i2_min←¯32768 | ||
| i2_max←32767 | ||
| i4_min←¯2147483648 | ||
| i4_max←2147483647 | ||
| dbl_small←1E¯300+⍳10 ⍝ Very small positive decimals | ||
| dbl_boundary←i4_max+0.1 0.5 0.9 ⍝ Near int32 boundary | ||
| fl_small←⍬ | ||
| fl_boundary←⍬ | ||
| ⎕FR←#.utils.fr_decf | ||
| fl_small←1E¯6000+⍳10 ⍝ Very small positive decimals (decf) | ||
| fl_boundary←(2*127)+0.1 0.5 0.9 ⍝ Near decf boundary | ||
| ⎕FR←#.utils.fr_dbl | ||
|
|
||
| :For case :In 'bool' 'i1' 'i2' 'i3' 'dbl' 'Hdbl' 'fl' 'Hfl' 'cmplx' 'Hcmplx' 'i1_min' 'i1_max' 'i2_min' 'i2_max' 'i4_min' 'i4_max' 'dbl_small' 'dbl_boundary' 'fl_small' 'fl_boundary' | ||
| data←⍎case | ||
| desc←testDesc | ||
|
|
||
| ⍝ RunVariations: normal, scalar, empty, multiple shapes, shape with 0, model comparison, random data | ||
| r,←'T1'desc quadparams RunVariations,⊂data | ||
|
|
||
| desc←'Double reverse for ',case | ||
| r,←'T2'desc Assert data≡⌽⌽data | ||
|
|
||
| desc←'Datatype preserved for ',case | ||
| r,←'T3'desc Assert (⎕DR data)≡⎕DR ⌽data | ||
|
|
||
| ⍝ Large array stress test | ||
| desc←'Large array (10000) for ',case | ||
| largeData←10000⍴data | ||
| r,←'T4'desc Assert largeData≡⌽⌽largeData | ||
|
|
||
| ⍝ Hash collision handling test | ||
| :If 9=⎕NC'#.utils.hashArray' | ||
| hashedData←#.utils.hashArray data | ||
| desc←'Hashed array reverse for ',case | ||
| r,←'T5'desc Assert hashedData≡⌽⌽hashedData | ||
| :EndIf | ||
| :EndFor | ||
|
|
||
| ⍝ Explicit tests with ⎕IO variation (not covered by RunVariations) | ||
| :For ⎕IO :In #.utils.io_default #.utils.io_0 | ||
|
|
||
| ⍝ Explicit decimal precision preservation tests | ||
| desc←'Decimal precision: 0.1 0.2 0.3' | ||
| data←0.1 0.2 0.3 | ||
| r,←'TPrec1'desc Assert data≡⌽⌽data | ||
| r,←'TPrec2'desc Assert data≡modelReverse⌽data | ||
|
|
||
| desc←'Decimal precision: repeating decimals' | ||
| data←(⍳10)÷3 | ||
| r,←'TPrec3'desc Assert data≡⌽⌽data | ||
|
|
||
| desc←'Decimal precision: very small values' | ||
| data←1E¯15×⍳10 | ||
| r,←'TPrec4'desc Assert data≡⌽⌽data | ||
|
|
||
| desc←'Decimal precision: mixed magnitude' | ||
| data←1E15 1 1E¯15 | ||
| r,←'TPrec5'desc Assert data≡⌽⌽data | ||
|
|
||
| ⍝ Systematic shape variations for structural testing | ||
| ⍝ Different vector lengths | ||
| :For len :In 1 10 100 1000 10000 | ||
| data←len⍴i1 | ||
| desc←'Vector length ',⍕len | ||
| r,←('TLen',⍕len)desc Assert data≡⌽⌽data | ||
| :EndFor | ||
|
|
||
| ⍝ Tall matrices (many rows, few columns) | ||
| :For rows :In 10 100 1000 | ||
| matrix←rows 11⍴i1 | ||
| desc←'Tall matrix ',⍕rows,'x11' | ||
| r,←('TTall',⍕rows)desc Assert matrix≡⌽⌽matrix | ||
| :EndFor | ||
|
|
||
| ⍝ Wide matrices (few rows, many columns) | ||
| :For cols :In 10 100 1000 | ||
| matrix←11 cols⍴i1 | ||
| desc←'Wide matrix 11x',⍕cols | ||
| r,←('TWide',⍕cols)desc Assert matrix≡⌽⌽matrix | ||
| :EndFor | ||
|
|
||
| ⍝ Square matrices of different sizes | ||
| :For size :In 1 4 16 252 | ||
| matrix←size size⍴i1 | ||
| desc←'Square matrix ',⍕size,'x',⍕size | ||
| r,←('TSquare',⍕size)desc Assert matrix≡⌽⌽matrix | ||
| :EndFor | ||
|
|
||
| ⍝ Nested arrays: reverse reorders top-level elements, preserves nesting structure | ||
| desc←'Simple nested array (numeric)' | ||
| data←(i1 i2) | ||
| r,←'TNest1'desc Assert data≡⌽⌽data | ||
| r,←'TNest2'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| desc←'Deeply nested array (numeric)' | ||
| data←(i1 (i2 (i3 dbl))) | ||
| r,←'TNest3'desc Assert data≡⌽⌽data | ||
| r,←'TNest4'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| desc←'Mixed rank nested (numeric)' | ||
| data←(matrix (2 3 4⍴⍳24) (2 3⍴i1)) | ||
| r,←'TNest5'desc Assert data≡⌽⌽data | ||
| r,←'TNest6'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| ⍝ Mixed numeric/character arrays (type 326) | ||
| desc←'Mixed array: numbers and characters' | ||
| data←(42 'Hello' 3.14) | ||
| r,←'TMix1'desc Assert data≡⌽⌽data | ||
| r,←'TMix2'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| desc←'Mixed array: numeric and character vectors' | ||
| data←(i1 char0 dbl) | ||
| r,←'TMix3'desc Assert data≡⌽⌽data | ||
| r,←'TMix4'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| desc←'Nested mixed array' | ||
| data←(i1 'ABC' dbl) | ||
| r,←'TMix5'desc Assert data≡⌽⌽data | ||
| r,←'TMix6'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| desc←'Deeply nested mixed array' | ||
| data←(42 ('Hello' 3.14) char0) | ||
| r,←'TMix7'desc Assert data≡⌽⌽data | ||
| r,←'TMix8'desc Assert (modelReverse data)≡⌽data | ||
|
|
||
| ⍝ Namespace arrays | ||
| desc←'Namespace reverse' | ||
| r,←'Tns1'desc Assert ((# ⎕SE))≡⌽⌽(# ⎕SE) | ||
| r,←'Tns2'desc Assert (modelReverse(# ⎕SE))≡⌽(# ⎕SE) | ||
|
|
||
| desc←'Single namespace' | ||
| r,←'Tns3'desc Assert (,#)≡⌽,# | ||
|
|
||
| ⍝ Scalar edge case: rank 0 arrays | ||
| scalar←42 | ||
| desc←'Scalar unchanged' | ||
| r,←'TE1'desc Assert scalar≡⌽scalar | ||
|
|
||
| ⍝ Empty vector | ||
| empty←⍬ | ||
| desc←'Empty vector' | ||
| r,←'TE2'desc Assert empty≡⌽empty | ||
|
|
||
| ⍝ Empty arrays with non-zero trailing dimensions | ||
| empty2d←0 5⍴⍬ | ||
| desc←'Empty 2D array' | ||
| r,←'TEmpty1'desc Assert empty2d≡⌽empty2d | ||
| r,←'TEmpty2'desc Assert (⍴empty2d)≡⍴⌽empty2d | ||
|
|
||
| empty3d←0 0 5⍴⍬ | ||
| desc←'Empty 3D array' | ||
| r,←'TEmpty3'desc Assert empty3d≡⌽empty3d | ||
|
|
||
| ⍝ Multi-dimensional arrays: reverse along last axis | ||
| matrix←3 4⍴⍳12 | ||
| desc←'Matrix reverse' | ||
| r,←'TE3'desc Assert matrix≡⌽⌽matrix | ||
| r,←'TE4'desc Assert (⍴matrix)≡⍴⌽matrix | ||
|
|
||
| array3d←2 3 4⍴⍳24 | ||
| desc←'3D array reverse' | ||
| r,←'T3D1'desc Assert array3d≡⌽⌽array3d | ||
| r,←'T3D2'desc Assert (⍴array3d)≡⍴⌽array3d | ||
|
|
||
| array3d←4 5 6⍴⍳120 | ||
| desc←'3D array (4x5x6) reverse' | ||
| r,←'T3D3'desc Assert array3d≡⌽⌽array3d | ||
|
|
||
| ⍝ Bracket-axis reverse ⌽[k] tests | ||
| ⍝ Test reversing along different axes of multi-dimensional arrays | ||
| ⍝ Bracket-axis notation is 1-indexed (independent of ⎕IO per APL docs) | ||
| ⍝ Uses Squad indexing (⌷) in model to reverse along specified axis | ||
| ⍝ requires modelReverseBracket above | ||
| ⍝desc←'Matrix reverse along axes' | ||
| ⍝matrix←3 4⍴⍳12 | ||
| ⍝⎕IO←1 ⍝ Bracket-axis requires 1-based indexing | ||
| ⍝:For axis :In ⍳≢⍴matrix | ||
| ⍝ r,←('TAxisMat',⍕axis)desc Assert (axis modelReverseBracket matrix)≡⌽[axis]matrix | ||
| ⍝:EndFor | ||
| ⍝⍝ Verify first axis is ⊖ | ||
| ⍝r,←'TAxisFirst'desc Assert (⌽[1]matrix)≡⊖matrix | ||
| ⍝ | ||
| ⍝desc←'3D array reverse along axes' | ||
| ⍝array3d←2 3 4⍴⍳24 | ||
| ⍝:For axis :In ⍳≢⍴array3d | ||
| ⍝ r,←('TAxis3D',⍕axis)desc Assert (axis modelReverseBracket array3d)≡⌽[axis]array3d | ||
| ⍝:EndFor | ||
| ⍝⍝ Verify last axis same as monadic | ||
| ⍝r,←'TAxisLast'desc Assert (⌽[(≢⍴array3d)]array3d)≡⌽array3d | ||
| :EndFor | ||
|
|
||
| :For case :In 'char0' 'char1' 'char2' 'char3' | ||
| :If (isDyalogClassic)∧(case≢'char0') | ||
| :Continue | ||
| :EndIf | ||
| data←⍎case | ||
| desc←testDesc | ||
|
|
||
| r,←'TC1'desc quadparams RunVariations,⊂data | ||
|
|
||
| desc←'Char datatype preserved for ',case | ||
| r,←'TC2'desc Assert (⎕DR data)≡⎕DR ⌽data | ||
| :EndFor | ||
|
|
||
| :For case :In 'data_rand_i1' 'data_rand_i2' 'data_rand_i4' | ||
| data←⍎case | ||
| desc←testDesc | ||
| r,←'TRand1'desc quadparams RunVariations,⊂data | ||
| :EndFor | ||
|
|
||
| :If ~isDyalogClassic | ||
| :For case :In 'data_rand_char1' 'data_rand_char2' | ||
| data←⍎case | ||
| desc←testDesc | ||
| r,←'TRandC1'desc quadparams RunVariations,⊂data | ||
| :EndFor | ||
| :EndIf | ||
| ∇ | ||
| :EndNamespace | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.