File Coverage

blib/lib/Statistics/Cluto.pm
Criterion Covered Total %
statement 25 276 9.0
branch 2 60 3.3
condition 0 136 0.0
subroutine 8 43 18.6
pod n/a
total 35 515 6.8


line stmt bran cond sub pod time code
1             package Statistics::Cluto;
2              
3 1     1   27974 use 5.008005;
  1         3  
  1         36  
4 1     1   5 use strict;
  1         1  
  1         31  
5 1     1   5 use warnings;
  1         6  
  1         44  
6 1     1   5 use Carp;
  1         1  
  1         91  
7              
8             require Exporter;
9 1     1   1912 use AutoLoader;
  1         1584  
  1         5  
10              
11             our @ISA = qw(Exporter);
12              
13             # Items to export into callers namespace by default. Note: do not export
14             # names by default without a very good reason. Use EXPORT_OK instead.
15             # Do not simply export all your public functions/methods/constants.
16              
17             # This allows declaration use Statistics::Cluto ':all';
18             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
19             # will save memory.
20             our %EXPORT_TAGS = ( 'all' => [ qw(
21             CLUTO_CLFUN_CLINK
22             CLUTO_CLFUN_CLINK_W
23             CLUTO_CLFUN_CUT
24             CLUTO_CLFUN_E1
25             CLUTO_CLFUN_G1
26             CLUTO_CLFUN_G1P
27             CLUTO_CLFUN_H1
28             CLUTO_CLFUN_H2
29             CLUTO_CLFUN_I1
30             CLUTO_CLFUN_I2
31             CLUTO_CLFUN_MMCUT
32             CLUTO_CLFUN_NCUT
33             CLUTO_CLFUN_RCUT
34             CLUTO_CLFUN_SLINK
35             CLUTO_CLFUN_SLINK_W
36             CLUTO_CLFUN_UPGMA
37             CLUTO_CLFUN_UPGMA_W
38             CLUTO_COLMODEL_IDF
39             CLUTO_COLMODEL_NONE
40             CLUTO_CSTYPE_BESTFIRST
41             CLUTO_CSTYPE_LARGEFIRST
42             CLUTO_CSTYPE_LARGESUBSPACEFIRST
43             CLUTO_DBG_APROGRESS
44             CLUTO_DBG_CCMPSTAT
45             CLUTO_DBG_CPROGRESS
46             CLUTO_DBG_MPROGRESS
47             CLUTO_DBG_PROGRESS
48             CLUTO_DBG_RPROGRESS
49             CLUTO_GRMODEL_ASYMETRIC_DIRECT
50             CLUTO_GRMODEL_ASYMETRIC_LINKS
51             CLUTO_GRMODEL_EXACT_ASYMETRIC_DIRECT
52             CLUTO_GRMODEL_EXACT_ASYMETRIC_LINKS
53             CLUTO_GRMODEL_EXACT_SYMETRIC_DIRECT
54             CLUTO_GRMODEL_EXACT_SYMETRIC_LINKS
55             CLUTO_GRMODEL_INEXACT_ASYMETRIC_DIRECT
56             CLUTO_GRMODEL_INEXACT_ASYMETRIC_LINKS
57             CLUTO_GRMODEL_INEXACT_SYMETRIC_DIRECT
58             CLUTO_GRMODEL_INEXACT_SYMETRIC_LINKS
59             CLUTO_GRMODEL_NONE
60             CLUTO_GRMODEL_SYMETRIC_DIRECT
61             CLUTO_GRMODEL_SYMETRIC_LINKS
62             CLUTO_MEM_NOREUSE
63             CLUTO_MEM_REUSE
64             CLUTO_MTYPE_HEDGE
65             CLUTO_MTYPE_HSTAR
66             CLUTO_MTYPE_HSTAR2
67             CLUTO_OPTIMIZER_MULTILEVEL
68             CLUTO_OPTIMIZER_SINGLELEVEL
69             CLUTO_ROWMODEL_LOG
70             CLUTO_ROWMODEL_MAXTF
71             CLUTO_ROWMODEL_NONE
72             CLUTO_ROWMODEL_SQRT
73             CLUTO_SIM_CORRCOEF
74             CLUTO_SIM_COSINE
75             CLUTO_SIM_EDISTANCE
76             CLUTO_SIM_EJACCARD
77             CLUTO_SUMMTYPE_MAXCLIQUES
78             CLUTO_SUMMTYPE_MAXITEMSETS
79             CLUTO_TREE_FULL
80             CLUTO_TREE_TOP
81             CLUTO_VER_MAJOR
82             CLUTO_VER_MINOR
83             CLUTO_VER_SUBMINOR
84             ) ] );
85              
86             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
87              
88             our @EXPORT = qw(
89             CLUTO_CLFUN_CLINK
90             CLUTO_CLFUN_CLINK_W
91             CLUTO_CLFUN_CUT
92             CLUTO_CLFUN_E1
93             CLUTO_CLFUN_G1
94             CLUTO_CLFUN_G1P
95             CLUTO_CLFUN_H1
96             CLUTO_CLFUN_H2
97             CLUTO_CLFUN_I1
98             CLUTO_CLFUN_I2
99             CLUTO_CLFUN_MMCUT
100             CLUTO_CLFUN_NCUT
101             CLUTO_CLFUN_RCUT
102             CLUTO_CLFUN_SLINK
103             CLUTO_CLFUN_SLINK_W
104             CLUTO_CLFUN_UPGMA
105             CLUTO_CLFUN_UPGMA_W
106             CLUTO_COLMODEL_IDF
107             CLUTO_COLMODEL_NONE
108             CLUTO_CSTYPE_BESTFIRST
109             CLUTO_CSTYPE_LARGEFIRST
110             CLUTO_CSTYPE_LARGESUBSPACEFIRST
111             CLUTO_DBG_APROGRESS
112             CLUTO_DBG_CCMPSTAT
113             CLUTO_DBG_CPROGRESS
114             CLUTO_DBG_MPROGRESS
115             CLUTO_DBG_PROGRESS
116             CLUTO_DBG_RPROGRESS
117             CLUTO_GRMODEL_ASYMETRIC_DIRECT
118             CLUTO_GRMODEL_ASYMETRIC_LINKS
119             CLUTO_GRMODEL_EXACT_ASYMETRIC_DIRECT
120             CLUTO_GRMODEL_EXACT_ASYMETRIC_LINKS
121             CLUTO_GRMODEL_EXACT_SYMETRIC_DIRECT
122             CLUTO_GRMODEL_EXACT_SYMETRIC_LINKS
123             CLUTO_GRMODEL_INEXACT_ASYMETRIC_DIRECT
124             CLUTO_GRMODEL_INEXACT_ASYMETRIC_LINKS
125             CLUTO_GRMODEL_INEXACT_SYMETRIC_DIRECT
126             CLUTO_GRMODEL_INEXACT_SYMETRIC_LINKS
127             CLUTO_GRMODEL_NONE
128             CLUTO_GRMODEL_SYMETRIC_DIRECT
129             CLUTO_GRMODEL_SYMETRIC_LINKS
130             CLUTO_MEM_NOREUSE
131             CLUTO_MEM_REUSE
132             CLUTO_MTYPE_HEDGE
133             CLUTO_MTYPE_HSTAR
134             CLUTO_MTYPE_HSTAR2
135             CLUTO_OPTIMIZER_MULTILEVEL
136             CLUTO_OPTIMIZER_SINGLELEVEL
137             CLUTO_ROWMODEL_LOG
138             CLUTO_ROWMODEL_MAXTF
139             CLUTO_ROWMODEL_NONE
140             CLUTO_ROWMODEL_SQRT
141             CLUTO_SIM_CORRCOEF
142             CLUTO_SIM_COSINE
143             CLUTO_SIM_EDISTANCE
144             CLUTO_SIM_EJACCARD
145             CLUTO_SUMMTYPE_MAXCLIQUES
146             CLUTO_SUMMTYPE_MAXITEMSETS
147             CLUTO_TREE_FULL
148             CLUTO_TREE_TOP
149             CLUTO_VER_MAJOR
150             CLUTO_VER_MINOR
151             CLUTO_VER_SUBMINOR
152             );
153              
154             our $VERSION = '0.01';
155              
156             sub AUTOLOAD {
157             # This AUTOLOAD is used to 'autoload' constants from the constant()
158             # XS function.
159              
160 2     2   3 my $constname;
161 2         2 our $AUTOLOAD;
162 2         9 ($constname = $AUTOLOAD) =~ s/.*:://;
163 2 100       334 croak "&Statistics::Cluto::constant not defined" if $constname eq 'constant';
164 1         5 my ($error, $val) = constant($constname);
165 0 0       0 if ($error) { croak $error; }
  0         0  
166             {
167 1     1   283 no strict 'refs';
  1         2  
  1         4988  
  0         0  
168             # Fixed between 5.005_53 and 5.005_61
169             #XXX if ($] >= 5.00561) {
170             #XXX *$AUTOLOAD = sub () { $val };
171             #XXX }
172             #XXX else {
173 0     0   0 *$AUTOLOAD = sub { $val };
  0         0  
174             #XXX }
175             }
176 0         0 goto &$AUTOLOAD;
177             }
178              
179 0     0   0 sub DESTROY {}
180              
181             require XSLoader;
182             XSLoader::load('Statistics::Cluto', $VERSION);
183              
184             # Preloaded methods go here.
185              
186             our $MATRIX_TYPE_DENSE = 0;
187             our $MATRIX_TYPE_SPARSE = 1;
188              
189             our $NO_OPTIMIZE_SOLUTION = 0;
190             our $OPTIMIZE_SOLUTION = 1;
191              
192             sub new {
193 1     1   2900 my $class = shift;
194 1         9 my $self = {
195             nrows => 0,
196             ncols => 0,
197             nnz => 0,
198             rowptr => [],
199             rowind => [],
200             rowval => [],
201              
202             # global (not method-specific) defaults
203             simfun => CLUTO_SIM_COSINE(),
204             cstype => CLUTO_CSTYPE_BESTFIRST(),
205             rowmodel => CLUTO_ROWMODEL_NONE(),
206             colprune => 1.0,
207             nnbrs => 40,
208             grmodel => CLUTO_GRMODEL_EXACT_SYMETRIC_DIRECT(),
209             edgeprune => -1,
210             vtxprune => -1,
211             mincomponent => 5,
212             kwayrefine => $NO_OPTIMIZE_SOLUTION,
213             ntrials => 10,
214             niter => 10,
215             seed => time,
216             dbglvl => 0,
217             nclusters => 1,
218             nfeatures => 5,
219              
220             pretty_format => 0,
221              
222             @_,
223             };
224              
225 0           bless $self, $class;
226 0           return $self;
227             }
228              
229             sub set_options {
230 0     0     my ($self, $opts) = @_;
231              
232 0           while (my ($key, $val) = each(%$opts)) {
233 0           $self->{$key} = $val;
234             }
235             }
236              
237             #
238             # matrix loading functions
239             #
240              
241             sub set_sparse_matrix {
242 0     0     my ($self, $nrows, $ncols, $rowval) = @_;
243              
244 0 0         die ('number of rows does not match') if ($nrows != $#$rowval + 1);
245              
246 0           $self->{matrix_type} = $MATRIX_TYPE_SPARSE;
247 0           $self->{nrows} = $nrows;
248 0           $self->{ncols} = $ncols;
249 0           $self->{nnz} = 0;
250              
251 0           my @rowptr = ();
252 0           my @rowind = ();
253 0           my @rowval = ();
254 0           for (my $rowptr = 0; $rowptr < $nrows; $rowptr++) {
255 0           my $row = $$rowval[$rowptr];
256 0           push @rowptr, $#rowind + 1;
257 0           for (my $j = 0; $j <= $#$row; $j+=2) {
258 0           my $col = $$row[$j];
259 0 0         die ("inappropriate col#$col in row#".($rowptr+1)) if ($col > $ncols);
260 0           push @rowind, $col - 1;
261 0           push @rowval, $$row[$j + 1];
262 0           $self->{nnz} ++;
263             }
264             }
265 0           push @rowptr, $#rowind + 1;
266 0           $self->{rowptr} = \@rowptr;
267 0           $self->{rowind} = \@rowind;
268 0           $self->{rowval} = \@rowval;
269             }
270              
271             sub set_raw_sparse_matrix {
272 0     0     my ($self, $nrows, $ncols, $rowptr, $rowind, $rowval) = @_;
273              
274             # $$rowptr[$#$rowptr + 1] = $#$rowind + 1 if ($$rowptr[-1] != $#$rowind + 1);
275 0 0 0       if ($$rowptr[-1] != $#$rowind + 1 or $#$rowptr != $nrows) {
276 0           die('rowptr not appropriate');
277             }
278              
279 0           $self->{matrix_type} = $MATRIX_TYPE_SPARSE;
280 0           $self->{nrows} = $nrows;
281 0           $self->{ncols} = $ncols;
282 0           $self->{nnz} = $#$rowval + 1;
283              
284 0           $self->{rowptr} = $rowptr;
285 0           $self->{rowind} = $rowind;
286 0           $self->{rowval} = $rowval;
287             }
288              
289             sub set_dense_matrix {
290 0     0     my ($self, $nrows, $ncols, $rowval) = @_;
291              
292 0 0         die ('number of rows does not match') if ($nrows != $#$rowval + 1);
293              
294 0           $self->{matrix_type} = $MATRIX_TYPE_DENSE;
295 0           $self->{nrows} = $nrows;
296 0           $self->{ncols} = $ncols;
297 0           $self->{nnz} = -1;
298              
299 0           my @rowval = ();
300 0           for (my $i = 0; $i <= $#$rowval; $i++) {
301 0           my $row = $$rowval[$i];
302 0 0         die ('number of cols does not match: row #'.($i+1)) if ($#$row+1 != $self->{ncols});
303 0           push @rowval, @$row;
304             }
305 0           $self->{rowval} = \@rowval;
306             }
307              
308             sub set_dense_matrix_as_sparse {
309 0     0     my ($self, $nrows, $ncols, $matrix) = @_;
310 0           my $rowval = [];
311              
312 0 0         die ('number of rows does not match') if ($nrows != $#$matrix + 1);
313              
314 0           for my $row_n (0..$nrows-1) {
315 0 0         die ('number of cols does not match: row #'.($row_n+1)) if ($#{$matrix->[$row_n]} + 1 != $ncols);
  0            
316 0           $rowval->[$row_n] = [];
317 0           for my $col_n (0..$ncols-1) {
318 0           my $val = $matrix->[$row_n][$col_n];
319 0 0         if ($val) {
320 0           push @{$rowval->[$row_n]}, $col_n + 1;
  0            
321 0           push @{$rowval->[$row_n]}, $val;
  0            
322             }
323             }
324             }
325 0           $self->set_sparse_matrix($nrows, $ncols, $rowval);
326             }
327              
328              
329             #
330             # API wrappers
331             #
332              
333             sub VP_ClusterDirect {
334 0     0     my $self = shift;
335              
336             # set method-specific defaults
337 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
338 0 0 0       $self->{colmodel} ||=
339             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
340              
341             # init return values
342 0           $self->{part} = [];
343              
344             # call xs
345 0           &_VP_ClusterDirect($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{ntrials}, $self->{niter}, $self->{seed}, $self->{dbglvl}, $self->{nclusters}, $self->{part});
346              
347 0   0       return $self->{pretty_format} && $self->format_cluster
348             || $self->{part};
349             }
350              
351             sub VP_ClusterRB {
352 0     0     my $self = shift;
353              
354             # set method-specific defaults
355 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
356 0 0 0       $self->{colmodel} ||=
357             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
358              
359             # init return values
360 0           $self->{part} = [];
361              
362             # call xs
363 0           &_VP_ClusterRB($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{ntrials}, $self->{niter}, $self->{seed}, $self->{cstype}, $self->{kwayrefine}, $self->{dbglvl}, $self->{nclusters}, $self->{part});
364              
365 0   0       return $self->{pretty_format} && $self->format_cluster
366             || $self->{part};
367             }
368              
369             sub VA_Cluster {
370 0     0     my $self = shift;
371              
372             # set method-specific defaults
373 0   0       $self->{crfun} ||= CLUTO_CLFUN_UPGMA();
374 0 0 0       $self->{colmodel} ||=
375             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
376              
377             # init return values
378 0           $self->{part} = [];
379 0           $self->{ptree} = [];
380 0           $self->{tsims} = [];
381 0           $self->{gains} = [];
382              
383             # call xs
384 0           &_VA_Cluster($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{tsims}, $self->{gains});
385              
386 0   0       return $self->{pretty_format} && {
387             clusters => $self->format_cluster,
388             tree => $self->format_tree
389             }
390             || map $self->{$_}, qw(part ptree tsims gains);
391             }
392              
393             sub VA_ClusterBiased {
394 0     0     my $self = shift;
395              
396             # set method-specific defaults
397 0   0       $self->{crfun} ||= CLUTO_CLFUN_UPGMA();
398 0 0 0       $self->{colmodel} ||=
399             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
400 0           $self->{npclusters} = int($self->{nrows}**.5);
401              
402             # init return values
403 0           $self->{part} = [];
404 0           $self->{ptree} = [];
405 0           $self->{tsims} = [];
406 0           $self->{gains} = [];
407              
408             # call xs
409 0           &_VA_ClusterBiased($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{dbglvl}, $self->{npclusters}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{tsims}, $self->{gains});
410              
411 0   0       return $self->{pretty_format} && {
412             clusters => $self->format_cluster,
413             tree => $self->format_tree
414             }
415             || map $self->{$_}, qw(part ptree tsims gains);
416             }
417              
418             sub SP_ClusterDirect {
419 0     0     my $self = shift;
420              
421             # set method-specific defaults
422 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
423 0 0         warn ("number of rows not equal to number of cols") if ($self->{nrows} != $self->{ncols});
424              
425             # init return values
426 0           $self->{part} = [];
427              
428             # call xs
429 0           &_SP_ClusterDirect($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{crfun}, $self->{ntrials}, $self->{niter}, $self->{seed}, $self->{dbglvl}, $self->{nclusters}, $self->{part});
430              
431 0   0       return $self->{pretty_format} && $self->format_cluster
432             || $self->{part};
433             }
434              
435             sub SP_ClusterRB {
436 0     0     my $self = shift;
437              
438             # set method-specific defaults
439 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
440 0 0         warn ("number of rows not equal to number of cols") if ($self->{nrows} != $self->{ncols});
441              
442             # init return values
443 0           $self->{part} = [];
444              
445             # call xs
446 0           &_SP_ClusterRB($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{crfun}, $self->{ntrials}, $self->{niter}, $self->{seed}, $self->{cstype}, $self->{kwayrefine}, $self->{dbglvl}, $self->{nclusters}, $self->{part});
447              
448 0   0       return $self->{pretty_format} && $self->format_cluster
449             || $self->{part};
450             }
451              
452             sub VP_GraphClusterRB {
453 0     0     my $self = shift;
454              
455             # method-specific defaults
456 0   0       $self->{crfun} ||= CLUTO_CLFUN_CUT();
457 0 0 0       $self->{colmodel} ||=
458             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
459              
460             # init return values
461 0           $self->{part} = [];
462 0           $self->{crvalue} = 0;
463              
464             # call xs
465 0           my $rtn = &_VP_GraphClusterRB($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{grmodel}, $self->{nnbrs}, $self->{edgeprune}, $self->{vtxprune}, $self->{mincomponent}, $self->{ntrials}, $self->{seed}, $self->{cstype}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{crvalue});
466              
467 0   0       return $self->{pretty_format} && $self->format_cluster
468             || [ $rtn, $self->{part}, $self->{crvalue} ];
469             }
470              
471             sub SP_GraphClusterRB {
472 0     0     my $self = shift;
473              
474             # method-specific defaults
475 0   0       $self->{crfun} ||= CLUTO_CLFUN_CUT();
476 0 0 0       $self->{colmodel} ||=
477             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
478              
479             # init return values
480 0           $self->{part} = [];
481 0           $self->{crvalue} = 0;
482              
483             # call xs
484 0           my $rtn = &_SP_GraphClusterRB($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{nnbrs}, $self->{edgeprune}, $self->{vtxprune}, $self->{mincomponent}, $self->{ntrials}, $self->{seed}, $self->{cstype}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{crvalue});
485              
486 0   0       return $self->{pretty_format} && $self->format_cluster
487             || [ $rtn, $self->{part}, $self->{crvalue} ];
488             }
489              
490             sub SA_Cluster {
491 0     0     my $self = shift;
492              
493             # set method-specific defaults
494 0   0       $self->{crfun} ||= CLUTO_CLFUN_UPGMA();
495              
496             # init return values
497 0           $self->{part} = [];
498 0           $self->{ptree} = [];
499 0           $self->{tsims} = [];
500 0           $self->{gains} = [];
501              
502             # call xs
503 0           &_SA_Cluster($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{crfun}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{tsims}, $self->{gains});
504              
505 0   0       return $self->{pretty_format} && {
506             clusters => $self->format_cluster,
507             tree => $self->format_tree
508             }
509             || map $self->{$_}, qw(part ptree tsims gains);
510             }
511              
512             sub V_BuildTree {
513 0     0     my $self = shift;
514              
515             # set method-specific defaults
516 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
517 0 0 0       $self->{colmodel} ||=
518             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
519 0   0       $self->{treetype} ||= CLUTO_TREE_TOP();
520              
521             # init return values
522 0           $self->{ptree} = [];
523 0           $self->{tsims} = [];
524 0           $self->{gains} = [];
525              
526             # call xs
527 0           &_V_BuildTree($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{treetype}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{tsims}, $self->{gains});
528              
529 0   0       return $self->{pretty_format} && $self->format_tree
530             || map $self->{$_}, qw(ptree tsims gains);
531             }
532              
533             sub S_BuildTree {
534 0     0     my $self = shift;
535              
536             # set method-specific defaults
537 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
538 0 0         warn ("number of rows not equal to number of cols") if ($self->{nrows} != $self->{ncols});
539 0   0       $self->{treetype} ||= CLUTO_TREE_TOP();
540              
541             # init return values
542 0           $self->{ptree} = [];
543 0           $self->{tsims} = [];
544 0           $self->{gains} = [];
545              
546             # call xs
547 0           &_S_BuildTree($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{crfun}, $self->{treetype}, $self->{dbglvl}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{tsims}, $self->{gains});
548              
549 0   0       return $self->{pretty_format} && $self->format_tree
550             || map $self->{$_}, qw(ptree tsims gains);
551             }
552              
553             sub V_GetGraph {
554 0     0     my $self = shift;
555              
556             # set method-specific defaults
557 0 0 0       $self->{colmodel} ||=
558             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
559              
560             # init return values
561 0           $self->{growptr} = [];
562 0           $self->{growind} = [];
563 0           $self->{growval} = [];
564              
565             # call xs
566 0           &_V_GetGraph($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{grmodel}, $self->{nnbrs}, $self->{dbglvl}, $self->{growptr}, $self->{growind}, $self->{growval});
567              
568 0           return map $self->{$_}, qw(growptr growind growval);
569             }
570              
571             sub S_GetGraph {
572 0     0     my $self = shift;
573              
574             # set method-specific defaults
575              
576             # init return values
577 0           $self->{growptr} = [];
578 0           $self->{growind} = [];
579 0           $self->{growval} = [];
580              
581             # call xs
582 0           &_S_GetGraph($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{grmodel}, $self->{nnbrs}, $self->{dbglvl}, $self->{growptr}, $self->{growind}, $self->{growval});
583              
584 0           return map $self->{$_}, qw(growptr growind growval);
585             }
586              
587             sub V_GetSolutionQuality {
588 0     0     my $self = shift;
589              
590             # set method-specific defaults
591 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
592 0 0 0       $self->{colmodel} ||=
593             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
594              
595             # init return values
596              
597             # call xs
598 0           return &_V_GetSolutionQuality($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{crfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part});
599             }
600              
601             sub S_GetSolutionQuality {
602 0     0     my $self = shift;
603              
604             # set method-specific defaults
605 0   0       $self->{crfun} ||= CLUTO_CLFUN_I2();
606 0 0         warn ("number of rows not equal to number of cols") if ($self->{nrows} != $self->{ncols});
607              
608             # init return values
609              
610             # call xs
611 0           return &_S_GetSolutionQuality($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{crfun}, $self->{nclusters}, $self->{part});
612             }
613              
614             sub V_GetClusterStats {
615 0     0     my $self = shift;
616              
617             # set method-specific defaults
618              
619             # init return values
620 0           $self->{pwgts} = [];
621 0           $self->{cintsim} = [];
622 0           $self->{cintsdev} = [];
623 0           $self->{izscores} = [];
624 0           $self->{cextsim} = [];
625 0           $self->{cextsdev} = [];
626 0           $self->{ezscores} = [];
627              
628             # call xs
629 0           &_V_GetClusterStats($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part}, $self->{pwgts}, $self->{cintsim}, $self->{cintsdev}, $self->{izscores}, $self->{cextsim}, $self->{cextsdev}, $self->{ezscores});
630              
631 0   0       return $self->{pretty_format} && $self->format_cluster_stats
632             || map $self->{$_}, qw(pwgts cintsim cintsdev izscores cextsim cextsdev ezscores);
633             }
634              
635             sub S_GetClusterStats {
636 0     0     my $self = shift;
637              
638             # set method-specific defaults
639 0 0         warn ("number of rows not equal to number of cols") if ($self->{nrows} != $self->{ncols});
640              
641             # init return values
642 0           $self->{pwgts} = [];
643 0           $self->{cintsim} = [];
644 0           $self->{cintsdev} = [];
645 0           $self->{izscores} = [];
646 0           $self->{cextsim} = [];
647 0           $self->{cextsdev} = [];
648 0           $self->{ezscores} = [];
649              
650             # call xs
651 0           &_S_GetClusterStats($self->{matrix_type}, $self->{nrows}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{nclusters}, $self->{part}, $self->{pwgts}, $self->{cintsim}, $self->{cintsdev}, $self->{izscores}, $self->{cextsim}, $self->{cextsdev}, $self->{ezscores});
652              
653 0   0       return $self->{pretty_format} && $self->format_cluster_stats
654             || map $self->{$_}, qw(pwgts cintsim cintsdev izscores cextsim cextsdev ezscores);
655             }
656              
657             sub V_GetClusterFeatures {
658 0     0     my $self = shift;
659              
660             # init return values
661 0           $self->{internalids} = [];
662 0           $self->{internalwgts} = [];
663 0           $self->{externalids} = [];
664 0           $self->{externalwgts} = [];
665              
666             # call xs
667 0           &_V_GetClusterFeatures($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part}, $self->{nfeatures}, $self->{internalids}, $self->{internalwgts}, $self->{externalids}, $self->{externalwgts});
668              
669 0   0       return $self->{pretty_format} && $self->format_cluster_features
670             || map $self->{$_}, qw(internalids internalwgts externalids externalwgts);
671             }
672              
673             sub V_GetClusterSummaries {
674 0     0     my $self = shift;
675              
676             # set method-specific defaults
677 0 0 0       $self->{colmodel} ||=
678             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
679 0   0       $self->{sumtype} ||= CLUTO_SUMMTYPE_MAXCLIQUES();
680              
681             # init return values
682 0           $self->{r_nsum} = undef;
683 0           $self->{r_spid} = [];
684 0           $self->{r_swgt} = [];
685 0           $self->{r_sumptr} = [];
686 0           $self->{r_sumind} = [];
687              
688             # call xs
689 0           &_V_GetClusterSummaries($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part}, $self->{sumtype}, $self->{nfeatures}, $self->{r_nsum}, $self->{r_spid}, $self->{r_swgt}, $self->{r_sumptr}, $self->{r_sumind});
690              
691              
692 0   0       return $self->{pretty_format} && $self->format_cluster_summaries
693             || map $self->{$_}, qw(r_nsum r_spid r_swgt r_sumptr r_sumind);
694             }
695              
696             sub V_GetTreeStats {
697 0     0     my $self = shift;
698              
699             # set method-specific defaults
700 0 0 0       $self->{colmodel} ||=
701             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
702 0 0         warn ("ptree not set or size does not equal to 2*nclusters") if ($#{$self->{ptree}}+1 != $self->{nclusters}*2);
  0            
703              
704             # init return values
705 0           $self->{pwgts} = [];
706 0           $self->{cintsim} = [];
707 0           $self->{cextsim} = [];
708              
709             # call xs
710 0           &_V_GetTreeStats($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{pwgts}, $self->{cintsim}, $self->{cextsim});
711              
712              
713 0   0       return $self->{pretty_format} && $self->format_tree_stats
714             || map $self->{$_}, qw(pwgts cintsim cextsim);
715             }
716              
717             sub V_GetTreeFeatures {
718 0     0     my $self = shift;
719              
720             # set method-specific defaults
721 0 0 0       $self->{colmodel} ||=
722             ($self->{simfun} == CLUTO_SIM_CORRCOEF() ? CLUTO_COLMODEL_NONE() : CLUTO_COLMODEL_IDF());
723 0           warn ("ptree not set or size does not equal to 2*nclusters")
724 0 0         if ($#{$self->{ptree}}+1 != $self->{nclusters}*2);
725              
726             # init return values
727 0           $self->{internalids} = [];
728 0           $self->{internalwgts} = [];
729 0           $self->{externalids} = [];
730 0           $self->{externalwgts} = [];
731              
732             # call xs
733 0           &_V_GetTreeFeatures($self->{matrix_type}, $self->{nrows}, $self->{ncols}, $self->{nnz}, $self->{rowptr}, $self->{rowind}, $self->{rowval}, $self->{simfun}, $self->{rowmodel}, $self->{colmodel}, $self->{colprune}, $self->{nclusters}, $self->{part}, $self->{ptree}, $self->{nfeatures}, $self->{internalids}, $self->{internalwgts}, $self->{externalids}, $self->{externalwgts});
734              
735              
736 0   0       return $self->{pretty_format} && $self->format_tree_features
737             || map $self->{$_}, qw(internalids internalwgts externalids externalwgts);
738             }
739              
740              
741              
742              
743             #
744             # for prertty_format option
745             #
746              
747             sub format_cluster {
748 0     0     my $self = shift;
749              
750 0           my $clusters = [];
751 0           for my $i (0..$self->{nrows}-1) {
752 0 0         push @{$clusters->[$self->{part}->[$i]]}, {
  0            
753             row => $i,
754             rowlabel => $self->{rowlabels}->[$i]
755             } if ($self->{part}->[$i] >= 0);
756             }
757 0           return $clusters;
758              
759             # return [ map {
760             # rowlabel => $self->{rowlabels}->[$_],
761             # cluster => $self->{part}->[$_]
762             # }, (0..$self->{nrows}-1)]
763             }
764              
765             sub format_cluster_stats {
766 0     0     my $self = shift;
767              
768             return {
769 0           clusters => [ map {
770             pwgt => $self->{pwgts}->[$_],
771             cintsim => $self->{cintsim}->[$_],
772             cintsdev => $self->{cintsdev}->[$_],
773             cextsim => $self->{cextsim}->[$_],
774             cextsdev => $self->{cextsdev}->[$_],
775             }, (0..$self->{nclusters}-1) ],
776             rows => [ map {
777             rowlabel => $self->{rowlabels}->[$_],
778             izscore => $self->{izscores}->[$_],
779             exscore => $self->{ezscores}->[$_]
780             }, (0..$self->{nrows}-1) ]
781             }
782             }
783              
784             sub format_cluster_features {
785 0     0     my $self = shift;
786              
787 0           return [ map {
788             descriptive =>
789             [ map {
790             internalid => $self->{internalids}->[$_],
791             collabel => $self->{collabels}->[$self->{internalids}->[$_]],
792             internalwgt => $self->{internalwgts}->[$_]
793             }, (($_*$self->{nfeatures})..(($_ + 1)*$self->{nfeatures} - 1)) ],
794             discriminating =>
795             [ map {
796             externalid => $self->{externalids}->[$_],
797             collabel => $self->{collabels}->[$self->{externalids}->[$_]],
798             externalwgt => $self->{externalwgts}->[$_]
799             }, (($_*$self->{nfeatures})..(($_ + 1)*$self->{nfeatures} - 1)) ],
800             }, (0..$self->{nclusters}-1)];
801             }
802              
803             sub format_cluster_summaries {
804 0     0     my $self = shift;
805              
806 0           return [ map {
807             cluster => $self->{r_spid}->[$_],
808             swgt => $self->{r_swgt}->[$_],
809             features => [ map $self->{r_sumind}->[$_], ($self->{r_sumptr}->[$_]..($self->{r_sumptr}->[$_+1]-1)) ],
810             }, (0..($self->{r_nsum}-1)) ];
811             }
812              
813             sub format_tree {
814 0     0     my $self = shift;
815              
816 0           return [ map {
817             parent => $self->{ptree}->[$_],
818             tsims => $self->{tsims}->[$_],
819             gains => $self->{gains}->[$_]
820 0           }, (0..$#{$self->{ptree}}-1) ];
821             }
822              
823             sub format_tree_stats {
824 0     0     my $self = shift;
825              
826 0           return [ map {
827             cintsim => $self->{cintsim}->[$_],
828             cextsim => $self->{cextsim}->[$_]
829             }, (0..$self->{nclusters}*2-1) ];
830             }
831              
832             sub format_tree_features {
833 0     0     my $self = shift;
834              
835 0           return [ map
836             [ map {
837             descriptive =>
838             [ map {
839             internalid => $self->{internalids}->[$_],
840             collabel => $self->{collabels}->[$self->{internalids}->[$_]],
841             internalwgt => $self->{internalwgts}->[$_]
842             },
843             grep defined($self->{internalids}->[$_]),
844             (($_*$self->{nfeatures})..(($_ + 1)*$self->{nfeatures} - 1)) ],
845             discriminating =>
846             [ map {
847             externalid => $self->{externalids}->[$_],
848             collabel => $self->{collabels}->[$self->{externalids}->[$_]],
849             externalwgt => $self->{externalwgts}->[$_]
850             },
851             grep defined($self->{externalids}->[$_]),
852             (($_*$self->{nfeatures})..(($_ + 1)*$self->{nfeatures} - 1)) ],
853             }, ($_..$_+$self->{nclusters}-1)]
854             , (0..$self->{nclusters}*2-1) ];
855             }
856              
857              
858             # Autoload methods go after =cut, and are processed by the autosplit program.
859              
860             1;
861             __END__