File Coverage

blib/lib/PDLA/Basic.pm
Criterion Covered Total %
statement 131 162 80.8
branch 57 92 61.9
condition 14 24 58.3
subroutine 27 30 90.0
pod 5 25 20.0
total 234 333 70.2


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             PDLA::Basic -- Basic utility functions for PDLA
5              
6             =head1 DESCRIPTION
7              
8             This module contains basic utility functions for
9             creating and manipulating piddles. Most of these functions
10             are simplified interfaces to the more flexible functions in
11             the modules
12             L
13             and
14             L.
15              
16             =head1 SYNOPSIS
17              
18             use PDLA::Basic;
19              
20             =head1 FUNCTIONS
21              
22             =cut
23              
24             package PDLA::Basic;
25 78     78   529 use PDLA::Core '';
  78         170  
  78         552  
26 78     78   487 use PDLA::Types;
  78         154  
  78         9570  
27 78     78   537 use PDLA::Exporter;
  78         200  
  78         519  
28 78     78   453 use PDLA::Options;
  78         179  
  78         206251  
29              
30             @ISA=qw/PDLA::Exporter/;
31             @EXPORT_OK = qw/ ndcoords rvals axisvals allaxisvals xvals yvals zvals sec ins hist whist
32             similar_assign transpose sequence xlinvals ylinvals
33             zlinvals axislinvals/;
34             %EXPORT_TAGS = (Func=>[@EXPORT_OK]);
35              
36             # Exportable functions
37             *axisvals = \&PDLA::axisvals;
38             *allaxisvals = \&PDLA::allaxisvals;
39             *sec = \&PDLA::sec;
40             *ins = \&PDLA::ins;
41             *hist = \&PDLA::hist;
42             *whist = \&PDLA::whist;
43             *similar_assign = \&PDLA::similar_assign;
44             *transpose = \&PDLA::transpose;
45             *xlinvals = \&PDLA::xlinvals;
46             *ylinvals = \&PDLA::ylinvals;
47             *zlinvals = \&PDLA::zlinvals;
48              
49             =head2 xvals
50              
51             =for ref
52              
53             Fills a piddle with X index values. Uses similar specifications to
54             L and L.
55              
56             CAVEAT:
57              
58             If you use the single argument piddle form (top row
59             in the usage table) the output will have the same type as the input;
60             this may give surprising results if, e.g., you have a byte array with
61             a dimension of size greater than 256. To force a type, use the third form.
62              
63             =for usage
64              
65             $x = xvals($somearray);
66             $x = xvals([OPTIONAL TYPE],$nx,$ny,$nz...);
67             $x = xvals([OPTIONAL TYPE], $somarray->dims);
68              
69             etc. see L.
70              
71             =for example
72              
73             pdla> print xvals zeroes(5,10)
74             [
75             [0 1 2 3 4]
76             [0 1 2 3 4]
77             [0 1 2 3 4]
78             [0 1 2 3 4]
79             [0 1 2 3 4]
80             [0 1 2 3 4]
81             [0 1 2 3 4]
82             [0 1 2 3 4]
83             [0 1 2 3 4]
84             [0 1 2 3 4]
85             ]
86              
87             =head2 yvals
88              
89             =for ref
90              
91             Fills a piddle with Y index values. See the CAVEAT for L.
92              
93             =for usage
94              
95             $x = yvals($somearray); yvals(inplace($somearray));
96             $x = yvals([OPTIONAL TYPE],$nx,$ny,$nz...);
97              
98             etc. see L.
99              
100             =for example
101              
102             pdla> print yvals zeroes(5,10)
103             [
104             [0 0 0 0 0]
105             [1 1 1 1 1]
106             [2 2 2 2 2]
107             [3 3 3 3 3]
108             [4 4 4 4 4]
109             [5 5 5 5 5]
110             [6 6 6 6 6]
111             [7 7 7 7 7]
112             [8 8 8 8 8]
113             [9 9 9 9 9]
114             ]
115              
116             =head2 zvals
117              
118             =for ref
119              
120             Fills a piddle with Z index values. See the CAVEAT for L.
121              
122             =for usage
123              
124             $x = zvals($somearray); zvals(inplace($somearray));
125             $x = zvals([OPTIONAL TYPE],$nx,$ny,$nz...);
126              
127             etc. see L.
128              
129             =for example
130              
131             pdla> print zvals zeroes(3,4,2)
132             [
133             [
134             [0 0 0]
135             [0 0 0]
136             [0 0 0]
137             [0 0 0]
138             ]
139             [
140             [1 1 1]
141             [1 1 1]
142             [1 1 1]
143             [1 1 1]
144             ]
145             ]
146              
147             =head2 xlinvals
148              
149             =for ref
150              
151             X axis values between endpoints (see L).
152              
153             =for usage
154              
155             $w = zeroes(100,100);
156             $x = $w->xlinvals(0.5,1.5);
157             $y = $w->ylinvals(-2,-1);
158             # calculate Z for X between 0.5 and 1.5 and
159             # Y between -2 and -1.
160             $z = f($x,$y);
161              
162             C, C and C return a piddle with the same shape
163             as their first argument and linearly scaled values between the two other
164             arguments along the given axis.
165              
166             =head2 ylinvals
167              
168             =for ref
169              
170             Y axis values between endpoints (see L).
171              
172             See L for more information.
173              
174             =head2 zlinvals
175              
176             =for ref
177              
178             Z axis values between endpoints (see L).
179              
180             See L for more information.
181              
182             =head2 xlogvals
183              
184             =for ref
185              
186             X axis values logarithmically spaced between endpoints (see L).
187              
188             =for usage
189              
190             $w = zeroes(100,100);
191             $x = $w->xlogvals(1e-6,1e-3);
192             $y = $w->ylinvals(1e-4,1e3);
193             # calculate Z for X between 1e-6 and 1e-3 and
194             # Y between 1e-4 and 1e3.
195             $z = f($x,$y);
196              
197             C, C and C return a piddle with the same shape
198             as their first argument and logarithmically scaled values between the two other
199             arguments along the given axis.
200              
201             =head2 ylogvals
202              
203             =for ref
204              
205             Y axis values logarithmically spaced between endpoints (see L).
206              
207             See L for more information.
208              
209             =head2 zlogvals
210              
211             =for ref
212              
213             Z axis values logarithmically spaced between endpoints (see L).
214              
215             See L for more information.
216              
217             =cut
218              
219             # Conveniently named interfaces to axisvals()
220              
221 31 100 100 31 1 2109 sub xvals { ref($_[0]) && ref($_[0]) ne 'PDLA::Type' ? $_[0]->xvals : PDLA->xvals(@_) }
222 18 100 66 18 1 206 sub yvals { ref($_[0]) && ref($_[0]) ne 'PDLA::Type' ? $_[0]->yvals : PDLA->yvals(@_) }
223 3 100 66 3 1 37 sub zvals { ref($_[0]) && ref($_[0]) ne 'PDLA::Type' ? $_[0]->zvals : PDLA->zvals(@_) }
224             sub PDLA::xvals {
225 169     169 0 306 my $class = shift;
226 169 100       769 my $pdl = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inplace;
227 169         811 axisvals2($pdl,0);
228 169         4495 return $pdl;
229             }
230             sub PDLA::yvals {
231 24     24 0 56 my $class = shift;
232 24 100       112 my $pdl = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inplace;
233 24         123 axisvals2($pdl,1);
234 24         3797 return $pdl;
235             }
236             sub PDLA::zvals {
237 5     5 0 15 my $class = shift;
238 5 100       31 my $pdl = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inplace;
239 5         24 axisvals2($pdl,2);
240 5         3277 return $pdl;
241             }
242              
243             sub PDLA::xlinvals {
244 1     1 0 10 my $dim = $_[0]->getdim(0);
245 1 50       4 barf "Must have at least two elements in dimension for xlinvals"
246             if $dim <= 1;
247 1         6 return $_[0]->xvals * (($_[2] - $_[1]) / ($dim-1)) + $_[1];
248             }
249              
250             sub PDLA::ylinvals {
251 1     1 0 98 my $dim = $_[0]->getdim(1);
252 1 50       5 barf "Must have at least two elements in dimension for ylinvals"
253             if $dim <= 1;
254 1         6 return $_[0]->yvals * (($_[2] - $_[1]) / ($dim-1)) + $_[1];
255             }
256              
257             sub PDLA::zlinvals {
258 1     1 0 19 my $dim = $_[0]->getdim(2);
259 1 50       6 barf "Must have at least two elements in dimension for zlinvals"
260             if $dim <= 1;
261 1         6 return $_[0]->zvals * (($_[2] - $_[1]) / ($dim-1)) + $_[1];
262             }
263              
264             sub PDLA::xlogvals {
265 1     1 0 10 my $dim = $_[0]->getdim(0);
266 1 50       6 barf "Must have at least two elements in dimension for xlogvals"
267             if $dim <= 1;
268 1         4 my ($xmin,$xmax) = @_[1,2];
269 1 50 33     9 barf "xmin and xmax must be positive"
270             if $xmin <= 0 || $xmax <= 0;
271 1         6 my ($lxmin,$lxmax) = (log($xmin), log($xmax));
272 1         4 return exp($_[0]->xvals * (($lxmax - $lxmin) / ($dim-1)) + $lxmin);
273             }
274              
275             sub PDLA::ylogvals {
276 1     1 0 12 my $dim = $_[0]->getdim(1);
277 1 50       5 barf "Must have at least two elements in dimension for xlogvals"
278             if $dim <= 1;
279 1         5 my ($xmin,$xmax) = @_[1,2];
280 1 50 33     8 barf "xmin and xmax must be positive"
281             if $xmin <= 0 || $xmax <= 0;
282 1         4 my ($lxmin,$lxmax) = (log($xmin), log($xmax));
283 1         5 return exp($_[0]->yvals * (($lxmax - $lxmin) / ($dim-1)) + $lxmin);
284             }
285              
286             sub PDLA::zlogvals {
287 1     1 0 13 my $dim = $_[0]->getdim(2);
288 1 50       4 barf "Must have at least two elements in dimension for xlogvals"
289             if $dim <= 1;
290 1         4 my ($xmin,$xmax) = @_[1,2];
291 1 50 33     7 barf "xmin and xmax must be positive"
292             if $xmin <= 0 || $xmax <= 0;
293 1         5 my ($lxmin,$lxmax) = (log($xmin), log($xmax));
294 1         4 return exp($_[0]->zvals * (($lxmax - $lxmin) / ($dim-1)) + $lxmin);
295             }
296              
297              
298             =head2 allaxisvals
299              
300             =for ref
301              
302             Synonym for L - enumerates all coordinates in a
303             PDLA or dim list, adding an extra dim on the front to accommodate
304             the vector coordinate index (the form expected by L,
305             L, and L). See L for more detail.
306              
307             =for usage
308              
309             $indices = allaxisvals($pdl);
310             $indices = allaxisvals(@dimlist);
311             $indices = allaxisvals($type,@dimlist);
312              
313             =cut
314              
315             =head2 ndcoords
316              
317             =for ref
318              
319             Enumerate pixel coordinates for an N-D piddle
320              
321             Returns an enumerated list of coordinates suitable for use in
322             L or L: you feed
323             in a dimension list and get out a piddle whose 0th dimension runs over
324             dimension index and whose 1st through Nth dimensions are the
325             dimensions given in the input. If you feed in a piddle instead of a
326             perl list, then the dimension list is used, as in L etc.
327              
328             Unlike L etc., if you supply a piddle input, you get
329             out a piddle of the default piddle type: double. This causes less
330             surprises than the previous default of keeping the data type of
331             the input piddle since that rarely made sense in most usages.
332              
333             =for usage
334              
335             $indices = ndcoords($pdl);
336             $indices = ndcoords(@dimlist);
337             $indices = ndcoords($type,@dimlist);
338              
339             =for example
340              
341             pdla> print ndcoords(2,3)
342              
343             [
344             [
345             [0 0]
346             [1 0]
347             ]
348             [
349             [0 1]
350             [1 1]
351             ]
352             [
353             [0 2]
354             [1 2]
355             ]
356             ]
357              
358             pdla> $w = zeroes(byte,2,3); # $w is a 2x3 byte piddle
359             pdla> $y = ndcoords($w); # $y inherits $w's type
360             pdla> $c = ndcoords(long,$w->dims); # $c is a long piddle, same dims as $y
361             pdla> help $y;
362             This variable is Byte D [2,2,3] P 0.01Kb
363             pdla> help $c;
364             This variable is Long D [2,2,3] P 0.05Kb
365              
366              
367             =cut
368              
369             sub PDLA::ndcoords {
370 1     1 0 3 my $type;
371 1 50       4 if(ref $_[0] eq 'PDLA::Type') {
372 0         0 $type = shift;
373             }
374            
375 1 50       5 my @dims = (ref $_[0]) ? (shift)->dims : @_;
376 1         2 my @d = @dims;
377 1         3 unshift(@d,scalar(@dims));
378 1 50       3 unshift(@d,$type) if defined($type);
379              
380 1         11 $out = PDLA->zeroes(@d);
381            
382 1         4 for my $d(0..$#dims) {
383 2         22 my $w = $out->index($d)->mv($d,0);
384 2         14 $w .= xvals($w);
385             }
386              
387 1         11 $out;
388             }
389             *ndcoords = \&PDLA::ndcoords;
390             *allaxisvals = \&PDLA::ndcoords;
391             *PDLA::allaxisvals = \&PDLA::ndcoords;
392            
393              
394             =head2 hist
395              
396             =for ref
397              
398             Create histogram of a piddle
399              
400             =for usage
401              
402             $hist = hist($data);
403             ($xvals,$hist) = hist($data);
404              
405             or
406              
407             $hist = hist($data,$min,$max,$step);
408             ($xvals,$hist) = hist($data,[$min,$max,$step]);
409              
410             If C is run in list context, C<$xvals> gives the
411             computed bin centres as double values.
412              
413             A nice idiom (with
414             L) is
415              
416             bin hist $data; # Plot histogram
417              
418             =for example
419              
420             pdla> p $y
421             [13 10 13 10 9 13 9 12 11 10 10 13 7 6 8 10 11 7 12 9 11 11 12 6 12 7]
422             pdla> $h = hist $y,0,20,1; # hist with step 1, min 0 and 20 bins
423             pdla> p $h
424             [0 0 0 0 0 0 2 3 1 3 5 4 4 4 0 0 0 0 0 0]
425              
426             =cut
427              
428             sub PDLA::hist {
429              
430 2     2 0 15 my $usage = "\n" . ' Usage: $hist = hist($data)' . "\n" .
431             ' $hist = hist($data,$min,$max,$step)' . "\n" .
432             ' ($xvals,$hist) = hist($data)' . "\n" .
433             ' ($xvals,$hist) = hist($data,$min,$max,$step)' . "\n" ;
434 2 50       11 barf($usage) if $#_<0;
435              
436 2         9 my($pdl,$min,$max,$step)=@_;
437 2         4 my $xvals;
438              
439 2         9 ($step, $min, $bins, $xvals) =
440             _hist_bin_calc($pdl, $min, $max, $step, wantarray());
441              
442 2         13 PDLA::Primitive::histogram($pdl->clump(-1),(my $hist = null),
443             $step,$min,$bins);
444              
445 2 100       30 return wantarray() ? ($xvals,$hist) : $hist;
446             }
447              
448             =head2 whist
449              
450             =for ref
451              
452             Create a weighted histogram of a piddle
453              
454             =for usage
455              
456             $hist = whist($data, $wt, [$min,$max,$step]);
457             ($xvals,$hist) = whist($data, $wt, [$min,$max,$step]);
458              
459             If requested, C<$xvals> gives the computed bin centres
460             as type double values. C<$data> and C<$wt> should have
461             the same dimensionality and extents.
462              
463             A nice idiom (with
464             L) is
465              
466             bin whist $data, $wt; # Plot histogram
467              
468             =for example
469              
470             pdla> p $y
471             [13 10 13 10 9 13 9 12 11 10 10 13 7 6 8 10 11 7 12 9 11 11 12 6 12 7]
472             pdla> $wt = grandom($y->nelem)
473             pdla> $h = whist $y, $wt, 0, 20, 1 # hist with step 1, min 0 and 20 bins
474             pdla> p $h
475             [0 0 0 0 0 0 -0.49552342 1.7987439 0.39450696 4.0073722 -2.6255299 -2.5084501 2.6458365 4.1671676 0 0 0 0 0 0]
476              
477              
478             =cut
479              
480             sub PDLA::whist {
481 1 50   1 0 7 barf('Usage: ([$xvals],$hist) = whist($data,$wt,[$min,$max,$step])')
482             if @_ < 2;
483 1         4 my($pdl,$wt,$min,$max,$step)=@_;
484 1         2 my $xvals;
485              
486 1         4 ($step, $min, $bins, $xvals) =
487             _hist_bin_calc($pdl, $min, $max, $step, wantarray());
488              
489 1         8 PDLA::Primitive::whistogram($pdl->clump(-1),$wt->clump(-1),
490             (my $hist = null), $step, $min, $bins);
491 1 50       15 return wantarray() ? ($xvals,$hist) : $hist;
492             }
493              
494             sub _hist_bin_calc {
495 3     3   10 my($pdl,$min,$max,$step,$wantarray)=@_;
496 3 50       9 $min = $pdl->min() unless defined $min;
497 3 50       9 $max = $pdl->max() unless defined $max;
498 3         16 my $nelem = $pdl->nelem;
499 3 50       9 barf "empty piddle, no values to work with" if $nelem == 0;
500              
501 3 0       8 $step = ($max-$min)/(($nelem>10_000) ? 100 : sqrt($nelem)) unless defined $step;
    50          
502 3 50       10 barf "step is zero (or all data equal to one value)" if $step == 0;
503              
504 3         14 my $bins = int(($max-$min)/$step+0.5);
505 3 50       8 print "hist with step $step, min $min and $bins bins\n"
506             if $PDLA::debug;
507             # Need to use double for $xvals here
508 3 100       14 my $xvals = $min + $step/2 + sequence(PDLA::Core::double,$bins)*$step if $wantarray;
509              
510 3         36 return ( $step, $min, $bins, $xvals );
511             }
512              
513              
514             =head2 sequence
515              
516             =for ref
517              
518             Create array filled with a sequence of values
519              
520             =for usage
521              
522             $w = sequence($y); $w = sequence [OPTIONAL TYPE], @dims;
523              
524             etc. see L.
525              
526             =for example
527              
528             pdla> p sequence(10)
529             [0 1 2 3 4 5 6 7 8 9]
530             pdla> p sequence(3,4)
531             [
532             [ 0 1 2]
533             [ 3 4 5]
534             [ 6 7 8]
535             [ 9 10 11]
536             ]
537              
538             =cut
539              
540 110 50 66 110 1 92615 sub sequence { ref($_[0]) && ref($_[0]) ne 'PDLA::Type' ? $_[0]->sequence : PDLA->sequence(@_) }
541             sub PDLA::sequence {
542 115     115 0 1393 my $class = shift;
543 115 100       558 my $pdl = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inplace;
544 115         436 my $bar = $pdl->clump(-1)->inplace;
545 115         348 my $foo = $bar->xvals;
546 115         1739 return $pdl;
547             }
548              
549             =head2 rvals
550              
551             =for ref
552              
553             Fills a piddle with radial distance values from some centre.
554              
555             =for usage
556              
557             $r = rvals $piddle,{OPTIONS};
558             $r = rvals [OPTIONAL TYPE],$nx,$ny,...{OPTIONS};
559              
560             =for options
561              
562             Options:
563              
564             Centre => [$x,$y,$z...] # Specify centre
565             Center => [$x,$y.$z...] # synonym.
566              
567             Squared => 1 # return distance squared (i.e., don't take the square root)
568              
569             =for example
570              
571             pdla> print rvals long,7,7,{Centre=>[2,2]}
572             [
573             [2 2 2 2 2 3 4]
574             [2 1 1 1 2 3 4]
575             [2 1 0 1 2 3 4]
576             [2 1 1 1 2 3 4]
577             [2 2 2 2 2 3 4]
578             [3 3 3 3 3 4 5]
579             [4 4 4 4 4 5 5]
580             ]
581              
582             If C
is not specified, the midpoint for a given dimension of
583             size C is given by C< int(N/2) > so that the midpoint always falls
584             on an exact pixel point in the data. For dimensions of even size,
585             that means the midpoint is shifted by 1/2 pixel from the true center
586             of that dimension.
587              
588             Also note that the calculation for C for integer values
589             does not promote the datatype so you will have wraparound when
590             the value calculated for C< r**2 > is greater than the datatype
591             can hold. If you need exact values, be sure to use large integer
592             or floating point datatypes.
593              
594             For a more general metric, one can define, e.g.,
595              
596             sub distance {
597             my ($w,$centre,$f) = @_;
598             my ($r) = $w->allaxisvals-$centre;
599             $f->($r);
600             }
601             sub l1 { sumover(abs($_[0])); }
602             sub euclid { use PDLA::Math 'pow'; pow(sumover(pow($_[0],2)),0.5); }
603             sub linfty { maximum(abs($_[0])); }
604              
605             so now
606              
607             distance($w, $centre, \&euclid);
608              
609             will emulate rvals, while C<\&l1> and C<\&linfty> will generate other
610             well-known norms.
611              
612             =cut
613              
614 9 50 66 9 1 1590 sub rvals { ref($_[0]) && ref($_[0]) ne 'PDLA::Type' ? $_[0]->rvals(@_[1..$#_]) : PDLA->rvals(@_) }
615             sub PDLA::rvals { # Return radial distance from given point and offset
616 9     9 0 21 my $class = shift;
617 9 100       31 my $opt = pop @_ if ref($_[$#_]) eq "HASH";
618 9 100       49 my %opt = defined $opt ?
619             iparse( {
620             CENTRE => undef, # needed, otherwise centre/center handling painful
621             Squared => 0,
622             }, $opt ) : ();
623 9 50       68 my $r = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inplace;
624              
625 9         16 my @pos;
626 9 100       27 @pos = @{$opt{CENTRE}} if defined $opt{CENTRE};
  5         13  
627 9         14 my $offset;
628              
629 9         84 $r .= 0.0;
630 9         57 my $tmp = $r->copy;
631 9         17 my $i;
632 9         43 for ($i=0; $i<$r->getndims; $i++) {
633 18 100       75 $offset = (defined $pos[$i] ? $pos[$i] : int($r->getdim($i)/2));
634             # Note careful coding for speed and min memory footprint
635 18         355 PDLA::Primitive::axisvalues($tmp->xchg(0,$i));
636 18         125 $tmp -= $offset; $tmp *= $tmp;
  18         53  
637 18         47 $r += $tmp;
638             }
639 9 100       53 return $opt{Squared} ? $r : $r->inplace->sqrt;
640             }
641              
642             =head2 axisvals
643              
644             =for ref
645              
646             Fills a piddle with index values on Nth dimension
647              
648             =for usage
649              
650             $z = axisvals ($piddle, $nth);
651              
652             This is the routine, for which L, L etc
653             are mere shorthands. C can be used to fill along any dimension,
654             using a parameter.
655              
656             See also L, which generates all axis values
657             simultaneously in a form useful for L, L,
658             L, etc.
659              
660             Note the 'from specification' style (see L) is
661             not available here, for obvious reasons.
662              
663             =cut
664              
665             sub PDLA::axisvals {
666 1     1 0 3 my($this,$nth) = @_;
667 1         4 my $dummy = $this->new_or_inplace;
668 1 50       7 if($dummy->getndims() <= $nth) {
669             # This is 'kind of' consistency...
670 0         0 $dummy .= 0;
671 0         0 return $dummy;
672             # barf("Too few dimensions given to axisvals $nth\n");
673             }
674 1         6 my $bar = $dummy->xchg(0,$nth);
675 1         16 PDLA::Primitive::axisvalues($bar);
676 1         6 return $dummy;
677             }
678              
679             # We need this version for xvals etc to work in place
680             sub axisvals2 {
681 198     198 0 576 my($this,$nth) = @_;
682 198         331 my $dummy = shift;
683 198 50       1117 if($dummy->getndims() <= $nth) {
684             # This is 'kind of' consistency...
685 0         0 $dummy .= 0;
686 0         0 return $dummy;
687             # barf("Too few dimensions given to axisvals $nth\n");
688             }
689 198         1593 my $bar = $dummy->xchg(0,$nth);
690 198         8937 PDLA::Primitive::axisvalues($bar);
691 198         1492 return $dummy;
692             }
693             sub PDLA::sec {
694 0     0 0 0 my($this,@coords) = @_;
695 0         0 my $i; my @maps;
696 0         0 while($#coords > -1) {
697 0         0 $i = int(shift @coords) ;
698 0         0 push @maps, "$i:".int(shift @coords);
699             }
700 0         0 my $tmp = PDLA->null;
701 0         0 $tmp .= $this->slice(join ',',@maps);
702 0         0 return $tmp;
703             }
704              
705             sub PDLA::ins {
706 0     0 0 0 my($this,$what,@coords) = @_;
707 0         0 my $w = PDLA::Core::alltopdl($PDLA::name,$what);
708 0         0 my $tmp;
709 0 0       0 if($this->is_inplace) {
710 0         0 $this->set_inplace(0);
711             } else {
712 0         0 $this = $this->copy;
713             }
714             ($tmp = $this->slice(
715 0 0       0 (join ',',map {int($coords[$_]).":".
  0         0  
716             ((int($coords[$_])+$w->getdim($_)-1)<$this->getdim($_) ?
717             (int($coords[$_])+$w->getdim($_)-1):$this->getdim($_))
718             }
719             0..$#coords)))
720             .= $w;
721 0         0 return $this;
722             }
723              
724             sub PDLA::similar_assign {
725 0     0 0 0 my($from,$to) = @_;
726 0 0       0 if((join ',',@{$from->dims}) ne (join ',',@{$to->dims})) {
  0         0  
  0         0  
727             barf "Similar_assign: dimensions [".
728 0         0 (join ',',@{$from->dims})."] and [".
729 0         0 (join ',',@{$to->dims})."] do not match!\n";
  0         0  
730             }
731 0         0 $to .= $from;
732             }
733              
734             =head2 transpose
735              
736             =for ref
737              
738             transpose rows and columns.
739              
740             =for usage
741              
742             $y = transpose($w);
743              
744             =for example
745              
746             pdla> $w = sequence(3,2)
747             pdla> p $w
748             [
749             [0 1 2]
750             [3 4 5]
751             ]
752             pdla> p transpose( $w )
753             [
754             [0 3]
755             [1 4]
756             [2 5]
757             ]
758              
759             =cut
760              
761             sub PDLA::transpose {
762 11     11 0 44 my($this) = @_;
763 11 100       50 if($this->getndims <= 1) {
764 4 50       21 if($this->getndims==0) {
765 0         0 return pdl $this->dummy(0)->dummy(0);
766             } else {
767 4         21 return pdl $this->dummy(0);
768             }
769             }
770 7         66 return $this->xchg(0,1);
771             }
772              
773             1;
774