1NiceSlice(3)          User Contributed Perl Documentation         NiceSlice(3)
2
3
4

NAME

6       PDL::NiceSlice - toward a nicer slicing syntax for PDL
7

SYNOPSYS

9         use PDL::NiceSlice;
10
11         $a(1:4) .= 2;             # concise syntax for ranges
12         print $b((0),1:$end);     # use variables in the slice expression
13         $a->xchg(0,1)->(($pos-1)) .= 0; # default method syntax
14
15         $idx = long 1, 7, 3, 0;   # a piddle of indices
16         $a(-3:2:2,$idx) += 3;     # mix explicit indexing and ranges
17         $a->clump(1,2)->(0:30);   # 'default method' syntax
18         $a(myfunc(0,$var),1:4)++; # when using functions in slice expressions
19                                   # use parentheses around args!
20
21         $b = $a(*3);              # Add dummy dimension of order 3
22
23         # modifiers are specified in a ;-separated trailing block
24         $a($a!=3;?)++;            # short for $a->where($a!=3)++
25         $a(0:1114;_) .= 0;        # short for $a->flat->(0:1114)
26         $b = $a(0:-1:3;|);        # short for $a(0:-1:3)->sever
27         $n = sequence 3,1,4,1;
28         $b = $n(;-);              # drop all dimensions of size 1 (AKA squeeze)
29         $b = $n(0,0;-|);          # squeeze *and* sever
30         $c = $a(0,3,0;-);         # more compact way of saying $a((0),(3),(0))
31
32         # Use with perldl versions < v1.31 (or include these lines in .perldlrc)
33         perldl> use PDL::NiceSlice;
34         # next one is required, see below
35         perldl> $PERLDL::PREPROCESS = \&PDL::NiceSlice::perldlpp;
36         perldl> $a(4:5) .= xvals(2);
37

DESCRIPTION

39       Slicing is a basic, extremely common operation, and PDL's slice method
40       would be cumbersome to use in many cases.  "PDL::NiceSlice" rectifies
41       that by incorporating new slicing syntax directly into the language via
42       a perl source filter (see the perlfilter man page).  NiceSlice adds no
43       new functionality, only convenient syntax.
44
45       NiceSlice is loaded automatically in the perldl shell, but (to avoid
46       conflicts with other modules) must be loaded automatically in
47       standalone perl/PDL scripts (see below).  If you prefer not to use a
48       prefilter on your standalone scripts, you can use the slice method in
49       those scripts, rather than the more compact NiceSlice constructs.
50

Use in scripts and "perldl" shell

