File Coverage

blib/lib/PDL/CCS/MatrixOps.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


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