File Coverage

blib/lib/PDL/EditDistance.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 EditDistance.pd! Don't modify!
3             #
4             package PDL::EditDistance;
5              
6             our @EXPORT_OK = qw( edit_costs _edit_costs edit_costs_static edit_distance_full _edit_distance_full _edit_distance_full edit_align_full _edit_align_full _edit_align_full edit_distance_static _edit_distance_static _edit_distance_static edit_align_static _edit_align_static _edit_align_static align_op_insert1 align_op_insert1 align_op_insert2 align_op_insert2 align_op_match align_op_match align_op_substitute align_op_substitute align_op_insert align_op_delete align_ops edit_bestpath _edit_bestpath _edit_bestpath edit_pathtrace _edit_pathtrace _edit_pathtrace edit_lcs _edit_lcs _edit_lcs lcs_backtrace _lcs_backtrace _lcs_backtrace );
7             our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
8              
9 2     2   975732 use PDL::Core;
  2         4  
  2         12  
10 2     2   642 use PDL::Exporter;
  2         5  
  2         30  
11 2     2   60 use DynaLoader;
  2         3  
  2         916  
12              
13              
14             our $VERSION = '0.10';
15             our @ISA = ( 'PDL::Exporter','DynaLoader' );
16             push @PDL::Core::PP, __PACKAGE__;
17             bootstrap PDL::EditDistance $VERSION;
18              
19              
20              
21              
22              
23              
24              
25              
26             #line 12 "EditDistance.pd"
27              
28             use strict;
29             use version;
30              
31             ## $PDL_ATLEAST_2_014 : avoid in-place reshape() in _edit_pdl() for PDL >= 2.014
32             ## + prior to PDL-2.014, PDL::reshape() returned a new PDL, but modifies
33             ## the calling object in-place for v2.014
34             our $PDL_ATLEAST_2_014 = version->parse($PDL::VERSION) >= version->parse("2.014");
35              
36             =pod
37              
38             =head1 NAME
39              
40             PDL::EditDistance - Wagner-Fischer edit distance and alignment for PDLs.
41              
42             =head1 SYNOPSIS
43              
44             use PDL;
45             use PDL::EditDistance;
46              
47             ##-- input PDLs
48             $a = pdl([map { ord($_) } qw(G U M B O)]);
49             $b = pdl([map { ord($_) } qw(G A M B O L)]);
50              
51             $a1 = pdl([0, map { ord($_) } qw(G U M B O)]);
52             $b1 = pdl([0, map { ord($_) } qw(G A M B O L)]);
53              
54             ##-------------------------------------------------------------
55             ## Levenshtein distance
56             $dist = edit_distance_static($a,$b, 0,1,1,1);
57             ($dist,$align) = edit_align_static($a,$b, 0,1,1,1);
58              
59             ##-------------------------------------------------------------
60             ## Wagner-Fischer distance
61             @costs = ($costMatch=0,$costInsert=1,$costDelete=1,$costSubstitute=2);
62             $dist = edit_distance_static($a,$b, @costs);
63             ($dist,$align) = edit_align_static($a,$b, @costs);
64              
65             ##-------------------------------------------------------------
66             ## General edit distance
67             $costsMatch = random($a->nelem+1, $b->nelem+1);
68             $costsIns = random($a->nelem+1, $b->nelem+1);
69             $costsDel = random($a->nelem+1, $b->nelem+1);
70             $costsSubst = random($a->nelem+1, $b->nelem+1);
71             @costs = ($costsMatch,$costsIns,$costDel,$costsSubst);
72             $dist = edit_distance_full($a,$b,@costs);
73             ($dist,$align) = edit_align_full($a,$b,@costs);
74              
75             ##-------------------------------------------------------------
76             ## Alignment
77             $op_match = align_op_match(); ##-- constant
78             $op_del = align_op_insert1(); ##-- constant
79             $op_ins = align_op_insert2(); ##-- constant
80             $op_subst = align_op_substitute(); ##-- constant
81              
82             ($apath,$bpath,$pathlen) = edit_bestpath($align);
83             ($ai,$bi,$ops,$pathlen) = edit_pathtrace($align);
84              
85             ##-------------------------------------------------------------
86             ## Longest Common Subsequence
87             $lcs = edit_lcs($a,$b);
88             ($ai,$bi,$lcslen) = lcs_backtrace($a,$b,$lcs);
89              
90             =cut
91             #line 92 "EditDistance.pm"
92              
93              
94             =head1 FUNCTIONS
95              
96             =cut
97              
98              
99              
100              
101              
102             #line 124 "EditDistance.pd"
103              
104             =pod
105              
106             =head2 _edit_pdl
107              
108             =for sig
109              
110             Signature: (a(N); [o]apdl(N+1))
111              
112             Convenience method.
113             Returns a pdl $apdl() suitable for representing $a(),
114             which can be specified as a UTF-8 or byte-string, as an arrays of numbers, or as a PDL.
115             $apdl(0) is always set to zero.
116              
117             =cut
118              
119             sub _edit_pdl {
120             if (UNIVERSAL::isa($_[0],'PDL')) {
121             return ($PDL_ATLEAST_2_014 ? $_[0]->pdl : $_[0])->flat->reshape($_[0]->nelem+1)->rotate(1);
122             }
123             #return pdl(byte,[0, map { ord($_) } split(//,$_[0])]) if (!ref($_[0]) && !utf8::is_utf8($_[0])); ##-- byte-string (old)
124             elsif (!ref($_[0])) {
125             return pdl(long,[0, unpack('C0C*',$_[0])]) if (utf8::is_utf8($_[0])); ##-- utf8-string
126             return pdl(byte,[0, unpack('U0C*',$_[0])]); ##-- byte-string
127             }
128             return pdl([0,@{$_[0]}]);
129             }
130              
131             #line 159 "EditDistance.pd"
132              
133             =pod
134              
135             =head2 edit_costs
136              
137             =for sig
138              
139             Signature: (PDL::Type type; int N; int M;
140             [o]costsMatch(N+1,M+1); [o]costsIns(N+1,M+1); [o]costsDel(N+1,M+1); [o]costsSubst(N+1,M+1))
141              
142             Convenience method.
143             Ensures existence and proper dimensionality of cost matrices for inputs
144             of length N and M.
145              
146             =cut
147              
148             sub edit_costs {
149             return _edit_costs($_[0],$_[1]+1,$_[2]+1,@_[3..$#_]);
150             }
151              
152             #line 187 "EditDistance.pd"
153              
154             =pod
155              
156             =head2 _edit_costs
157              
158             =for sig
159              
160             Signature: (PDL::Type type; int N1; int M1;
161             [o]costsMatch(N1,M1); [o]costsIns(N1,M1); [o]costsDel(N1,M1); [o]costsSubst(N1,M1))
162              
163             Low-level method.
164             Ensures existence and proper dimensionality of cost matrices for inputs
165             of length N1-1 and M1-1.
166              
167             =cut
168              
169             sub _edit_costs {
170             #my ($type,$n1,$m1,$costsMatch,$costsIns,$costsDel,$costsSubst) = @_;
171             return (_edit_matrix(@_[0..2],$_[3]),
172             _edit_matrix(@_[0..2],$_[4]),
173             _edit_matrix(@_[0..2],$_[5]),
174             _edit_matrix(@_[0..2],$_[6]));
175             }
176              
177             ##-- $matrix = _edit_matrix($type,$dim0,$dim1,$mat)
178             sub _edit_matrix {
179             return zeroes(@_[0..2]) if (!defined($_[3]));
180             $_[3]->reshape(@_[1,2]) if ($_[3]->ndims != 2 || $_[3]->dim(0) != $_[1] || $_[3]->dim(1) != $_[2]);
181             return $_[3]->type == $_[0] ? $_[3] : $_[3]->convert($_[0]);
182             }
183              
184             #line 226 "EditDistance.pd"
185              
186             =pod
187              
188             =head2 edit_costs_static
189              
190             =for sig
191              
192             Signature: (PDL::Type type; int N; int M;
193             staticCostMatch(); staticCostIns(); staticCostSubst();
194             [o]costsMatch(N+1,M+1); [o]costsIns(N+1,M+1); [o]costsDel(N+1,M+1); [o]costsSubst(N+1,M+1))
195              
196             Convenience method.
197              
198             =cut
199              
200             sub edit_costs_static {
201             #my ($type,$n,$m, $cMatch,$cIns,$cDel,$cSubst, $costsMatch,$costsIns,$costsDel,$costsSubst) = @_;
202             my @costs = edit_costs(@_[0..2],@_[7..$#_]);
203             $costs[$_] .= $_[$_+3] foreach (0..3);
204             return @costs;
205             }
206              
207             #line 258 "EditDistance.pd"
208              
209             =pod
210              
211             =head2 edit_distance_full
212              
213             =for sig
214              
215             Signature: (a(N); b(M);
216             costsMatch(N+1,M+1); costsIns(N+1,M+1); costsDel(N+1,M+1); costsSubst(N+1,M+1);
217             [o]dist(N+1,M+1); [o]align(N+1,M+1))
218              
219             Convenience method.
220             Compute the edit distance matrix for inputs $a() and $b(), and
221             cost matrices $costsMatch(), $costsIns(), $costsDel(), and $costsSubst().
222             $a() and $b() may be specified as PDLs, arrays of numbers, or as strings.
223              
224             =cut
225              
226             sub edit_distance_full {
227             return _edit_distance_full(_edit_pdl($_[0]), _edit_pdl($_[1]), @_[2..$#_]);
228             }
229             #line 230 "EditDistance.pm"
230              
231              
232             =head2 _edit_distance_full
233              
234             =for sig
235              
236             Signature: (a1(N1); b1(M1); costsMatch(N1,M1); costsIns(N1,M1); costsDel(N1,M1); costsSubst(N1,M1); [o]dist(N1,M1))
237             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
238             float double ldouble)
239              
240             =for usage
241              
242             $dist = _edit_distance_full($a1, $b1, $costsMatch, $costsIns, $costsDel, $costsSubst);
243             _edit_distance_full($a1, $b1, $costsMatch, $costsIns, $costsDel, $costsSubst, $dist); # all arguments given
244             $dist = $a1->_edit_distance_full($b1, $costsMatch, $costsIns, $costsDel, $costsSubst); # method call
245             $a1->_edit_distance_full($b1, $costsMatch, $costsIns, $costsDel, $costsSubst, $dist);
246              
247             Low-level method.
248             Compute the edit distance matrix for input PDLs $a1() and $b1() and
249             cost matrices $costsMatch(), $costsIns(), $costsDel(), and $costsSubst().
250              
251             The first elements of $a1() and $b1() are ignored.
252              
253             =pod
254              
255             Broadcasts over its inputs.
256              
257             =for bad
258              
259             C<_edit_distance_full> does not process bad values.
260             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
261              
262             =cut
263              
264              
265              
266              
267             *_edit_distance_full = \&PDL::_edit_distance_full;
268              
269              
270              
271              
272              
273             #line 349 "EditDistance.pd"
274              
275             =pod
276              
277             =head2 edit_align_full
278              
279             =for sig
280              
281             Signature: (a(N); b(M);
282             costsMatch(N+1,M+1); costsIns(N+1,M+1); costsDel(N+1,N+1); costsSubst(N+1,M+1);
283             [o]dist(N+1,M+1); [o]align(N+1,M+1))
284              
285             Convenience method.
286             Compute the edit distance and alignment matrices for inputs $a() and $b(), and
287             cost matrices $costsMatch(), $costsIns(), $costsDel(), and $costsSubst().
288             $a() and $b() may be specified as PDLs, arrays of numbers, or as strings.
289              
290             =cut
291              
292             sub edit_align_full {
293             return _edit_align_full(_edit_pdl($_[0]), _edit_pdl($_[1]), @_[2..$#_]);
294             }
295             #line 296 "EditDistance.pm"
296              
297              
298             =head2 _edit_align_full
299              
300             =for sig
301              
302             Signature: (a1(N1); b1(M1); costsMatch(N1,M1); costsIns(N1,M1); costsDel(N1,M1); costsSubst(N1,M1); [o]dist(N1,M1); byte [o]align(N1,M1))
303             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
304             float double ldouble)
305              
306             =for usage
307              
308             ($dist, $align) = _edit_align_full($a1, $b1, $costsMatch, $costsIns, $costsDel, $costsSubst);
309             _edit_align_full($a1, $b1, $costsMatch, $costsIns, $costsDel, $costsSubst, $dist, $align); # all arguments given
310             ($dist, $align) = $a1->_edit_align_full($b1, $costsMatch, $costsIns, $costsDel, $costsSubst); # method call
311             $a1->_edit_align_full($b1, $costsMatch, $costsIns, $costsDel, $costsSubst, $dist, $align);
312              
313             Low-level method.
314             Compute the edit distance and alignment matrix for input PDLs $a1() and $b1() and
315             cost matrices $costsMatch(), $costsIns(), $costsDel(), and $costsSubst().
316              
317             The first elements of $a1() and $b1() are ignored.
318              
319             =pod
320              
321             Broadcasts over its inputs.
322              
323             =for bad
324              
325             C<_edit_align_full> does not process bad values.
326             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
327              
328             =cut
329              
330              
331              
332              
333             *_edit_align_full = \&PDL::_edit_align_full;
334              
335              
336              
337              
338              
339             #line 451 "EditDistance.pd"
340              
341             =pod
342              
343             =head2 edit_distance_static
344              
345             =for sig
346              
347             Signature: (a(N); b(M);
348             staticCostMatch(); staticCostIns(); staticCostDel(); staticCostSubst();
349             [o]dist(N+1,M+1))
350              
351             Convenience method.
352             Compute the edit distance matrix for inputs $a() and $b() given
353             a static cost schema @costs = ($staticCostMatch(), $staticCostIns(), $staticCostDel(), and $staticCostSubst()).
354             $a() and $b() may be specified as PDLs, arrays of numbers, or as strings.
355             Functionally equivalent to edit_distance_full($matches,@costs,$dist),
356             but slightly faster.
357              
358             =cut
359              
360             sub edit_distance_static {
361             return _edit_distance_static(_edit_pdl($_[0]), _edit_pdl($_[1]), @_[2..$#_]);
362             }
363             #line 364 "EditDistance.pm"
364              
365              
366             =head2 _edit_distance_static
367              
368             =for sig
369              
370             Signature: (a1(N1); b1(M1); costMatch(); costIns(); costDel(); costSubst(); [o]dist(N1,M1))
371             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
372             float double ldouble)
373              
374             =for usage
375              
376             $dist = _edit_distance_static($a1, $b1, $costMatch, $costIns, $costDel, $costSubst);
377             _edit_distance_static($a1, $b1, $costMatch, $costIns, $costDel, $costSubst, $dist); # all arguments given
378             $dist = $a1->_edit_distance_static($b1, $costMatch, $costIns, $costDel, $costSubst); # method call
379             $a1->_edit_distance_static($b1, $costMatch, $costIns, $costDel, $costSubst, $dist);
380              
381             Low-level method.
382             Compute the edit distance matrix for input PDLs $a1() and $b1() given a
383             static cost schema @costs = ($costMatch(), $costIns(), $costDel(), $costSubst()).
384             Functionally identitical to _edit_distance_matrix_full($matches,@costs,$dist),
385             but slightly faster.
386              
387             The first elements of $a1() and $b1() are ignored.
388              
389             =pod
390              
391             Broadcasts over its inputs.
392              
393             =for bad
394              
395             C<_edit_distance_static> does not process bad values.
396             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
397              
398             =cut
399              
400              
401              
402              
403             *_edit_distance_static = \&PDL::_edit_distance_static;
404              
405              
406              
407              
408              
409             #line 540 "EditDistance.pd"
410              
411             =pod
412              
413             =head2 edit_align_static
414              
415             =for sig
416              
417             Signature: (a(N); b(M);
418             staticCostMatch(); staticCostIns(); staticCostDel(); staticCostSubst();
419             [o]dist(N+1,M+1); [o]align(N+1,M+1))
420              
421             Convenience method.
422             Compute the edit distance and alignment matrices for inputs $a() and $b() given
423             a static cost schema @costs = ($staticCostMatch(), $staticCostIns(), $staticCostDel(), and $staticCostSubst()).
424             $a() and $b() may be specified as PDLs, arrays of numbers, or as strings.
425             Functionally equivalent to edit_align_full($matches,@costs,$dist),
426             but slightly faster.
427              
428             =cut
429              
430             sub edit_align_static {
431             return _edit_align_static(_edit_pdl($_[0]), _edit_pdl($_[1]), @_[2..$#_]);
432             }
433             #line 434 "EditDistance.pm"
434              
435              
436             =head2 _edit_align_static
437              
438             =for sig
439              
440             Signature: (a1(N1); b1(M1); costMatch(); costIns(); costDel(); costSubst(); [o]dist(N1,M1); byte [o]align(N1,M1))
441             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
442             float double ldouble)
443              
444             =for usage
445              
446             ($dist, $align) = _edit_align_static($a1, $b1, $costMatch, $costIns, $costDel, $costSubst);
447             _edit_align_static($a1, $b1, $costMatch, $costIns, $costDel, $costSubst, $dist, $align); # all arguments given
448             ($dist, $align) = $a1->_edit_align_static($b1, $costMatch, $costIns, $costDel, $costSubst); # method call
449             $a1->_edit_align_static($b1, $costMatch, $costIns, $costDel, $costSubst, $dist, $align);
450              
451             Low-level method.
452             Compute the edit distance and alignment matrices for input PDLs $a1() and $b1() given a
453             static cost schema @costs = ($costMatch(), $costIns(), $costDel(), $costSubst()).
454             Functionally identitical to _edit_distance_matrix_full($matches,@costs,$dist),
455             but slightly faster.
456              
457             The first elements of $a1() and $b1() are ignored.
458              
459             =pod
460              
461             Broadcasts over its inputs.
462              
463             =for bad
464              
465             C<_edit_align_static> does not process bad values.
466             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
467              
468             =cut
469              
470              
471              
472              
473             *_edit_align_static = \&PDL::_edit_align_static;
474              
475              
476              
477              
478              
479              
480             =head2 align_op_insert1
481              
482             =for sig
483              
484             Signature: ([o]a())
485             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
486             float double ldouble)
487              
488             =for usage
489              
490             $a = align_op_insert1();
491             align_op_insert1($a); # all arguments given
492             $a->align_op_insert1;
493              
494             =for ref
495              
496             Alignment matrix value constant for insertion operations on $a() string.
497              
498             =pod
499              
500             Broadcasts over its inputs.
501              
502             =for bad
503              
504             C does not process bad values.
505             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
506              
507             =cut
508              
509              
510              
511              
512             *align_op_insert1 = \&PDL::align_op_insert1;
513              
514              
515              
516              
517              
518              
519             =head2 align_op_insert2
520              
521             =for sig
522              
523             Signature: ([o]a())
524             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
525             float double ldouble)
526              
527             =for usage
528              
529             $a = align_op_insert2();
530             align_op_insert2($a); # all arguments given
531             $a->align_op_insert2;
532              
533             =for ref
534              
535             Alignment matrix value constant for insertion operations on $a() string.
536              
537             =pod
538              
539             Broadcasts over its inputs.
540              
541             =for bad
542              
543             C does not process bad values.
544             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
545              
546             =cut
547              
548              
549              
550              
551             *align_op_insert2 = \&PDL::align_op_insert2;
552              
553              
554              
555              
556              
557              
558             =head2 align_op_match
559              
560             =for sig
561              
562             Signature: ([o]a())
563             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
564             float double ldouble)
565              
566             =for usage
567              
568             $a = align_op_match();
569             align_op_match($a); # all arguments given
570             $a->align_op_match;
571              
572             =for ref
573              
574             Alignment matrix value constant for matches.
575              
576             =pod
577              
578             Broadcasts over its inputs.
579              
580             =for bad
581              
582             C does not process bad values.
583             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
584              
585             =cut
586              
587              
588              
589              
590             *align_op_match = \&PDL::align_op_match;
591              
592              
593              
594              
595              
596              
597             =head2 align_op_substitute
598              
599             =for sig
600              
601             Signature: ([o]a())
602             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
603             float double ldouble)
604              
605             =for usage
606              
607             $a = align_op_substitute();
608             align_op_substitute($a); # all arguments given
609             $a->align_op_substitute;
610              
611             =for ref
612              
613             Alignment matrix value constant for substitution operations.
614              
615             =pod
616              
617             Broadcasts over its inputs.
618              
619             =for bad
620              
621             C does not process bad values.
622             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
623              
624             =cut
625              
626              
627              
628              
629             *align_op_substitute = \&PDL::align_op_substitute;
630              
631              
632              
633              
634              
635             #line 672 "EditDistance.pd"
636              
637             =pod
638              
639             =head2 align_op_delete
640              
641             Alias for align_op_insert1()
642              
643             =head2 align_op_insert
644              
645             Alias for align_op_insert2()
646              
647             =cut
648              
649             *align_op_delete = \&align_op_insert1;
650             *align_op_insert = \&align_op_insert2;
651              
652             #line 693 "EditDistance.pd"
653              
654             =pod
655              
656             =head2 align_ops
657              
658             =for sig
659              
660             Signature: ([o]ops(4))
661              
662             Alignment matrix value constants 4-element pdl (match,insert1,insert2,substitute).a
663              
664             =cut
665              
666             sub align_ops { return PDL->sequence(PDL::byte(),4); }
667              
668             #line 716 "EditDistance.pd"
669              
670             =pod
671              
672             =head2 edit_bestpath
673              
674             =for sig
675              
676             Signature: (align(N+1,M+1); [o]apath(N+M+2); [o]bpath(N+M+2); [o]pathlen())
677              
678             Convenience method.
679             Compute best path through alignment matrix $align().
680             Stores paths for original input strings $a() and $b() in $apath() and $bpath()
681             respectively.
682             Negative values in $apath() and $bpath() indicate insertion/deletion operations.
683             On completion, $pathlen() holds the actual length of the paths.
684              
685             =cut
686              
687             sub edit_bestpath {
688             my ($align,$apath,$bpath,$len) = @_;
689             $len=pdl(long,$align->dim(0)+$align->dim(1)) if (!defined($len));
690             if (!defined($apath)) { $apath=zeroes(long,$len); }
691             else { $apath->reshape($len) if ($apath->nelem < $len); }
692             if (!defined($bpath)) { $bpath = zeroes(long,$len); }
693             else { $bpath->reshape($len) if ($bpath->nelem < $len); }
694             _edit_bestpath($align, $apath, $bpath, $len, $align->dim(0)-1, $align->dim(1)-1);
695             return ($apath,$bpath,$len);
696             }
697             #line 698 "EditDistance.pm"
698              
699              
700             =head2 _edit_bestpath
701              
702             =for sig
703              
704             Signature: (align(N1,M1); int [o]apath(L); int [o]bpath(L); int [o]len(); int ifinal; int jfinal)
705             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
706             float double ldouble)
707              
708             =for usage
709              
710             ($apath, $bpath, $len) = _edit_bestpath($align, $ifinal, $jfinal);
711             _edit_bestpath($align, $apath, $bpath, $len, $ifinal, $jfinal); # all arguments given
712             ($apath, $bpath, $len) = $align->_edit_bestpath($ifinal, $jfinal); # method call
713             $align->_edit_bestpath($apath, $bpath, $len, $ifinal, $jfinal);
714              
715             Low-level method.
716             Compute best path through alignment matrix $align() from final index ($ifinal,$jfinal).
717             Stores paths for (original) input strings $a() and $b() in $apath() and $bpath()
718             respectively.
719             Negative values in $apath() and $bpath() indicate insertion/deletion operations.
720             On completion, $pathlen() holds the actual length of the paths.
721              
722             =pod
723              
724             Broadcasts over its inputs.
725              
726             =for bad
727              
728             C<_edit_bestpath> does not process bad values.
729             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
730              
731             =cut
732              
733              
734              
735              
736             *_edit_bestpath = \&PDL::_edit_bestpath;
737              
738              
739              
740              
741              
742             #line 811 "EditDistance.pd"
743              
744             =pod
745              
746             =head2 edit_pathtrace
747              
748             =for sig
749              
750             Signature: ( align(N+1,M+1); [o]ai(L); [o]bi(L); [o]ops(L); [o]$pathlen() )
751              
752             Convenience method.
753             Compute alignment path backtrace through alignment matrix $align() from final index ($ifinal,$jfinal).
754             Stores raw paths for (original) input strings $a() and $b() in $ai() and $bi()
755             respectively.
756             Unlike edit_bestpath(), null-moves for $ai() and $bi() are not stored here as negative values.
757             Returned pdls ($ai,$bi,$ops) are trimmed to the appropriate path length.
758              
759             =cut
760              
761             sub edit_pathtrace {
762             my ($align,$ai,$bi,$ops,$len) = @_;
763             $len=pdl(long,$align->dim(0)+$align->dim(1)) if (!defined($len));
764             if (!defined($ai)) { $ai=zeroes(long,$len); }
765             else { $ai->reshape($len) if ($ai->nelem < $len); }
766             if (!defined($bi)) { $bi = zeroes(long,$len); }
767             else { $bi->reshape($len) if ($bi->nelem < $len); }
768             if (!defined($ops)) { $ops = zeroes(long,$len); }
769             else { $ops->reshape($len) if ($ops->nelem < $len); }
770             _edit_pathtrace($align, $ai,$bi,$ops,$len, $align->dim(0)-1,$align->dim(1)-1);
771             my $lens = ($len->sclr-1);
772             return ((map { $_->slice("0:$lens") } ($ai,$bi,$ops)), $len);
773             }
774             #line 775 "EditDistance.pm"
775              
776              
777             =head2 _edit_pathtrace
778              
779             =for sig
780              
781             Signature: (align(N1,M1); int [o]ai(L); int [o]bi(L); int [o]ops(L); int [o]len(); int ifinal; int jfinal)
782             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
783             float double ldouble)
784              
785             =for usage
786              
787             ($ai, $bi, $ops, $len) = _edit_pathtrace($align, $ifinal, $jfinal);
788             _edit_pathtrace($align, $ai, $bi, $ops, $len, $ifinal, $jfinal); # all arguments given
789             ($ai, $bi, $ops, $len) = $align->_edit_pathtrace($ifinal, $jfinal); # method call
790             $align->_edit_pathtrace($ai, $bi, $ops, $len, $ifinal, $jfinal);
791              
792             Low-level method.
793             Compute alignment path backtrace through alignment matrix $align() from final index ($ifinal,$jfinal).
794             Stores raw paths for (original) input strings $a() and $b() in $ai() and $bi()
795             respectively.
796             Unlike edit_bestpath(), null-moves for $ai() and $bi() are not stored here as negative values.
797             Returned pdls ($ai,$bi,$ops) are trimmed to the appropriate path length.
798              
799             =pod
800              
801             Broadcasts over its inputs.
802              
803             =for bad
804              
805             C<_edit_pathtrace> does not process bad values.
806             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
807              
808             =cut
809              
810              
811              
812              
813             *_edit_pathtrace = \&PDL::_edit_pathtrace;
814              
815              
816              
817              
818              
819             #line 905 "EditDistance.pd"
820              
821             =pod
822              
823             =head2 edit_lcs
824              
825             =for sig
826              
827             Signature: (a(N); b(M); int [o]lcs(N+1,M+1);)
828              
829             Convenience method.
830             Compute the longest common subsequence (LCS) matrix for input PDLs $a1() and $b1().
831             The output matrix $lcs() contains at cell ($i+1,$j+1) the length of the LCS
832             between $a1(0..$i) and $b1(0..$j); thus $lcs($N,$M) contains the
833             length of the LCS between $a() and $b().
834              
835             =cut
836              
837             sub edit_lcs {
838             return _edit_lcs(_edit_pdl($_[0]), _edit_pdl($_[1]), @_[2..$#_]);
839             }
840             #line 841 "EditDistance.pm"
841              
842              
843             =head2 _edit_lcs
844              
845             =for sig
846              
847             Signature: (a1(N1); b1(M1); int [o]lcs(N1,M1))
848             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
849             float double ldouble)
850              
851             =for usage
852              
853             $lcs = _edit_lcs($a1, $b1);
854             _edit_lcs($a1, $b1, $lcs); # all arguments given
855             $lcs = $a1->_edit_lcs($b1); # method call
856             $a1->_edit_lcs($b1, $lcs);
857              
858             Low-level method.
859             Compute the longest common subsequence (LCS) matrix for input PDLs $a1() and $b1().
860             The initial (zeroth) elements of $a1() and $b1() are ignored.
861             The output matrix $lcs() contains at cell ($i,$j) the length of the LCS
862             between $a1(1..$i) and $b1(1..$j); thus $lcs($N1-1,$M1-1) contains the
863             length of the LCS between $a1() and $b1().
864              
865             =pod
866              
867             Broadcasts over its inputs.
868              
869             =for bad
870              
871             C<_edit_lcs> does not process bad values.
872             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
873              
874             =cut
875              
876              
877              
878              
879             *_edit_lcs = \&PDL::_edit_lcs;
880              
881              
882              
883              
884              
885             #line 970 "EditDistance.pd"
886              
887             =pod
888              
889             =head2 lcs_backtrace
890              
891             =for sig
892              
893             Signature: (a(N); b(M); int lcs(N+1,M+1); int ifinal(); int jfinal(); int [o]ai(L); int [o]bi(L); int [o]len())
894              
895             Convenience method.
896             Compute longest-common-subsequence backtrace through LCS matrix $lcs()
897             for original input strings ($a(),$b()) from final index ($ifinal,$jfinal).
898             Stores raw paths for (original) input strings $a() and $b() in $ai() and $bi()
899             respectively.
900              
901             =cut
902              
903             sub lcs_backtrace {
904             my ($a,$b,$lcs,$ifinal,$jfinal,$ai,$bi,$len) = @_;
905             $len=pdl(long, pdl(long,$lcs->dims)->min) if (!defined($len));
906             if (!defined($ai)) { $ai=zeroes(long,$len); }
907             else { $ai->reshape($len) if ($ai->nelem < $len); }
908             if (!defined($bi)) { $bi = zeroes(long,$len); }
909             else { $bi->reshape($len) if ($bi->nelem < $len); }
910             if (!defined($ifinal)) { $ifinal = $lcs->dim(0)-1; }
911             if (!defined($jfinal)) { $jfinal = $lcs->dim(1)-1; }
912             _lcs_backtrace(_edit_pdl($a),_edit_pdl($b), $lcs,$ifinal,$jfinal, $ai,$bi,$len);
913             my $lens = ($len->sclr-1);
914             return ($ai->slice("0:$lens"),$bi->slice("0:$lens"), $len);
915             }
916             #line 917 "EditDistance.pm"
917              
918              
919             =head2 _lcs_backtrace
920              
921             =for sig
922              
923             Signature: (a1(N1); b1(M1); int lcs(N1,M1); int ifinal(); int jfinal(); [o]ai(L); [o]bi(L); int [o]len())
924             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
925             float double ldouble)
926              
927             =for usage
928              
929             ($ai, $bi, $len) = _lcs_backtrace($a1, $b1, $lcs, $ifinal, $jfinal);
930             _lcs_backtrace($a1, $b1, $lcs, $ifinal, $jfinal, $ai, $bi, $len); # all arguments given
931             ($ai, $bi, $len) = $a1->_lcs_backtrace($b1, $lcs, $ifinal, $jfinal); # method call
932             $a1->_lcs_backtrace($b1, $lcs, $ifinal, $jfinal, $ai, $bi, $len);
933              
934             Low-level method.
935             Compute longest-common-subsequence backtrace through LCS matrix $lcs()
936             for initial-padded strings ($a1(),$b1()) from final index ($ifinal,$jfinal).
937             Stores raw paths for (original) input strings $a() and $b() in $ai() and $bi()
938             respectively.
939              
940             =pod
941              
942             Broadcasts over its inputs.
943              
944             =for bad
945              
946             C<_lcs_backtrace> does not process bad values.
947             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
948              
949             =cut
950              
951              
952              
953              
954             *_lcs_backtrace = \&PDL::_lcs_backtrace;
955              
956              
957              
958              
959              
960             #line 1063 "EditDistance.pd"
961              
962             ##---------------------------------------------------------------------
963             =pod
964              
965             =head1 ACKNOWLEDGEMENTS
966              
967             Perl by Larry Wall.
968              
969             PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others.
970              
971             =cut
972              
973             ##----------------------------------------------------------------------
974             =pod
975              
976             =head1 KNOWN BUGS
977              
978             Probably many.
979              
980             =cut
981              
982             ##---------------------------------------------------------------------
983             =pod
984              
985             =head1 AUTHOR
986              
987             Bryan Jurish Emoocow@cpan.orgE
988              
989             =head2 Copyright Policy
990              
991             Copyright (C) 2006-2015, Bryan Jurish. All rights reserved.
992              
993             This package is free software, and entirely without warranty.
994             You may redistribute it and/or modify it under the same terms
995             as Perl itself, either Perl 5.20.2, or at your option any later
996             version of Perl 5.
997              
998             =head1 SEE ALSO
999              
1000             perl(1), PDL(3perl).
1001              
1002             =cut
1003             #line 1004 "EditDistance.pm"
1004              
1005             # Exit with OK status
1006              
1007             1;