52       The new slicing syntax can be switched on and off in scripts and perl
53       modules by using or unloading "PDL::NiceSlice".
54
55       Note: this will not work in the perldl shell < v1.31.  Because the
56       perldl shell uses evals, and NiceSlice is a perl source filter, you
57       have to set a special variable to use it within perldl. See below how
58       to enable the new slicing syntax within older perldl.
59
60       But now back to scripts and modules.  Everything after "use
61       PDL::NiceSlice" will be translated and you can use the new slicing
62       syntax. Source filtering will continue until the end of the file is
63       encountered.  You can stop sourcefiltering before the end of the file
64       by issuing a "no PDL::NiceSlice" statement.
65
66       Here is an example:
67
68         use PDL::NiceSlice;
69
70         # this code will be translated
71         # and you can use the new slicing syntax
72
73         no PDL::NiceSlice;
74
75         # this code won't
76         # and the new slicing syntax will raise errors!
77
78       See also Filter::Simple and example in this distribution for further
79       examples.
80
81       NOTE: Unlike "normal" modules you need to include a "use
82       PDL::NiceSlice" call in each and every file that contains code that
83       uses the new slicing syntax. Imagine the following situation: a file
84       test0.pl
85
86          # start test0.pl
87          use PDL;
88          use PDL::NiceSlice;
89
90          $a = sequence 10;
91          print $a(0:4),"\n";
92
93          require 'test1.pl';
94          # end test0.pl
95
96       that "require"s a second file test1.pl
97
98          # begin test1.pl
99          $aa = sequence 11;
100          print $aa(0:7),"\n";
101          1;
102          # end test1.pl
103
104       Following conventional perl wisdom everything should be alright since
105       we "use"d "PDL" and "PDL::NiceSlice" already from within test0.pl and
106       by the time test1.pl is "require"d things should be defined and
107       imported, etc. A quick test run will, however, produce something like
108       the following:
109
110         perl test0.pl
111        [0 1 2 3 4]
112        syntax error at test1.pl line 3, near "0:"
113        Compilation failed in require at test0.pl line 7.
114
115       This can be fixed by adding the line
116
117         use PDL::NiceSlice;
118
119       "before" the code in test1.pl that uses the new slicing syntax (to play
120       safe just include the line near the top of the file), e.g.
121
122          # begin corrected test1.pl
123          use PDL::NiceSlice;
124          $aa = sequence 11;
125          print $aa(0:7),"\n";
126          1;
127          # end test1.pl
128
129       Now things proceed more smoothly
130
131         perl test0.pl
132        [0 1 2 3 4]
133        [0 1 2 3 4 5 6 7]
134
135       Note that we don't need to issue "use PDL" again.  "PDL::NiceSlice" is
136       a somewhat funny module in that respect. It is a consequence of the way
137       source filtering works in Perl (see also the IMPLEMENTATION section
138       below).
139
140   Usage with perldl
141       NOTE: This information only applies to versions of perldl earlier than
142       1.31 . From v1.31 onwards niceslicing is enabled by default, i.e.  it
143       should just work. See perldl for details.
144
145       For pre v1.31 "perldl"s you need to add the following two lines to your
146       .perldlrc file:
147
148          use PDL::NiceSlice;
149          $PERLDL::PREPROCESS = \&PDL::NiceSlice::perldlpp;
150
151       A more complete tool box of commands for experimentation is in the file
152       local.perldlrc in the "PDL::NiceSlice" source directory. Just include
153       the code in that file in your usual ~/.perldlrc and you can switch
154       source filtering with PDL::NiceSlice on and off by typing "trans" and
155       "notrans", respectively. To see what and how your commands are
156       translated switch reporting on:
157
158         perldl> report 1;
159
160       Similarly, switch reporting off as needed
161
162         perldl> report 0;
163
164       Note that these commands will only work if you included the contents of
165       local.perldlrc in your perldl startup file.  In "perldl" v1.31 and
166       later these commands are available by default.
167
168   evals and "PDL::NiceSlice"
169       Due to "PDL::NiceSlice" being a source filter it won't work in the
170       usual way within evals. The following will not do what you want:
171
172         $a = sequence 10;
173         eval << 'EOE';
174
175         use PDL::NiceSlice;
176         $b = $a(0:5);
177
178         EOE
179         print $b;
180
181       Instead say:
182
183         use PDL::NiceSlice;
184         $a = sequence 10;
185         eval << 'EOE';
186
187         $b = $a(0:5);
188
189         EOE
190         print $b;
191
192       Source filters must be executed at compile time to be effective. And
193       "PDL::NiceFilter" is just a source filter (although it is not
194       necessarily obvious for the casual user).
195

The new slicing syntax

