| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
## File: PDL::CCS::Functions.pm |
|
2
|
|
|
|
|
|
|
## Author: Bryan Jurish |
|
3
|
|
|
|
|
|
|
## Description: useful perl-level functions for PDL::CCS |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package PDL::CCS::Functions; |
|
6
|
2
|
|
|
2
|
|
13
|
use PDL::CCS::Config qw(ccs_indx); |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
124
|
|
|
7
|
2
|
|
|
2
|
|
1260
|
use PDL::CCS::Utils; |
|
|
2
|
|
|
|
|
50
|
|
|
|
2
|
|
|
|
|
47
|
|
|
8
|
2
|
|
|
2
|
|
327
|
use PDL::VectorValued; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
12
|
|
|
9
|
2
|
|
|
2
|
|
339
|
use PDL; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
30
|
|
|
10
|
2
|
|
|
2
|
|
6653
|
use strict; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
1220
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
my @ccs_binops = qw( |
|
13
|
|
|
|
|
|
|
plus minus mult divide modulo power |
|
14
|
|
|
|
|
|
|
gt ge lt le eq ne spaceship |
|
15
|
|
|
|
|
|
|
and2 or2 xor shiftleft shiftright |
|
16
|
|
|
|
|
|
|
); |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.24.1'; ##-- update with perl-reversion from Perl::Version module |
|
19
|
|
|
|
|
|
|
our @ISA = ('PDL::Exporter'); |
|
20
|
|
|
|
|
|
|
our @EXPORT_OK = |
|
21
|
|
|
|
|
|
|
( |
|
22
|
|
|
|
|
|
|
## |
|
23
|
|
|
|
|
|
|
##-- Decoding |
|
24
|
|
|
|
|
|
|
qw(ccs_decode), #ccs_pointerlen |
|
25
|
|
|
|
|
|
|
## |
|
26
|
|
|
|
|
|
|
##-- Vector Operations (compat) |
|
27
|
|
|
|
|
|
|
qw(ccs_binop_vector_mia), |
|
28
|
|
|
|
|
|
|
(map "ccs_${_}_vector_mia", @ccs_binops), |
|
29
|
|
|
|
|
|
|
## |
|
30
|
|
|
|
|
|
|
##-- qsort |
|
31
|
|
|
|
|
|
|
qw(ccs_qsort), |
|
32
|
|
|
|
|
|
|
); |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
our %EXPORT_TAGS = |
|
35
|
|
|
|
|
|
|
( |
|
36
|
|
|
|
|
|
|
Func => [@EXPORT_OK], ##-- respect PDL conventions (hopefully) |
|
37
|
|
|
|
|
|
|
); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
##====================================================================== |
|
41
|
|
|
|
|
|
|
## pod: headers |
|
42
|
|
|
|
|
|
|
=pod |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 NAME |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
PDL::CCS::Functions - Useful perl-level functions for PDL::CCS |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
use PDL; |
|
51
|
|
|
|
|
|
|
use PDL::CCS::Functions; |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
##--------------------------------------------------------------------- |
|
54
|
|
|
|
|
|
|
## ... stuff happens |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=cut |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
##====================================================================== |
|
60
|
|
|
|
|
|
|
## Decoding |
|
61
|
|
|
|
|
|
|
=pod |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head1 Decoding |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=cut |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
##-- DEPRECATED STEALTH METHOD: formerly a PDL::PP function in PDL::CCS::Utils |
|
68
|
|
|
|
|
|
|
#*PDL::ccs_pointerlen = \&ccs_pointerlen; |
|
69
|
|
|
|
|
|
|
sub ccs_pointerlen :lvalue { |
|
70
|
0
|
|
|
0
|
0
|
0
|
my ($ptr,$len) = @_; |
|
71
|
0
|
0
|
|
|
|
0
|
if (!defined($len)) { |
|
72
|
0
|
|
|
|
|
0
|
$len = $ptr->slice("1:-1") - $ptr->slice("0:-2"); |
|
73
|
|
|
|
|
|
|
} else { |
|
74
|
0
|
|
|
|
|
0
|
$len .= $ptr->slice("1:-1"); |
|
75
|
0
|
|
|
|
|
0
|
$len -= $ptr->slice("0:-2"); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
0
|
|
|
|
|
0
|
return $len; |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
##--------------------------------------------------------------- |
|
82
|
|
|
|
|
|
|
## Decoding: generic |
|
83
|
|
|
|
|
|
|
=pod |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head2 ccs_decode |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=for sig |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
Signature: (indx whichnd(Ndims,Nnz); nzvals(Nnz); missing(); \@Dims; [o]a(@Dims)) |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Decode a CCS-encoded matrix (no dataflow). |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=cut |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
;#-- emacs |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
*PDL::ccs_decode = \&ccs_decode; |
|
98
|
|
|
|
|
|
|
sub ccs_decode :lvalue { |
|
99
|
7
|
|
|
7
|
1
|
19
|
my ($aw,$nzvals,$missing,$dims,$a) = @_; |
|
100
|
7
|
50
|
|
|
|
18
|
$missing = $PDL::undefval if (!defined($missing)); |
|
101
|
7
|
50
|
|
|
|
14
|
if (!defined($dims)) { |
|
102
|
0
|
0
|
|
|
|
0
|
barf("PDL::CCS::ccs_decode(): whichnd() is empty; you must specify \@Dims!") if ($aw->isempty); |
|
103
|
0
|
|
|
|
|
0
|
$dims = [ map {$aw->slice("($_),")->max+1} (0..($aw->dim(0)-1))]; |
|
|
0
|
|
|
|
|
0
|
|
|
104
|
|
|
|
|
|
|
} |
|
105
|
7
|
100
|
|
|
|
19
|
$a = zeroes($nzvals->type, @$dims) if (!defined($a)); |
|
106
|
7
|
|
|
|
|
55
|
$a .= $missing; |
|
107
|
|
|
|
|
|
|
|
|
108
|
7
|
|
|
|
|
112
|
(my $tmp=$a->indexND($aw)) .= $nzvals; ##-- CPAN tests puke here with "Can't modify non-lvalue subroutine call" in 5.15.x (perl bug #107366) |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
##-- workaround for missing empty pdl support in PDL 2.4.10 release candidates (pdl bug #3462924), fixed in 2.4.9_993 |
|
111
|
|
|
|
|
|
|
#$a->indexND($aw) .= $nzvals if (!$nzvals->isempty); |
|
112
|
|
|
|
|
|
|
#if (!$nzvals->isempty) { |
|
113
|
|
|
|
|
|
|
# my $tmp = $a->indexND($aw); |
|
114
|
|
|
|
|
|
|
# $tmp .= $nzvals; |
|
115
|
|
|
|
|
|
|
#} |
|
116
|
|
|
|
|
|
|
|
|
117
|
7
|
|
|
|
|
450
|
return $a; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
##====================================================================== |
|
121
|
|
|
|
|
|
|
## Scalar Operations |
|
122
|
|
|
|
|
|
|
=pod |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=head1 Scalar Operations |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Scalar operations can be performed in parallel directly on C<$nzvals> |
|
127
|
|
|
|
|
|
|
(and if applicable on C<$missing> as well): |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
$c = 42; |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
$nzvals2 = $nzvals + $c; $missing2 = $missing + $c; |
|
132
|
|
|
|
|
|
|
$nzvals2 = $nzvals - $c; $missing2 = $missing - $c; |
|
133
|
|
|
|
|
|
|
$nzvals2 = $nzvals * $c; $missing2 = $missing * $c; |
|
134
|
|
|
|
|
|
|
$nzvals2 = $nzvals / $c; $missing2 = $missing / $c; |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
$nzvals2 = $nzvals ** $c; $missing2 = $missing ** $c; |
|
137
|
|
|
|
|
|
|
$nzvals2 = log($nzvals); $missing2 = log($missing); |
|
138
|
|
|
|
|
|
|
$nzvals2 = exp($nzvals); $missing2 = exp(missing); |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
$nzvals2 = $nzvals->and2($c,0); $missing2 = $missing->and($c,0); |
|
141
|
|
|
|
|
|
|
$nzvals2 = $nzvals->or2($c,0); $missing2 = $missing->or2($c,0); |
|
142
|
|
|
|
|
|
|
$nzvals2 = $nzvals->not(); $missing2 = $missing->not(); |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Nothing prevents scalar operations from producing new "missing" values (e.g. $nzvals*0), |
|
145
|
|
|
|
|
|
|
so you might want to re-encode your compressed data after applying the operation. |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=cut |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
##====================================================================== |
|
151
|
|
|
|
|
|
|
## Vector Operations |
|
152
|
|
|
|
|
|
|
=pod |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=head1 Vector Operations |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 ccs_OP_vector_mia |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=for sig |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Signature: (indx whichDimV(Nnz); nzvals(Nnz); vec(V); [o]nzvals_out(Nnz)) |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
A number of row- and column-vector operations may be performed directly |
|
163
|
|
|
|
|
|
|
on encoded Nd-PDLs, without the need for decoding to a (potentially huge) |
|
164
|
|
|
|
|
|
|
dense temporary. These operations assume that "missing" values are |
|
165
|
|
|
|
|
|
|
annihilators with respect to the operation in question, i.e. |
|
166
|
|
|
|
|
|
|
that it holds for all C<$x> in C<$vec> that: |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
($missing __OP__ $x) == $missing |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
This is in line with the usual PDL semantics if your C<$missing> value is C, |
|
171
|
|
|
|
|
|
|
but may produce unexpected results when e.g. adding a vector to a sparse PDL with C<$missing>==0. |
|
172
|
|
|
|
|
|
|
If you really need to do something like the latter, then you're probably better off decoding to |
|
173
|
|
|
|
|
|
|
a dense PDL anyway. |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Predefined function names for encoded-PDL vector operations are all of the form: |
|
176
|
|
|
|
|
|
|
C, where ${OPNAME} is the base name of the operation: |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
plus ##-- addition |
|
179
|
|
|
|
|
|
|
minus ##-- subtraction |
|
180
|
|
|
|
|
|
|
mult ##-- multiplication (NOT matrix-multiplication) |
|
181
|
|
|
|
|
|
|
divide ##-- division |
|
182
|
|
|
|
|
|
|
modulo ##-- modulo |
|
183
|
|
|
|
|
|
|
power ##-- potentiation |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
gt ##-- greater-than |
|
186
|
|
|
|
|
|
|
ge ##-- greater-than-or-equal |
|
187
|
|
|
|
|
|
|
lt ##-- less-than |
|
188
|
|
|
|
|
|
|
le ##-- less-than-or-equal |
|
189
|
|
|
|
|
|
|
eq ##-- equality |
|
190
|
|
|
|
|
|
|
ne ##-- inequality |
|
191
|
|
|
|
|
|
|
spaceship ##-- 3-way comparison |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
and2 ##-- binary AND |
|
194
|
|
|
|
|
|
|
or2 ##-- binary OR |
|
195
|
|
|
|
|
|
|
xor ##-- binary XOR |
|
196
|
|
|
|
|
|
|
shiftleft ##-- left-shift |
|
197
|
|
|
|
|
|
|
shiftright ##-- right-shift |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head2 \&CODE = ccs_binop_vector_mia($opName, \&PDLCODE); |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Returns a generic vector-operation subroutine which reports errors as C<$opName> |
|
202
|
|
|
|
|
|
|
and uses \&PDLCODE to perform underlying computation. |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=cut |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
##====================================================================== |
|
207
|
|
|
|
|
|
|
## Vector Operations: Generic |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
*PDL::ccs_binop_vector_mia = \&ccs_binop_vector_mia; |
|
210
|
|
|
|
|
|
|
sub ccs_binop_vector_mia { |
|
211
|
36
|
|
|
36
|
1
|
58
|
my ($opName,$pdlCode) = @_; |
|
212
|
|
|
|
|
|
|
return sub :lvalue { |
|
213
|
2
|
|
|
2
|
|
5
|
my ($wi, $nzvals_in, $vec) = @_; |
|
214
|
2
|
|
|
|
|
50
|
my $tmp = $pdlCode->($nzvals_in, $vec->index($wi), 0); # $tmp for perl -d |
|
215
|
36
|
|
|
|
|
128
|
}; |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
for (@ccs_binops) { |
|
219
|
2
|
|
|
2
|
|
16
|
no strict 'refs'; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
1367
|
|
|
220
|
|
|
|
|
|
|
*{"PDL::ccs_${_}_vector_mia"} = *{"ccs_${_}_vector_mia"} = ccs_binop_vector_mia($_, PDL->can($_)); |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
##====================================================================== |
|
224
|
|
|
|
|
|
|
## Sorting |
|
225
|
|
|
|
|
|
|
=pod |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head1 Sorting |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head2 ccs_qsort |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=for sig |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Signature: (indx which(Ndims,Nnz); nzvals(Nnz); missing(); Dim0(); indx [o]nzix(Nnz); indx [o]nzenum(Nnz)) |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
Underlying guts for PDL::CCS::Nd::qsort() and PDL::CCS::Nd::qsorti(). |
|
236
|
|
|
|
|
|
|
Given a set of $Nnz items $i each associated with a vector-key C<$which(:,$i)> |
|
237
|
|
|
|
|
|
|
and a value C<$nzvals($i)>, returns a vector of $Nnz item indices C<$nzix()> |
|
238
|
|
|
|
|
|
|
such that C<$which(:,$nzix)> is vector-sorted in ascending order and |
|
239
|
|
|
|
|
|
|
C<$nzvals(:,$nzix)> are sorted in ascending order for each unique key-vector in |
|
240
|
|
|
|
|
|
|
C<$which()>, and an enumeration C<$nzenum()> of items for each unique key-vector |
|
241
|
|
|
|
|
|
|
in terms of the sorted data: C<$nzenum($j)> is the logical position of the item |
|
242
|
|
|
|
|
|
|
C<$nzix($j)>. |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
If C<$missing> and C<$Dim0> are defined, |
|
245
|
|
|
|
|
|
|
items C<$i=$nzix($j)> with values C<$nzvals($i) E $missing> |
|
246
|
|
|
|
|
|
|
will be logically enumerated at the end of the range [0,$Dim0-1] |
|
247
|
|
|
|
|
|
|
and there will be a gap between C<$nzenum()> values for a C<$which()>-key |
|
248
|
|
|
|
|
|
|
with fewer than $Dim0 instances; otherwise $nzenum() values will be |
|
249
|
|
|
|
|
|
|
enumerated in ascending order starting from 0. |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
For an unsorted index+value dataset C<($which0,$nzvals0)> with |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
($nzix,$nzenum) = ccs_qsort($which0("1:-1,"),$nzvals0,$missing,$which0("0,")->max+1) |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
qsort() can be implemented as: |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
$which = $nzenum("*1,")->glue(0,$which0("1:-1,")->dice_axis(1,$nzix)); |
|
258
|
|
|
|
|
|
|
$nzvals = $nzvals0->index($nzix); |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
and qsorti() as: |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
$which = $nzenum("*1,")->glue(0,$which0("1:-1,")->dice_axis(1,$nzix)); |
|
263
|
|
|
|
|
|
|
$nzvals = $which0("(0),")->index($nzix); |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=cut |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
## $bool = _checkdims(\@dims1,\@dims2,$label); ##-- match @dims1 ~ @dims2 |
|
268
|
|
|
|
|
|
|
## $bool = _checkdims( $pdl1, $pdl2,$label); ##-- match $pdl1->dims ~ $pdl2->dims |
|
269
|
|
|
|
|
|
|
sub _checkdims { |
|
270
|
|
|
|
|
|
|
#my ($dims1,$dims2,$label) = @_; |
|
271
|
|
|
|
|
|
|
#my ($pdl1,$pdl2,$label) = @_; |
|
272
|
0
|
0
|
|
0
|
|
|
my $d0 = UNIVERSAL::isa($_[0],'PDL') ? pdl(ccs_indx(),$_[0]->dims) : pdl(ccs_indx(),$_[0]); |
|
273
|
0
|
0
|
|
|
|
|
my $d1 = UNIVERSAL::isa($_[1],'PDL') ? pdl(ccs_indx(),$_[1]->dims) : pdl(ccs_indx(),$_[0]); |
|
274
|
0
|
0
|
0
|
|
|
|
barf(__PACKAGE__ . "::_checkdims(): dimension mismatch for ".($_[2]||'pdl').": $d0!=$d1") |
|
|
|
|
0
|
|
|
|
|
|
275
|
|
|
|
|
|
|
if (($d0->nelem!=$d1->nelem) || !all($d0==$d1)); |
|
276
|
0
|
|
|
|
|
|
return 1; |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub ccs_qsort { |
|
280
|
0
|
|
|
0
|
1
|
|
my ($which,$nzvals, $missing,$dim0, $nzix,$nzenum) = @_; |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
##-- prepare: $nzix |
|
283
|
0
|
0
|
|
|
|
|
$nzix = zeroes(ccs_indx(),$nzvals->dims) if (!defined($nzix)); |
|
284
|
0
|
0
|
|
|
|
|
$nzix->reshape($nzvals) if ($nzix->isempty); |
|
285
|
0
|
|
|
|
|
|
_checkdims($nzvals,$nzix,'ccs_qsort: nzvals~nzix'); |
|
286
|
|
|
|
|
|
|
## |
|
287
|
|
|
|
|
|
|
##-- prepare: $nzenum |
|
288
|
0
|
0
|
|
|
|
|
$nzenum = zeroes(ccs_indx(),$nzvals->dims) if (!defined($nzenum)); |
|
289
|
0
|
0
|
|
|
|
|
$nzenum->reshape($nzvals) if ($nzenum->isempty); |
|
290
|
0
|
|
|
|
|
|
_checkdims($nzenum,$nzvals,'ccs_qsort: nzvals~nzenum'); |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
##-- collect and sort base data (unsorted indices + values) |
|
293
|
0
|
|
|
|
|
|
my $vdata = $which->glue(0,$nzvals->slice("*1,")); |
|
294
|
0
|
|
|
|
|
|
$vdata->vv_qsortveci($nzix); |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
##-- get logical enumeration |
|
297
|
0
|
0
|
0
|
|
|
|
if (!defined($missing) || !defined($dim0)) { |
|
298
|
|
|
|
|
|
|
##-- ... flat enumeration |
|
299
|
0
|
|
|
|
|
|
$which->dice_axis(1,$nzix)->enumvec($nzenum); |
|
300
|
|
|
|
|
|
|
} else { |
|
301
|
|
|
|
|
|
|
##-- ... we have $missing and $dim0: split enumeration around $missing() |
|
302
|
0
|
|
|
|
|
|
my $whichx = $which->dice_axis(1,$nzix); |
|
303
|
0
|
|
|
|
|
|
my $nzvalsx = $nzvals->index($nzix); |
|
304
|
0
|
|
|
|
|
|
my ($nzii_l,$nzii_r) = which_both($nzvalsx <= $missing); |
|
305
|
|
|
|
|
|
|
#$nzenum .= -1; ##-- debug |
|
306
|
0
|
0
|
|
|
|
|
$whichx->dice_axis(1,$nzii_l)->enumvec($nzenum->index($nzii_l)) if (!$nzii_l->isempty); ##-- enum: <=$missing |
|
307
|
0
|
0
|
|
|
|
|
if (!$nzii_r->isempty) { |
|
308
|
|
|
|
|
|
|
##-- enum: >$missing |
|
309
|
0
|
|
|
|
|
|
my $nzenum_r = $nzenum->index($nzii_r); |
|
310
|
0
|
|
|
|
|
|
$whichx->dice_axis(1,$nzii_r)->slice(",-1:0")->enumvec($nzenum_r->slice("-1:0")); |
|
311
|
0
|
|
|
|
|
|
$nzenum_r *= -1; |
|
312
|
0
|
|
|
|
|
|
$nzenum_r += ($dim0-1); |
|
313
|
|
|
|
|
|
|
} |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
##-- all done |
|
317
|
0
|
0
|
|
|
|
|
return wantarray ? ($nzix,$nzenum) : $nzix; |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
##====================================================================== |
|
322
|
|
|
|
|
|
|
## Vector Operations: Generic |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
##====================================================================== |
|
326
|
|
|
|
|
|
|
## POD: footer |
|
327
|
|
|
|
|
|
|
=pod |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
Perl by Larry Wall. |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others. |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=cut |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
##--------------------------------------------------------------------- |
|
339
|
|
|
|
|
|
|
=pod |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=head1 AUTHOR |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Bryan Jurish Emoocow@cpan.orgE |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head2 Copyright Policy |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Copyright (C) 2007-2024, Bryan Jurish. All rights reserved. |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
This package is free software, and entirely without warranty. |
|
350
|
|
|
|
|
|
|
You may redistribute it and/or modify it under the same terms |
|
351
|
|
|
|
|
|
|
as Perl itself. |
|
352
|
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
perl(1), |
|
356
|
|
|
|
|
|
|
PDL(3perl), |
|
357
|
|
|
|
|
|
|
PDL::CCS::Nd(3perl), |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=cut |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
1; ##-- make perl happy |