@@ -343,6 +343,161 @@ using Test
343343 @test r4. dense == true
344344 end
345345
346+ # ===================================================================
347+ # Tests ported from v3 VectorOfArray ragged behavior
348+ # These were the standard ragged tests before v4's AbstractArray
349+ # subtyping changed VectorOfArray to zero-pad. The ragged sublibrary
350+ # preserves the original non-zero-padded behavior.
351+ # ===================================================================
352+
353+ @testset " v3 ragged indexing (ported)" begin
354+ recs = [[1 , 2 , 3 ], [3 , 5 , 6 , 7 ], [8 , 9 , 10 , 11 ]]
355+ r = RaggedVectorOfArray (recs)
356+ rd = RaggedDiffEqArray (recs, 1 : 3 )
357+
358+ # Colon indexing returns actual inner array (no zero-padding)
359+ @test r[:, 1 ] == recs[1 ]
360+ @test rd[:, 1 ] == recs[1 ]
361+
362+ # Subarray indexing into compatible region
363+ @test r[1 , 1 ] == 1
364+ @test r[2 , 1 ] == 2
365+ @test r[1 , 2 ] == 3
366+ @test r[2 , 2 ] == 5
367+
368+ # DiffEqArray column slicing preserves time
369+ rd_sub = rd[:, 1 : 2 ]
370+ @test rd_sub isa RaggedDiffEqArray
371+ @test rd_sub. t == [1 , 2 ]
372+ rd_sub2 = rd[:, 2 : 3 ]
373+ @test rd_sub2 isa RaggedDiffEqArray
374+ @test rd_sub2. t == [2 , 3 ]
375+ end
376+
377+ @testset " v3 heterogeneous views (ported, issue #453)" begin
378+ f = RaggedVectorOfArray ([[1.0 ], [2.0 , 3.0 ]])
379+ # Column access respects actual inner array size
380+ @test length (f[:, 1 ]) == 1
381+ @test length (f[:, 2 ]) == 2
382+ @test f[:, 1 ] == [1.0 ]
383+ @test f[:, 2 ] == [2.0 , 3.0 ]
384+
385+ f2 = RaggedVectorOfArray ([[1.0 , 2.0 ], [3.0 ]])
386+ @test length (f2[:, 1 ]) == 2
387+ @test length (f2[:, 2 ]) == 1
388+ @test f2[:, 1 ] == [1.0 , 2.0 ]
389+ @test f2[:, 2 ] == [3.0 ]
390+ end
391+
392+ @testset " v3 end indexing with ragged arrays (ported)" begin
393+ ragged = RaggedVectorOfArray ([[1.0 , 2.0 ], [3.0 , 4.0 , 5.0 ], [6.0 , 7.0 , 8.0 , 9.0 ]])
394+ # A[j, i] accesses the j-th element of i-th inner array
395+ @test ragged[2 , 1 ] == 2.0
396+ @test ragged[3 , 2 ] == 5.0
397+ @test ragged[4 , 3 ] == 9.0
398+ @test ragged[1 , 1 ] == 1.0
399+ @test ragged[2 , 2 ] == 4.0
400+ @test ragged[3 , 3 ] == 8.0
401+
402+ # Colon returns actual arrays
403+ @test ragged[:, 1 ] == [1.0 , 2.0 ]
404+ @test ragged[:, 2 ] == [3.0 , 4.0 , 5.0 ]
405+ @test ragged[:, 3 ] == [6.0 , 7.0 , 8.0 , 9.0 ]
406+
407+ # Subset selection
408+ r_sub = ragged[:, [2 , 3 ]]
409+ @test r_sub isa RaggedVectorOfArray
410+ @test r_sub[:, 1 ] == [3.0 , 4.0 , 5.0 ]
411+ @test r_sub[:, 2 ] == [6.0 , 7.0 , 8.0 , 9.0 ]
412+
413+ ragged2 = RaggedVectorOfArray ([[1.0 , 2.0 , 3.0 , 4.0 ], [5.0 , 6.0 ], [7.0 , 8.0 , 9.0 ]])
414+ @test ragged2[4 , 1 ] == 4.0
415+ @test ragged2[2 , 2 ] == 6.0
416+ @test ragged2[3 , 3 ] == 9.0
417+ @test ragged2[3 , 1 ] == 3.0
418+ @test ragged2[1 , 2 ] == 5.0
419+ @test ragged2[2 , 3 ] == 8.0
420+ @test ragged2[2 , 1 ] == 2.0
421+ @test ragged2[:, 1 ] == [1.0 , 2.0 , 3.0 , 4.0 ]
422+ @test ragged2[:, 2 ] == [5.0 , 6.0 ]
423+ @test ragged2[:, 3 ] == [7.0 , 8.0 , 9.0 ]
424+ end
425+
426+ @testset " v3 push! making array ragged (ported)" begin
427+ r = RaggedVectorOfArray ([[1 , 2 , 3 ], [4 , 5 , 6 ]])
428+ push! (r, [- 1 , - 2 , - 3 , - 4 ])
429+
430+ # Can still index compatible region
431+ @test r[1 , 1 ] == 1
432+ @test r[2 , 1 ] == 2
433+ @test r[1 , 2 ] == 4
434+ @test r[2 , 2 ] == 5
435+
436+ # Out-of-bounds on shorter arrays throws
437+ @test_throws BoundsError r[4 , 1 ]
438+ @test_throws BoundsError r[4 , 2 ]
439+
440+ # Full column access of the new ragged element
441+ @test r[:, 3 ] == [- 1 , - 2 , - 3 , - 4 ]
442+ @test length (r) == 3
443+ end
444+
445+ @testset " v3 broadcast assignment (ported, issue #454)" begin
446+ u = RaggedVectorOfArray ([[1.0 ], [2.0 , 3.0 ]])
447+ @test length (u[:, 1 ]) == 1
448+ @test length (u[:, 2 ]) == 2
449+
450+ # Broadcast assignment into a column
451+ u[:, 2 ] = [10.0 , 11.0 ]
452+ @test u. u[2 ] == [10.0 , 11.0 ]
453+ end
454+
455+ @testset " v3 DiffEqArray 2D ragged inner arrays (ported)" begin
456+ recs_2d = [rand (2 , 3 ), rand (2 , 4 )]
457+ rd = RaggedDiffEqArray (recs_2d, 1 : 2 )
458+ @test rd[:, 1 ] == recs_2d[1 ]
459+ @test rd[:, 2 ] == recs_2d[2 ]
460+ @test size (rd[:, 1 ]) == (2 , 3 )
461+ @test size (rd[:, 2 ]) == (2 , 4 )
462+
463+ # Subset preserves time
464+ rd_sub = rd[:, [1 , 2 ]]
465+ @test rd_sub isa RaggedDiffEqArray
466+ @test rd_sub. t == [1 , 2 ]
467+ @test rd_sub[:, 1 ] == recs_2d[1 ]
468+ @test rd_sub[:, 2 ] == recs_2d[2 ]
469+ end
470+
471+ @testset " v3 zero and fill on ragged (ported)" begin
472+ r = RaggedVectorOfArray ([[1.0 , 2.0 ], [3.0 , 4.0 , 5.0 ]])
473+
474+ # zero preserves ragged structure
475+ r0 = zero (r)
476+ @test r0[:, 1 ] == [0.0 , 0.0 ]
477+ @test r0[:, 2 ] == [0.0 , 0.0 , 0.0 ]
478+ @test length (r0[:, 1 ]) == 2
479+ @test length (r0[:, 2 ]) == 3
480+
481+ # fill! preserves ragged structure
482+ fill! (r0, 42.0 )
483+ @test r0[:, 1 ] == [42.0 , 42.0 ]
484+ @test r0[:, 2 ] == [42.0 , 42.0 , 42.0 ]
485+
486+ # .= zero works (the exact bug JoshuaLampert reported)
487+ r2 = copy (r)
488+ r2 .= zero (r2)
489+ @test r2[:, 1 ] == [0.0 , 0.0 ]
490+ @test r2[:, 2 ] == [0.0 , 0.0 , 0.0 ]
491+ end
492+
493+ @testset " v3 component timeseries (ported)" begin
494+ r = RaggedVectorOfArray ([[1.0 , 2.0 ], [3.0 , 4.0 , 5.0 ], [6.0 , 7.0 ]])
495+
496+ # A[j, :] returns the j-th component across all inner arrays
497+ @test r[1 , :] == [1.0 , 3.0 , 6.0 ]
498+ @test r[2 , :] == [2.0 , 4.0 , 7.0 ]
499+ end
500+
346501 @testset " Type hierarchy" begin
347502 r = RaggedVectorOfArray ([[1 , 2 ], [3 , 4 , 5 ]])
348503 @test r isa RecursiveArrayTools. AbstractRaggedVectorOfArray
0 commit comments