"Fossies" - the Fresh Open Source Software Archive

Member "PDL-2.080/t/slice.t" (19 May 2022, 15688 Bytes) of package /linux/misc/PDL-2.080.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "slice.t": 2.079_vs_2.080.

    1 use strict;
    2 use warnings;
    3 use Test::More;
    4 use PDL::LiteF;
    5 use PDL::Dbg;
    6 
    7 # PDL::Core::set_debugging(1);
    8 
    9 # Useful for debugging. Removed by DJB whilst cleaning up the
   10 # tests
   11 #
   12 #sub kill_if_debug () {
   13 #    kill INT,$$  if $ENV{UNDER_DEBUGGER};
   14 #}
   15 
   16 sub tapprox ($$) {
   17     my $x = shift;
   18     my $y = shift;
   19     my $maxdiff = abs($x-$y)->max;
   20     return $maxdiff < 0.01;
   21 }
   22 
   23 my ($x, $y, $c, $d, $e, $f);
   24 
   25 $x = (1+(xvals zeroes 4,5) + 10*(yvals zeroes 4,5));
   26 
   27 is($x->at(2,2), 23, "x location (2,2) is 23");
   28 
   29 $y = $x->slice('1:3:2,2:4:2');
   30 
   31 is($y->at(0,0), 22, "(1,2)->(0,0)");
   32 is($y->at(1,0), 24, "(3,2)->(1,0)");
   33 is($y->at(0,1), 42, "(1,4)->(0,1)");
   34 is($y->at(1,1), 44, "(3,4)->(1,1)");
   35 
   36 $y .= 0.5 * ones(2,2);
   37 
   38 is($y->at(1,0), 0.5);
   39 is($y->at(0,1), 0.5);
   40 
   41 is($x->at(1,2), 0.5);
   42 
   43 # Check that nothing happened to other elems
   44 is($x->at(2,2), 23);
   45 
   46 $x = pdl (1,2);
   47 $y = pdl [[1,2],[1,2],[1,2]];
   48 $c = $x->slice(',*3');
   49 
   50 # check dimensions, sum of elements and correct order of els (using tapprox)
   51 
   52 my $sum;
   53 # $c = $x->dummy(1,3);
   54 sumover($c->clump(-1),($sum=null));
   55 ok(tapprox($y,$c));
   56 is($sum->at, 9);
   57 
   58 is(join(',',$c->dims), "2,3");
   59 
   60 $y = pdl [[1,1,1],[2,2,2]];
   61 $c = $x->slice('*3,');
   62 sumover($c->clump(-1),($sum=null));
   63 
   64 ok(tapprox($y,$c));
   65 is($sum->at, 9, 'sum of dummy=3 slice gives right value');
   66 is(join(',',$c->dims), "3,2", 'right dims with dummy slice');
   67 
   68 # test stringify
   69 $x = zeroes(3,3);
   70 my $line = $x->slice(':,(0)');
   71 
   72 $x++;
   73 # $line += 0; # that's how to force an update before interpolation
   74 my $linepr = "$line";
   75 
   76 is($linepr, '[1 1 1]', 'right value after collapsing slice (0)');
   77 
   78 # Test whether error is properly returned:
   79 
   80 $y = zeroes(5,3,3);
   81 $c = $y->slice(":,:,1");
   82 
   83 is(join(',',$c->dims), "5,3,1", 'single-coord slice dims right');
   84 
   85 eval { my $d = $c->slice(":,:,2"); $d->string };
   86 
   87 like($@, qr/out of bounds/, 'check slice bounds error handling') or diag "ERROR WAS: '$@'\n" if $@;
   88 
   89 $x = zeroes 3,3;
   90 
   91 $y = $x->slice("1,1:2");
   92 
   93 $y .= 1;
   94 
   95 $x = xvals zeroes 20,20;
   96 
   97 $y = $x->slice("1:18:2,:");
   98 $c = $y->slice(":,1:18:2");
   99 $d = $c->slice("3:5,:");
  100 $e = $d->slice(":,(0)");
  101 $f = $d->slice(":,(1)");
  102 
  103 $y->string;
  104 $c->string; 
  105 $d->string;
  106 $e->string;
  107 $f->string;
  108 
  109 is("$e", "[7 9 11]");
  110 is("$f", "[7 9 11]");
  111 
  112 # Make sure that vaffining is properly working:
  113 
  114 $x = zeroes 5,6,2;
  115 
  116 $y = (xvals $x) + 0.1 * (yvals $x) + 0.01 * (zvals $x);
  117 
  118 $y = $y->copy;
  119 
  120 $c = $y->slice("2:3");
  121 
  122 $d = $c->copy;
  123 
  124 # $c->dump;
  125 # $d->dump;
  126 
  127 $e = $c-$d;
  128 
  129 is(max(abs($e)), 0);
  130 
  131 my ($im, $im1, $im2, $lut, $in);
  132 
  133 $im = byte [[0,1,255],[0,0,0],[1,1,1]];
  134 ($im1 = null) .= $im->dummy(0,3);
  135 $im2 = $im1->clump(2)->slice(':,0:2')->px;
  136 
  137 ok(!tapprox(ones(byte,9,3),$im2));
  138 
  139 # here we encounter the problem
  140 $im2 = $im1->clump(2)->slice(':,-1:0')->px;
  141 ok(!tapprox(ones(byte,9,3),$im2));
  142 
  143 $x = xvals( zeroes 10,10) + 0.1*yvals(zeroes 10,10);
  144 ok(tapprox($x->mslice('X',[6,7]),
  145 	   pdl([
  146 		[0.6, 1.6, 2.6, 3.6, 4.6, 5.6, 6.6, 7.6, 8.6, 9.6],
  147 		[0.7, 1.7, 2.7, 3.7, 4.7, 5.7, 6.7, 7.7, 8.7, 9.7]
  148 	       ])));
  149 
  150 $lut = pdl [[1,0],[0,1]];
  151 $im = pdl [1];
  152 $in = $lut->transpose->index($im->dummy(0));
  153 
  154 is("$in", "
  155 [
  156  [0 1]
  157 ]
  158 ");
  159 
  160 $in .= pdl 1;
  161 
  162 is("$in", "
  163 [
  164  [1 1]
  165 ]
  166 ");
  167 ok(tapprox($lut,pdl([[1,0],[1,1]])));
  168 
  169 # can we catch indices which are too negative?
  170 $x = PDL->sequence(10);
  171 $y = $x->slice('0:-10');
  172 is("$y", "[0]", "slice 0:-n picks first element");
  173 
  174 $y = $x->slice('0:-14');
  175 eval { $y->string };
  176 like($@, qr/slice ends out of bounds/);
  177 
  178 # Test of dice and dice_axis
  179 $x = sequence(10,4);
  180 is($x->dice([1,2],[0,3])->sum, 66, "dice");
  181 is($x->dice([0,1],'X')->sum, 124, "dice 'X'");
  182 
  183 # Test of dice clump compatability
  184 my $xxx = PDL->new([[[0,0]],[[1,1]],[[2,2]]]);
  185 is_deeply($xxx->where($xxx == 0)->unpdl,[0,0],"dice clump base zero");
  186 my $dice = $xxx->dice("X","X",[1,0]);
  187 is_deeply($dice->clump(-1)->unpdl,[1,1,0,0],"dice clump correct");
  188 is_deeply($dice->where($dice == 0)->unpdl,[0,0],"dice clump where zero");
  189 
  190 # Test of Reorder:
  191 $x = sequence(5,3,2);
  192 my @newDimOrder = (2,1,0);
  193 $y = $x->reorder(@newDimOrder);
  194 
  195 # since doing floating-point arithmetic here, should probably
  196 # use a better test than "eq" here
  197 #
  198 my $got = [$y->dims];
  199 is_deeply($got, [2,3,5], "Test of reorder") or diag explain $got;
  200 
  201 $x = zeroes(3,4);
  202 $y = $x->dummy(-1,2);
  203 is(join(',',$y->dims), '3,4,2');
  204 
  205 $x = pdl(2);
  206 $y = $x->slice('');
  207 ok(tapprox($x, $y), "Empty slice");
  208 
  209 $x = pdl [1,1,1,3,3,4,4,1,1,2];
  210 $y = null;
  211 $c = null;
  212 rle($x,$y,$c);
  213 ok(tapprox($x, rld($y,$c)),"rle with null input");
  214 
  215 undef $y; undef $c;
  216 ($y,$c) = rle($x);
  217 ok(tapprox($x, rld($y,$c)),"rle with return vals");
  218 
  219 my $x2d = $x->cat($x->rotate(1),$x->rotate(2),$x->rotate(3),$x->rotate(4));
  220 rle($x2d,$y=null,$c=null);
  221 ok(tapprox($x2d,rld($y,$c)),"rle 2d with null input");
  222 
  223 undef $y; undef $c;
  224 ($y,$c) = rle($x2d);
  225 ok(tapprox($x2d, rld($y,$c)),"rle 2d with return vals");
  226 
  227 $y = $x->mslice(0.5);
  228 ok(tapprox($y, 1), "mslice 1");
  229 
  230 $y = $x->mslice([0.5,2.11]);
  231 is("$y", "[1 1 1]", "mslice 2");
  232 
  233 $x = zeroes(3,3);
  234 $y = $x->splitdim(3,3);
  235 eval { $y->make_physdims };
  236 like($@, qr/splitdim:nthdim/, "make_physdim: Splitdim");
  237 $y = $x->splitdim(-1,1);
  238 is_deeply [$y->dims], [3,1,3], 'splitdims negative nthdim works' or diag explain [$y->dims];
  239 $y = $x->splitdim(1,1);
  240 is_deeply [$y->dims], [3,1,3], 'splitdims works' or diag explain [$y->dims];
  241 $y = $x->splitdim(1,2);
  242 eval { $y->make_physdims };
  243 like($@, qr/non-divisible/, "splitdims error non-divisible");
  244 
  245 $x = sequence 5,5;
  246 $y = $x->diagonal(0,1);
  247 is("$y", "[0 6 12 18 24]", "diagonal");
  248 
  249 $x = sequence 10;
  250 eval { $y = $x->lags(1,1,1)->make_physdims };
  251 like($@, qr/lags:\s*dim out of range/, "make_physdim: out of range");
  252 
  253 eval { $y = $x->lags(0,-1,1)->make_physdims };
  254 like($@, qr/lags:\s*step must be positive/, "make_physdim: negative step");
  255 
  256 eval { $y = $x->lags(0,1,11)->make_physdims };
  257 like($@, qr/too large/, "make_physdim: too large");
  258 
  259 ##############################
  260 # Tests of some edge cases
  261 $x = sequence(10);
  262 eval { $y = $x->slice("5") };
  263 is $@, '', "simple slice works";
  264 ok(($y->nelem==1 and $y==5), "simple slice works right");
  265 
  266 eval { $y = $x->slice("5:") };
  267 is $@, '', "empty second specifier works";
  268 ok(($y->nelem == 5  and  all($y == pdl(5,6,7,8,9))), "empty second specifier works right");
  269 
  270 eval { $y = $x->slice(":5") };
  271 is $@, '', "empty first specifier works";
  272 ok(($y->nelem == 6  and  all($y == pdl(0,1,2,3,4,5))), "empty first specifier works right");
  273 
  274 ##############################
  275 # White space in slice specifier
  276 eval {  $y = $x->slice(" 4:") };
  277 is $@, '',"slice with whitespace worked - 1";
  278 ok(($y->nelem==6 and all($y==pdl(4,5,6,7,8,9))),"slice with whitespace works right - 1");
  279 eval { $y = $x->slice(" :4") };
  280 is $@, '',"slice with whitespace worked - 2";
  281 ok(($y->nelem==5 and all($y==pdl(0,1,2,3,4))),"slice with whitespace works right - 2");
  282 eval { $y = $x->slice(" 3: 4 ") };
  283 is $@, '',"slice with whitespace worked - 3";
  284 ok(($y->nelem==2 and all($y==pdl(3,4))),"slice with whitespace works right - 3");
  285 
  286 ##############################
  287 # Tests of permissive slicing and dummying
  288 
  289 $x = xvals(5,5)+10*yvals(5,5);
  290 
  291 eval { $y = $x->slice("1,2,(0)")->make_physical };
  292 is $@, '';
  293 is($y->ndims, 2, "slice->make_physical: ndims");
  294 is(pdl($y->dims)->sumover, 2, "slice->make_physical: dims");
  295 
  296 eval { $c = $x->slice("1,2,(1)")->make_physical };
  297 like($@, qr/too many dims/i, "slice->make_physical: too many dims");
  298 
  299 # Hmmm, think these could be split up but not sure exactly what is being
  300 # tested so leave as is (ish)
  301 #
  302 eval { $d = $x->slice("0:1,2:3,0")->make_physical };
  303 is $@, '';
  304 is $d->ndims, 3;
  305 is +(pdl($d->dims) == pdl(2,2,1))->sumover, 3;
  306 is $d->ndims, 3;
  307 is +(pdl($d->dims) == pdl(2,2,1))->sumover, 3;
  308 
  309 eval { $d = $x->slice("0:1,2:3,0")->xchg(0,2) };
  310 is $@, '', "slice->xchg";
  311 
  312 is $d->ndims, 3;
  313 is +(pdl($d->dims) == pdl(1,2,2))->sumover, 3;
  314 
  315 eval { $e = $x->dummy(6,2) };
  316 is $@, '', "dummy";
  317 
  318 is $e->ndims, 7;
  319 is +(pdl($e->dims) == pdl(5,5,1,1,1,1,2))->sumover, 7;
  320 
  321 ##############################
  322 # Tests of indexND (Nowadays this is just another call to range)
  323 
  324 my ($source, $index, $dest, $z);
  325 
  326 # Basic indexND operation
  327 $source = 10*xvals(10,10) + yvals(10,10);
  328 $index  = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
  329 eval { $x = $source->indexND( $index ) };
  330 is $@, '';
  331 ok(eval { zcheck($x != pdl([23,45],[67,89])) }, "eval of zcheck 1");
  332 
  333 # Broadcast indexND operation
  334 $source = 100*xvals(10,10,2)+10*yvals(10,10,2)+zvals(10,10,2);
  335 $index  = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
  336 eval { $x = $source->indexND($index) };
  337 is $@, '';
  338 ok(eval { zcheck($x != pdl([[230,450],[670,890]],[[231,451],[671,891]])) }, "eval of zcheck 2");
  339 
  340 
  341 ##############################
  342 # Tests of range operator
  343 
  344 # Basic range operation
  345 $source = 10*xvals(10,10) + yvals(10,10);
  346 $index = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
  347 
  348 eval { $dest = $source->range($index); };
  349 is $@, '';
  350 ok(eval { zcheck($dest != pdl([23,45],[67,89])); }, "eval of zcheck 3");
  351 
  352 # Make a 3x3 range at each index
  353 eval { $dest = $source->range($index,3); };
  354 is $@, '';
  355 
  356 # Check that the range has the correct size
  357 is($dest->ndims, 4, "ndims after range");
  358 ok(zcheck(pdl($dest->dims) != pdl(2,2,3,3)), "zcheck after range");
  359 
  360 #### Check boundary conditions
  361 eval { $z = $dest->copy; }; # Should throw range-out-of-bounds error
  362 ok($@); # should check actual error message here
  363 
  364 ## Truncation
  365 eval { $z = $source->range($index,3,"t")->copy; };
  366 is $@, '';  # Should NOT throw range-out-of-bounds error.
  367 ok(zcheck($z->slice("(1),(1)") != pdl([[89,99,0],[0,0,0],[0,0,0]])));
  368 
  369 ## Truncation on one axis, periodic on another; string syntax
  370 eval { $z = $source->range($index,3,"tp") };
  371 ok(zcheck($z->slice("(1),(1)") != pdl([[89,99,0],[80,90,0],[81,91,0]])));
  372 
  373 ## Periodic on first axis, extension on another; list syntax
  374 eval { $z = $source->range($index,3,["e","p"]); };
  375 ok(zcheck($z->slice("(1),(1)") != pdl([[89,99,99],[80,90,90],[81,91,91]])));
  376 
  377 our $mt;
  378 eval { $mt = which(pdl(0)) };
  379 ok("$mt" =~ m/^Empty/);
  380 
  381 our $dex = pdl(5,4,3);
  382 $z = $dex->range(zeroes(0));  # scalar Empties are autopromoted like scalar nonempties
  383 ok("$z" eq 'Empty[0]', "scalar Empty[0] indices handled correctly by range");
  384 
  385 $z = $dex->range(zeroes(1,0)); # 1-vector Empties are handled right.
  386 ok("$z" eq 'Empty[0]', "1-vector Empty[1,0] indices handled correctly by range");
  387 
  388 $z = $mt->range($dex,undef,'e');
  389 ok(all($z==0),"empty source arrays handled correctly by range");
  390 
  391 $z = $mt->range($mt);
  392 ok("$z" eq 'Empty[0]', "ranging an empty array with an empty index gives Empty[0]");
  393 
  394 $x = pdl(5,5,5,5);
  395 $z = $x->range($mt);
  396 ok("$z" eq 'Empty[0]');
  397 
  398 $z .= 2; # should *not* segfault!
  399 ok all($x==5), 'empty range .= no mutate';   # should *not* change $x!
  400 
  401 ### Check slicing of a null PDL
  402 $x = PDL->null;
  403 eval { $y = $x->slice("") };
  404 like $@, qr/is null/, 'null->slice exception';
  405 
  406 for my $start (0, 4, -4, 20, -20) {
  407 	for my $stop (0, 4, -4, 20, -20) {
  408 		# Generate a simple data ndarray and a bad slice of that ndarray
  409 		my $data = sequence(10);
  410 		my $slice = $data->slice("$start:$stop");
  411 
  412 		pass('Slice operation for properly formed slice does not croak');
  413 
  414 		# Calculate the expected dimension size:
  415 		my $expected_dim_size;
  416 		my $real_start = $start;
  417 		$real_start += 10 if $start < 0;
  418 		my $real_stop = $stop;
  419 		$real_stop += 10 if $stop < 0;
  420 		$expected_dim_size = abs($real_stop - $real_start) + 1
  421 			if 0 <= $real_stop and $real_stop < 10
  422 				and 0 <= $real_start and $real_start < 10;
  423 
  424 		my $expected_outcome_description
  425 			= defined $expected_dim_size ? 'is fine' : 'croaks';
  426 
  427 		my $dim1;
  428 		# Should croak when we ask about the dimension:
  429 		eval { $dim1 = $slice->dim(0) };
  430 		is($dim1, $expected_dim_size, "Requesting dim(0) on slice($start:$stop) $expected_outcome_description");
  431 
  432 		# Should *STILL* croak when we ask about the dimension:
  433 		eval { $dim1 = $slice->dim(0) };
  434 		is($dim1, $expected_dim_size, "Requesting dim(0) a second time on slice($start:$stop) $expected_outcome_description");
  435 
  436 		# Calculate the expected value
  437 		my $expected_value;
  438 		$expected_value = $data->at($real_start) if defined $expected_dim_size;
  439 
  440 		# Should croak when we ask about data
  441 		my $value;
  442 		eval { $value = $slice->at(0) };
  443 		is($value, $expected_value, "Requesting first element on slice($start:$stop) $expected_outcome_description");
  444 	}
  445 }
  446 
  447 {
  448 # Test vaffine optimisation
  449 my $x = zeroes(100,100);
  450 my $y = $x->slice('10:90,10:90');
  451 $y++;
  452 ok( (not $y->allocated) ) ;
  453 }
  454 
  455 my $indices = pdl([]);
  456 $got = eval { my $s = pdl([1,2])->slice(pdl(1)); $s->string; $s->nelem };
  457 is $@, '', 'slice 2-elt ndarray with one-length ndarray';
  458 is $got, 1, 'right dim from 2-elt with one index';
  459 $got = eval { my $s = pdl([1,2])->slice($indices); $s->string; $s->nelem };
  460 is $@, '', 'slice 2-elt ndarray with zero-length ndarray';
  461 is $got, 0, 'zero dim from 2-elt';
  462 $got = eval { my $s = pdl([1])->slice($indices); $s->string; $s->nelem };
  463 is $@, '', 'slice 1-elt ndarray with zero-length ndarray';
  464 is $got, 0, 'zero dim from 1-elt';
  465 
  466 my $pa = sequence 10;
  467 $c = PDL->pdl(7,6);
  468 $got = $pa->slice([$c->slice(1),0,0]);
  469 is "".$got, 6, 'slice did "at" automatically' or diag "got:$got";
  470 
  471 my $cmp = pdl(2,4,6);
  472 my $rg = pdl(2,7,2);
  473 $got = $pa->slice([$rg->slice(0),$rg->slice(1),$rg->slice(2)]);
  474 ok all($got == $cmp), 'slice did "at"' or diag "got:$got";
  475 
  476 $pa = zeroes(7, 7); $pa->set(3, 4, 1);
  477 $indices = $pa->which->dummy(0,$pa->getndims)->make_physical;
  478 my $s = $indices->index(0);
  479 $s %= 7;
  480 is $indices.'', <<EOF, 'mutate indexed slice affects only right column';
  481 \n[\n [ 3 31]\n]
  482 EOF
  483 
  484 ## rlevec(), rldvec(): 2d ONLY
  485 my $p = pdl([[1,2],[1,2],[1,2],[3,4],[3,4],[5,6]]);
  486 my ($pf,$pv)  = rlevec($p);
  487 my $pf_expect = pdl(long,[3,2,1,0,0,0]);
  488 my $pv_expect = pdl([[1,2],[3,4],[5,6],[0,0],[0,0],[0,0]]);
  489 ok all(approx($pf, $pf_expect)), "rlevec():counts";
  490 ok all(approx($pv, $pv_expect)), "rlevec():elts";
  491 
  492 my $pd = rldvec($pf,$pv);
  493 ok all(approx($pd, $p)), "rldvec()";
  494 
  495 my $pk = enumvec($p);
  496 ok all(approx($pk, pdl(long,[0,1,2,0,1,0]))), "enumvec()";
  497 
  498 $pk = enumvecg($p);
  499 ok all(approx($pk, pdl(long,[0,0,0,1,1,2]))), "enumvecg()";
  500 
  501 ## 6..7: test rleND(): 2d
  502 ($pf,$pv) = rleND($p);
  503 ok all(approx($pf, $pf_expect)), "rleND():2d:counts";
  504 ok all(approx($pv, $pv_expect)), "rleND():2d:elts";
  505 
  506 ## 8..8: test rldND(): 2d
  507 $pd = rldND($pf,$pv);
  508 ok all(approx($pd, $p)), "rldND():2d";
  509 
  510 ## rleND, rldND: Nd
  511 my $pnd1 = (1  *(sequence(long, 2,3  )+1))->slice(",,*3");
  512 my $pnd2 = (10 *(sequence(long, 2,3  )+1))->slice(",,*2");
  513 my $pnd3 = (100*(sequence(long, 2,3,2)+1));
  514 my $p_nd = $pnd1->mv(-1,0)->append($pnd2->mv(-1,0))->append($pnd3->mv(-1,0))->mv(0,-1);
  515 
  516 my $pf_expect_nd = pdl(long,[3,2,1,1,0,0,0]);
  517 my $pv_expect_nd = zeroes($p_nd->type, $p_nd->dims);
  518 (my $tmp=$pv_expect_nd->slice(",,0:3")) .= $p_nd->dice_axis(-1,[0,3,5,6]);
  519 
  520 ## 9..10: test rleND(): Nd
  521 my ($pf_nd,$pv_nd) = rleND($p_nd);
  522 ok all(approx($pf_nd, $pf_expect_nd)), "rleND():Nd:counts";
  523 ok all(approx($pv_nd, $pv_expect_nd)), "rleND():Nd:elts";
  524 
  525 ## 11..11: test rldND(): Nd
  526 my $pd_nd = rldND($pf_nd,$pv_nd);
  527 ok all(approx($pd_nd, $p_nd)), "rldND():Nd";
  528 
  529 ## 12..12: test enumvec(): nd
  530 my $v_nd = $p_nd->clump(2);
  531 my $k_nd = $v_nd->enumvec();
  532 ok all(approx($k_nd, pdl(long,[0,1,2,0,1,0,0]))), "enumvec():Nd";
  533 
  534 ## 13..17: test rldseq(), rleseq()
  535 my $lens = pdl(long,[qw(3 0 1 4 2)]);
  536 my $offs = (($lens->xvals+1)*100)->short;
  537 my $seqs = zeroes(short, 0);
  538 $seqs  = $seqs->append(sequence(short,$_)) foreach ($lens->list);
  539 $seqs += $lens->rld($offs);
  540 
  541 my $seqs_got = $lens->rldseq($offs);
  542 is $seqs_got->type, $seqs->type, "rldseq():type";
  543 ok all(approx($seqs_got, $seqs)), "rldseq():data";
  544 
  545 my ($len_got,$off_got) = $seqs->rleseq();
  546 is $off_got->type, $seqs->type, "rleseq():type";
  547 ok all(approx($len_got->where($len_got), $lens->where($lens))), "rleseq():lens";
  548 ok all(approx($off_got->where($len_got), $offs->where($lens))), "rleseq():offs";
  549 
  550 done_testing;