File Coverage

/root/.cpan/build/PDL-CCS-1.23.13-0/blib/lib/PDL/CCS/MatrixOps.pm
Criterion Covered Total %
statement 12 28 42.8
branch 0 18 0.0
condition 0 21 0.0
subroutine 4 5 80.0
pod 1 1 100.0
total 17 73 23.2


line stmt bran cond sub pod time code
1              
2             #
3             # GENERATED WITH PDL::PP! Don't modify!
4             #
5             package PDL::CCS::MatrixOps;
6              
7             @EXPORT_OK = qw( PDL::PP ccs_matmult2d_sdd PDL::PP ccs_matmult2d_zdd PDL::PP ccs_vnorm ccs_vcos_zdd PDL::PP _ccs_vcos_zdd PDL::PP ccs_vcos_pzd );
8             %EXPORT_TAGS = (Func=>[@EXPORT_OK]);
9              
10 4     4   31 use PDL::Core;
  4         9  
  4         28  
11 4     4   1068 use PDL::Exporter;
  4         8  
  4         24  
12 4     4   163 use DynaLoader;
  4         9  
  4         334  
13              
14              
15              
16             $PDL::CCS::MatrixOps::VERSION = 1.23.13;
17             @ISA = ( 'PDL::Exporter','DynaLoader' );
18             push @PDL::Core::PP, __PACKAGE__;
19             bootstrap PDL::CCS::MatrixOps $VERSION;
20              
21              
22              
23              
24              
25             #use PDL::CCS::Version;
26 4     4   25 use strict;
  4         8  
  4         1838  