197       Using "PDL::NiceSlice" slicing piddles becomes so much easier since,
198       first of all, you don't need to make explicit method calls. No
199
200         $pdl->slice(....);
201
202       calls, etc. Instead, "PDL::NiceSlice" introduces two ways in which to
203       slice piddles without too much typing:
204
205       · using parentheses directly following a scalar variable name, for
206         example
207
208            $c = $b(0:-3:4,(0));
209
210       · using the so called default method invocation in which the piddle
211         object is treated as if it were a reference to a subroutine (see also
212         perlref). Take this example that slices a piddle that is part of a
213         perl list @b:
214
215           $c = $b[0]->(0:-3:4,(0));
216
217       The format of the argument list is the same for both types of
218       invocation and will be explained in more detail below.
219
220   Parentheses following a scalar variable name
221       An arglist in parentheses following directly after a scalar variable
222       name that is not preceded by "&" will be resolved as a slicing command,
223       e.g.
224
225         $a(1:4) .= 2;         # only use this syntax on piddles
226         $sum += $a(,(1));
227
228       However, if the variable name is immediately preceded by a "&", for
229       example
230
231         &$a(4,5);
232
233       it will not be interpreted as a slicing expression. Rather, to avoid
234       interfering with the current subref syntax, it will be treated as an
235       invocation of the code reference $a with argumentlist "(4,5)".
236
237       The $a(ARGS) syntax collides in a minor way with the perl syntax.  In
238       particular, ``foreach $avar(LIST)'' appears like a PDL slicing call.
239       NiceSlice avoids translating the ``for $avar(LIST)'' and ``foreach
240       $avar(LIST)'' constructs for this reason.  Since you can't use just any
241       old lvalue expression in the 'foreach' 'for' constructs -- only a real
242       perl scalar will do -- there's no functionality lost.  If later
243       versions of perl accept ``foreach <lvalue-expr> (LIST)'', then you can
244       use the code ref syntax, below, to get what you want.
245
246   The default method syntax
247       The second syntax that will be recognized is what I called the default
248       method syntax. It is the method arrow "->" directly followed by an open
249       parenthesis, e.g.
250
251         $a->xchg(0,1)->(($pos)) .= 0;
252
253       Note that this conflicts with the use of normal code references, since
254       you can write in plain Perl
255
256         $sub = sub { print join ',', @_ };
257         $sub->(1,'a');
258
259       NOTE: Once "use PDL::NiceSlice" is in effect (you can always switch it
260       off with a line "no PDL::NiceSlice;" anywhere in the script) the source
261       filter will incorrectly replace the above call to $sub with an
262       invocation of the slicing method.  This is one of the pitfalls of using
263       a source filter that doesn't know anything about the runtime type of a
264       variable (cf. the Implementation section).
265
266       This shouldn't be a major problem in practice; a simple workaround is
267       to use the "&"-way of calling subrefs, e.g.:
268
269         $sub = sub { print join ',', @_ };
270         &$sub(1,'a');
271
272   When to use which syntax?
273       Why are there two different ways to invoke slicing?  The first syntax
274       "$a(args)" doesn't work with chained method calls. E.g.
275
276         $a->xchg(0,1)(0);
277
278       won't work. It can only be used directly following a valid perl
279       variable name. Instead, use the default method syntax in such cases:
280
281         $a->xchg(0,1)->(0);
282
283       Similarly, if you have a list of piddles @pdls:
284
285         $b = $pdls[5]->(0:-1);
286
287   The argument list
288       The argument list is a comma separated list. Each argument specifies
289       how the corresponding dimension in the piddle is sliced. In contrast to
290       usage of the slice method the arguments should not be quoted. Rather
291       freely mix literals (1,3,etc), perl variables and function invocations,
292       e.g.
293
294         $a($pos-1:$end,myfunc(1,3)) .= 5;
295
296       There can even be other slicing commands in the arglist:
297
298         $a(0:-1:$pdl($step)) *= 2;
299
300       NOTE: If you use function calls in the arglist make sure that you use
301       parentheses around their argument lists. Otherwise the source filter
302       will get confused since it splits the argument list on commas that are
303       not protected by parentheses. Take the following example:
304
305         sub myfunc { return 5*$_[0]+$_[1] }
306         $a = sequence 10;
307         $sl = $a(0:myfunc 1, 2);
308         print $sl;
309        PDL barfed: Error in slice:Too many dims in slice
310        Caught at file /usr/local/bin/perldl, line 232, pkg main
311
312       The simple fix is
313
314         $sl = $a(0:myfunc(1, 2));
315         print $sl;
316        [0 1 2 3 4 5 6 7]
317
318       Note that using prototypes in the definition of myfunc does not help.
319       At this stage the source filter is simply not intelligent enough to
320       make use of this information. So beware of this subtlety.
321
322       Another pitfall to be aware of: currently, you can't use the
323       conditional operator in slice expressions (i.e., "?:", since the parser
324       confuses them with ranges). For example, the following will cause an
325       error:
326
327         $a = sequence 10;
328         $b = rand > 0.5 ? 0 : 1; # this one is ok
329         print $a($b ? 1 : 2);    # error !
330        syntax error at (eval 59) line 3, near "1,
331
332       For the moment, just try to stay clear of the conditional operator in
333       slice expressions (or provide us with a patch to the parser to resolve
334       this issue ;).
335
336   Modifiers
337       Following a suggestion originally put forward by Karl Glazebrook the
338       latest versions of "PDL::NiceSlice" implement modifiers in slice
339       expressions. Modifiers are convenient shorthands for common variations
340       on PDL slicing. The general syntax is
341
342           $pdl(<slice>;<modifier>)
343
344       Four modifiers are currently implemented:
345
346       ·   "_" : flatten the piddle before applying the slice expression. Here
347           is an example
348
349              $b = sequence 3, 3;
350              print $b(0:-2;_); # same as $b->flat->(0:-2)
351            [0 1 2 3 4 5 6 7]
352
353           which is quite different from the same slice expression without the
354           modifier
355
356              print $b(0:-2);
357            [
358             [0 1]
359             [3 4]
360             [6 7]
361            ]
362
363       ·   "|" : sever the link to the piddle, e.g.
364
365              $a = sequence 10;
366              $b = $a(0:2;|)++;  # same as $a(0:2)->sever++
367              print $b;
368            [1 2 3]
369              print $a; # check if $a has been modified
370            [0 1 2 3 4 5 6 7 8 9]
371
372       ·   "?" : short hand to indicate that this is really a where expression
373
374           As expressions like
375
376             $a->where($a>5)
377
378           are used very often you can write that shorter as
379
380             $a($a>5;?)
381
382           With the "?"-modifier the expression preceding the modifier is not
383           really a slice expression (e.g. ranges are not allowed) but rather
384           an expression as required by the where method.  For example, the
385           following code will raise an error:
386
387             $a = sequence 10;
388             print $a(0:3;?);
389            syntax error at (eval 70) line 3, near "0:"
390
391           That's about all there is to know about this one.
392
393       ·   "-" : squeeze out any singleton dimensions. In less technical
394           terms: reduce the number of dimensions (potentially) by deleting
395           all dims of size 1. It is equivalent to doing a reshape(-1).  That
396           can be very handy if you want to simplify the results of slicing
397           operations:
398
399             $a = ones 3, 4, 5;
400             $b = $a(1,0;-); # easier to type than $a((1),(0))
401             print $b->info;
402            PDL: Double D [5]
403
404           It also provides a unique opportunity to have smileys in your code!
405           Yes, PDL gives new meaning to smileys.
406
407   Combining modifiers
408       Several modifiers can be used in the same expression, e.g.
409
410         $c = $a(0;-|); # squeeze and sever
411
412       Other combinations are just as useful, e.g. ";_|" to flatten and sever.
413       The sequence in which modifiers are specified is not important.
414
415       A notable exception is the "where" modifier ("?") which must not be
416       combined with other flags (let me know if you see a good reason to
417       relax this rule).
418
419       Repeating any modifier will raise an error:
420
421         $c = $a(-1:1;|-|); # will cause error
422        NiceSlice error: modifier | used twice or more
423
424       Modifiers are still a new and experimental feature of "PDL::NiceSlice".
425       I am not sure how many of you are actively using them. Please do so and
426       experiment with the syntax. I think modifiers are very useful and make
427       life a lot easier.  Feedback is welcome as usual. The modifier syntax
428       will likely be further tuned in the future but we will attempt to
429       ensure backwards compatibility whenever possible.
430
431   Argument formats
432       In slice expressions you can use ranges and secondly, piddles as 1D
433       index lists (although compare the description of the "?"-modifier above
434       for an exception).
435
436       · ranges
437
438         You can access ranges using the usual ":" separated format:
439
440           $a($start:$stop:$step) *= 4;
441
442         Note that you can omit the trailing step which then defaults to 1.
443         Double colons ("::") are not allowed to avoid clashes with Perl's
444         namespace syntax. So if you want to use steps different from the
445         default you have to also at least specify the stop position.
446         Examples:
447
448           $a(::2);   # this won't work (in the way you probably intended)
449           $a(:-1:2); # this will select every 2nd element in the 1st dim
450
451         Just as with slice negative indices count from the end of the
452         dimension backwards with "-1" being the last element. If the start
453         index is larger than the stop index the resulting piddle will have
454         the elements in reverse order between these limits:
455
456           print $a(-2:0:2);
457          [8 6 4 2 0]
458
459         A single index just selects the given index in the slice
460
461           print $a(5);
462          [5]
463
464         Note, however, that the corresponding dimension is not removed from
465         the resulting piddle but rather reduced to size 1:
466
467           print $a(5)->info
468          PDL: Double D [1]
469
470         If you want to get completely rid of that dimension enclose the index
471         in parentheses (again similar to the slice syntax):
472
473           print $a((5));
474          5
475
476         In this particular example a 0D piddle results. Note that this syntax
477         is only allowed with a single index. All these will be errors:
478
479           print $a((0,4));  # will work but not in the intended way
480           print $a((0:4));  # compile time error
481
482         An empty argument selects the whole dimension, in this example all of
483         the first dimension:
484
485           print $a(,(0));
486
487         Alternative ways to select a whole dimension are
488
489           $a = sequence 5, 5;
490           print $a(:,(0));
491           print $a(0:-1,(0));
492           print $a(:-1,(0));
493           print $a(0:,(0));
494
495         Arguments for trailing dimensions can be omitted. In that case these
496         dimensions will be fully kept in the sliced piddle:
497
498           $a = random 3,4,5;
499           print $a->info;
500          PDL: Double D [3,4,5]
501           print $a((0))->info;
502          PDL: Double D [4,5]
503           print $a((0),:,:)->info;  # a more explicit way
504          PDL: Double D [4,5]
505           print $a((0),,)->info;    # similar
506          PDL: Double D [4,5]
507
508       · dummy dimensions
509
510         As in slice, you can insert a dummy dimension by preceding a single
511         index argument with '*'.  A lone '*' inserts a dummy dimension of
512         order 1; a '*' followed by a number inserts a dummy dimension of that
513         order.
514
515       · piddle index lists
516
517         The second way to select indices from a dimension is via 1D piddles
518         of indices. A simple example:
519
520           $a = random 10;
521           $idx = long 3,4,7,0;
522           $b = $a($idx);
523
524         This way of selecting indices was previously only possible using dice
525         ("PDL::NiceSlice" attempts to unify the "slice" and "dice"
526         interfaces). Note that the indexing piddles must be 1D or 0D. Higher
527         dimensional piddles as indices will raise an error:
528
529           $a = sequence 5, 5;
530           $idx2 = ones 2,2;
531           $sum = $a($idx2)->sum;
532          piddle must be <= 1D at /home/XXXX/.perldlrc line 93
533
534         Note that using index piddles is not as efficient as using ranges.
535         If you can represent the indices you want to select using a range use
536         that rather than an equivalent index piddle. In particular, memory
537         requirements are increased with index piddles (and execution time may
538         be longer). That said, if an index piddle is the way to go use it!
539
540       As you might have expected ranges and index piddles can be freely mixed
541       in slicing expressions:
542
543         $a = random 5, 5;
544         $b = $a(-1:2,pdl(3,0,1));
545
546   piddles as indices in ranges
547       You can use piddles to specify indices in ranges. No need to turn them
548       into proper perl scalars with the new slicing syntax.  However, make
549       sure they contain not more than one element! Otherwise a runtime error
550       will be triggered. First a couple of examples that illustrate proper
551       usage:
552
553         $a = sequence 5, 5;
554         $rg = pdl(1,-1,3);
555         print $a($rg(0):$rg(1):$rg(2),2);
556        [
557         [11 14]
558        ]
559         print $a($rg+1,:$rg(0));
560        [
561         [2 0 4]
562         [7 5 9]
563        ]
564
565       The next one raises an error
566
567         print $a($rg+1,:$rg(0:1));
568        multielement piddle where only one allowed at XXX/Core.pm line 1170.
569
570       The problem is caused by using the 2-element piddle "$rg(0:1)" as the
571       stop index in the second argument ":$rg(0:1)" that is interpreted as a
572       range by "PDL::NiceSlice". You can use multielement piddles as index
573       piddles as described above but not in ranges. And "PDL::NiceSlice"
574       treats any expression with unprotected ":"'s as a range.  Unprotected
575       means as usual "not occurring between matched parentheses".
576