27              
28             =pod
29              
30             =head1 NAME
31              
32             PDL::CCS::MatrixOps - Low-level matrix operations for compressed storage sparse PDLs
33              
34             =head1 SYNOPSIS
35              
36             use PDL;
37             use PDL::CCS::MatrixOps;
38              
39             ##---------------------------------------------------------------------
40             ## ... stuff happens
41              
42             =cut
43              
44              
45              
46              
47              
48              
49              
50             =head1 FUNCTIONS
51              
52              
53              
54             =cut
55              
56              
57              
58              
59             *ccs_indx = \&PDL::indx; ##-- typecasting for CCS indices
60              
61              
62              
63              
64             =head2 ccs_matmult2d_sdd
65              
66             =for sig
67              
68             Signature: (
69             indx ixa(NdimsA,NnzA); nza(NnzA); missinga();
70             b(O,M);
71             zc(O);
72             [o]c(O,N)
73             )
74              
75              
76             Two-dimensional matrix multiplication of a sparse index-encoded PDL
77             $a() with a dense pdl $b(), with output to a dense pdl $c().
78              
79             The sparse input PDL $a() should be passed here with 0th
80             dimension "M" and 1st dimension "N", just as for the
81             built-in PDL::Primitive::matmult().
82              
83             "Missing" values in $a() are treated as $missinga(), which shouldn't
84             be BAD or infinite, but otherwise ought to be handled correctly.
85             The input pdl $zc() is used to pass the cached contribution of
86             a $missinga()-row ("M") to an output column ("O"), i.e.
87              
88             $zc = ((zeroes($M,1)+$missinga) x $b)->flat;
89              
90             $SIZE(Ndimsa) is assumed to be 2.
91              
92              
93             =for bad
94              
95             ccs_matmult2d_sdd does not process bad values.
96             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
97              
98              
99             =cut
100              
101              
102              
103              
104              
105              
106             *ccs_matmult2d_sdd = \&PDL::ccs_matmult2d_sdd;
107              
108              
109              
110              
111              
112             =head2 ccs_matmult2d_zdd
113              
114             =for sig
115              
116             Signature: (
117             indx ixa(Ndimsa,NnzA); nza(NnzA);
118             b(O,M);
119             [o]c(O,N)
120             )
121              
122              
123             Two-dimensional matrix multiplication of a sparse index-encoded PDL
124             $a() with a dense pdl $b(), with output to a dense pdl $c().
125              
126             The sparse input PDL $a() should be passed here with 0th
127             dimension "M" and 1st dimension "N", just as for the
128             built-in PDL::Primitive::matmult().
129              
130             "Missing" values in $a() are treated as zero.
131             $SIZE(Ndimsa) is assumed to be 2.
132              
133              
134             =for bad
135              
136             ccs_matmult2d_zdd does not process bad values.
137             It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
138              
139              
140             =cut
141              
142              
143              
144              
145              
146              
147             *ccs_matmult2d_zdd = \&PDL::ccs_matmult2d_zdd;
148              
149              
150              
151              
152              
153             =head2 ccs_vnorm
154              
155             =for sig
156              
157             Signature: (
158             indx acols(NnzA); avals(NnzA);
159             float+ [o]vnorm(M);
160             ; int sizeM=>M)
161              
162              
163             Computes the Euclidean lengths of each column-vector $a(i,*) of a sparse index-encoded pdl $a()
164             of logical dimensions (M,N), with output to a dense piddle $vnorm().
165             "Missing" values in $a() are treated as zero,
166             and $acols() specifies the (unsorted) indices along the logical dimension M of the corresponding non-missing
167             values in $avals().
168             This is basically the same thing as:
169              
170             $vnorm = ($a**2)->xchg(0,1)->sumover->sqrt;
171              
172             ... but should be must faster to compute for sparse index-encoded piddles.
173              
174              
175              
176             =for bad
177              
178             ccs_vnorm() always clears the bad-status flag on $vnorm().
179              
180             =cut
181              
182              
183              
184              
185              
186              
187             *ccs_vnorm = \&PDL::ccs_vnorm;
188              
189              
190              
191              
192             =pod
193              
194             =head2 ccs_vcos_zdd
195              
196             =for sig
197              
198             Signature: (
199             indx ixa(2,NnzA); nza(NnzA);
200             b(N);
201             float+ [o]vcos(M);
202             float+ [t]anorm(M);
203             int sizeM=>M;
204             )
205              
206              
207             Computes the vector cosine similarity of a dense row-vector $b(N) with respect to each column $a(i,*)
208             of a sparse index-encoded PDL $a() of logical dimensions (M,N), with output to a dense piddle
209             $vcos(M).
210             "Missing" values in $a() are treated as zero,
211             and magnitudes for $a() are passed in the optional parameter $anorm(), which will be implicitly
212             computed using L if the $anorm() parameter is omitted or empty.
213             This is basically the same thing as:
214              
215             $anorm //= ($a**2)->xchg(0,1)->sumover->sqrt;
216             $vcos = ($a * $b->slice("*1,"))->xchg(0,1)->sumover / ($anorm * ($b**2)->sumover->sqrt);
217              
218             ... but should be must faster to compute.
219              
220             Output values in $vcos() are cosine similarities in the range [-1,1],
221             except for zero-magnitude vectors which will result in NaN values in $vcos().
222             If you need non-negative distances, follow this up with a:
223              
224             $vcos->minus(1,$vcos,1)
225             $vcos->inplace->setnantobad->inplace->setbadtoval(0); ##-- minimum distance for NaN values
226              
227             to get distances values in the range [0,2]. You can use PDL threading to batch-compute distances for
228             multiple $b() vectors simultaneously:
229              
230             $bx = random($N, $NB); ##-- get $NB random vectors of size $N
231             $vcos = ccs_vcos_zdd($ixa,$nza, $bx, $M); ##-- $vcos is now ($M,$NB)
232              
233              
234             =for bad
235              
236             ccs_vcos_zdd() always clears the bad status flag on the output piddle $vcos.
237              
238             =cut
239              
240             sub ccs_vcos_zdd {
241 0     0 1   my ($ixa,$nza,$b) = @_;
242 0 0         barf("Usage: ccs_vcos_zdd(ixa, nza, b, vcos?, anorm?, M?)") if (grep {!defined($_)} ($ixa,$nza,$b));
  0            
243              
244 0           my ($anorm,$vcos,$M);
245 0           foreach (@_[3..$#_]) {
246 0 0 0       if (!defined($M) && !UNIVERSAL::isa($_,"PDL")) { $M=$_; }
  0 0          
    0          
247 0           elsif (!defined($vcos)) { $vcos = $_; } ##-- compat: pass $vcos() in first
248 0           elsif (!defined($anorm)) { $anorm = $_; }
249             }
250              
251             ##-- get M
252 0 0 0       $M = $vcos->dim(0) if (!defined($M) && defined($vcos) && !$vcos->isempty);
      0        
253 0 0 0       $M = $anorm->dim(0) if (!defined($M) && defined($anorm) && !$anorm->isempty);
      0        
254 0 0         $M = $ixa->slice("(0),")->max+1 if (!defined($M));
255              
256             ##-- compat: create output piddles, implicitly computing anorm() if required
257 0 0 0       $anorm = $ixa->slice("(0),")->ccs_vnorm($nza, $M) if (!defined($anorm) || $anorm->isempty);
258 0 0 0       $vcos = PDL->zeroes($anorm->type, $M, ($b->dims)[1..$b->ndims-1]) if (!defined($vcos) || $vcos->isempty);
259              
260             ##-- guts
261 0           $ixa->_ccs_vcos_zdd($nza,$b, $anorm, $vcos);
262 0           return $vcos;
263             }
264              
265             *PDL::ccs_vcos_zdd = \&ccs_vcos_zdd;
266              
267              
268              
269              
270              
271             =head2 _ccs_vcos_zdd
272              
273             =for sig
274              
275             Signature: (
276             indx ixa(Two,NnzA); nza(NnzA);
277             b(N);
278             float+ anorm(M);
279             float+ [o]vcos(M);)
280              
281             =for ref
282              
283             Guts for L, with slightly different calling conventions.
284              
285             =for bad
286              
287             Always clears the bad status flag on the output piddle $vcos.
288              
289             =cut
290              
291              
292              
293              
294              
295              
296             *_ccs_vcos_zdd = \&PDL::_ccs_vcos_zdd;
297              
298              
299              
300              
301              
302             =head2 ccs_vcos_pzd
303              
304             =for sig
305              
306             Signature: (
307             indx aptr(Nplus1); indx acols(NnzA); avals(NnzA);
308             indx brows(NnzB); bvals(NnzB);
309             anorm(M);
310             float+ [o]vcos(M);)
311              
312              
313             Computes the vector cosine similarity of a sparse index-encoded row-vector $b() of logical dimension (N)
314             with respect to each column $a(i,*) a sparse Harwell-Boeing row-encoded PDL $a() of logical dimensions (M,N),
315             with output to a dense piddle $vcos(M).
316             "Missing" values in $a() are treated as zero,
317             and magnitudes for $a() are passed in the obligatory parameter $anorm().
318             Usually much faster than L if a CRS pointer over logical dimension (N) is available
319             for $a().
320              
321              
322             =for bad
323              
324             ccs_vcos_pzd() always clears the bad status flag on the output piddle $vcos.
325              
326             =cut
327              
328              
329              
330              
331              
332              
333             *ccs_vcos_pzd = \&PDL::ccs_vcos_pzd;
334              
335              
336              
337              
338             ##---------------------------------------------------------------------
339             =pod
340              
341             =head1 ACKNOWLEDGEMENTS
342              
343             Perl by Larry Wall.
344              
345             PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others.
346              
347             =cut
348              
349             ##----------------------------------------------------------------------
350             =pod
351              
352             =head1 KNOWN BUGS
353              
354             We should really implement matrix multiplication in terms of
355             inner product, and have a good sparse-matrix only implementation
356             of the former.
357              
358             =cut
359              
360              
361             ##---------------------------------------------------------------------
362             =pod
363              
364             =head1 AUTHOR
365              
366             Bryan Jurish Emoocow@cpan.orgE
367              
368             =head2 Copyright Policy
369              
370             All other parts Copyright (C) 2009-2015, Bryan Jurish. All rights reserved.
371              
372             This package is free software, and entirely without warranty.
373             You may redistribute it and/or modify it under the same terms
374             as Perl itself.
375              
376             =head1 SEE ALSO
377              
378             perl(1), PDL(3perl)
379              
380             =cut
381              
382              
383              
384             ;
385              
386              
387              
388             # Exit with OK status
389              
390             1;
391              
392