IMPLEMENTATION

578       "PDL::NiceSlice" exploits the ability of Perl to use source filtering
579       (see also perlfilter). A source filter basically filters (or rewrites)
580       your perl code before it is seen by the compiler. "PDL::NiceSlice"
581       searches through your Perl source code and when it finds the new
582       slicing syntax it rewrites the argument list appropriately and splices
583       a call to the "nslice" method using the modified arg list into your
584       perl code. You can see how this works in the perldl shell by switching
585       on reporting (see above how to do that).
586
587       The "nslice" method is an extended version of mslice that knows how to
588       deal with index piddles (and therefore combines slicing and dicing).
589       Full documentation of "nslice" will be in the next PDL release.
590

BUGS

592   Conditional operator
593       The conditional operator can't be used in slice expressions (see
594       above).
595
596   The "DATA" file handle
597       Note: To avoid clobbering the "DATA" filehandle "PDL::NiceSlice"
598       switches itself off when encountering the "__END__" or "__DATA__"
599       tokens.  This should not be a problem for you unless you use
600       "SelfLoader" to load PDL code including the new slicing from that
601       section. It is even desirable when working with Inline::Pdlpp, see
602       below.
603
604   Possible interaction with Inline::Pdlpp
605       There is currently an undesired interaction between "PDL::NiceSlice"
606       and the new Inline::Pdlpp module (currently only in PDL CVS). Since PP
607       code generally contains expressions of the type "$var()" (to access
608       piddles, etc) "PDL::NiceSlice" recognizes those incorrectly as slice
609       expressions and does its substitutions. This is not a problem if you
610       use the "DATA" section for your Pdlpp code -- the recommended place for
611       Inline code anyway. In that case "PDL::NiceSlice" will have switched
612       itself off before encountering any Pdlpp code (see above):
613
614           # use with Inline modules
615         use PDL;
616         use PDL::NiceSlice;
617         use Inline Pdlpp;
618
619         $a = sequence(10);
620         print $a(0:5);
621
622         __END__
623
624         __Pdlpp__
625
626         ... inline stuff
627
628       Otherwise switch "PDL::NiceSlice" explicitly off around the
629       Inline::Pdlpp code:
630
631         use PDL::NiceSlice;
632
633         $a = sequence 10;
634         $a(0:3)++;
635         $a->inc;
636
637         no PDL::NiceSlice; # switch off before Pdlpp code
638         use Inline Pdlpp => "Pdlpp source code";
639
640       The cleaner solution is to always stick with the "DATA" way of
641       including your "Inline" code as in the first example. That way you keep
642       your nice Perl code at the top and all the ugly Pdlpp stuff etc at the
643       bottom.
644
645   Bug reports
646       Feedback and bug reports are welcome. Please include an example that
647       demonstrates the problem. Log bug reports in the PDL bug database at
648
649         http://sourceforge.net/bugs/?group_id=612
650
651       or send them to the pdl-porters mailing list
652       <pdl-porters@jach.hawaii.edu>.
653
655       Copyright (c) 2001, 2002 Christian Soeller. All Rights Reserved.  This
656       module is free software. It may be used, redistributed and/or modified
657       under the same terms as PDL itself (see http://pdl.perl.org).
658
659
660
661perl v5.12.3                      2009-10-17                      NiceSlice(3)
Impressum