File Coverage

Bio/Matrix/Generic.pm
Criterion Covered Total %
statement 171 253 67.5
branch 43 90 47.7
condition 7 24 29.1
subroutine 26 29 89.6
pod 25 26 96.1
total 272 422 64.4


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::Matrix::Generic
3             #
4             # Please direct questions and support issues to
5             #
6             # Cared for by Jason Stajich
7             #
8             # Copyright Jason Stajich
9             #
10             # You may distribute this module under the same terms as perl itself
11              
12             # POD documentation - main docs before the code
13              
14             =head1 NAME
15              
16             Bio::Matrix::Generic - A generic matrix implementation
17              
18             =head1 SYNOPSIS
19              
20             # A matrix has columns and rows
21             my $matrix = Bio::Matrix::Generic->new;
22             $matrix->add_column(1,$column1);
23             $matrix->add_column(2,$column2);
24              
25             my $element = $matrix->entry_by_num(1,2);
26             $matrix->entry_by_num(1,2,$newval);
27              
28             my $entry = $matrix->entry('human', 'mouse');
29              
30             $matrix->entry('human','mouse', $newval);
31              
32              
33             =head1 DESCRIPTION
34              
35             This is a general purpose matrix object for dealing with row+column
36             data which is typical when enumerating all the pairwise combinations
37             and desiring to get slices of the data.
38              
39             Data can be accessed by column and row names or indexes. Matrix
40             indexes start at 0.
41              
42             =head1 FEEDBACK
43              
44             =head2 Mailing Lists
45              
46             User feedback is an integral part of the evolution of this and other
47             Bioperl modules. Send your comments and suggestions preferably to
48             the Bioperl mailing list. Your participation is much appreciated.
49              
50             bioperl-l@bioperl.org - General discussion
51             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
52              
53             =head2 Support
54              
55             Please direct usage questions or support issues to the mailing list:
56              
57             I
58              
59             rather than to the module maintainer directly. Many experienced and
60             reponsive experts will be able look at the problem and quickly
61             address it. Please include a thorough description of the problem
62             with code and data examples if at all possible.
63              
64             =head2 Reporting Bugs
65              
66             Report bugs to the Bioperl bug tracking system to help us keep track
67             of the bugs and their resolution. Bug reports can be submitted via the
68             web:
69              
70             https://github.com/bioperl/bioperl-live/issues
71              
72             =head1 AUTHOR - Jason Stajich
73              
74             Email jason-at-bioperl-dot-org
75              
76             =head1 APPENDIX
77              
78             The rest of the documentation details each of the object methods.
79             Internal methods are usually preceded with a _
80              
81             =cut
82              
83             package Bio::Matrix::Generic;
84 1     1   450 use strict;
  1         2  
  1         26  
85              
86              
87 1     1   4 use base qw(Bio::Root::Root Bio::Matrix::MatrixI);
  1         2  
  1         254  
88              
89             =head2 new
90              
91             Title : new
92             Usage : my $obj = Bio::Matrix::Generic->new();
93             Function: Builds a new Bio::Matrix::Generic object
94             Returns : an instance of Bio::Matrix::Generic
95             Args : -values => arrayref of arrayrefs of data initialization
96             -rownames => arrayref of row names
97             -colnames => arrayref of col names
98             -matrix_id => id of the matrix
99             -matrix_name=> name of the matrix
100             -matrix_init_value => default value to initialize empty cells
101              
102             =cut
103              
104             sub new {
105 5     5 1 95 my($class,@args) = @_;
106              
107 5         19 my $self = $class->SUPER::new(@args);
108 5         27 my ($values, $rownames, $colnames,
109             $id,$name,$init_val) =
110             $self->_rearrange([qw(VALUES ROWNAMES COLNAMES
111             MATRIX_ID MATRIX_NAME
112             MATRIX_INIT_VALUE)],@args);
113 5 100       15 $self->matrix_id($id) if defined $id;
114 5 100       20 $self->matrix_name($name) if defined $name;
115 5 50 33     16 if( defined $rownames && defined $colnames ) {
    0 0        
116 5 50       19 if( ref($rownames) !~ /ARRAY/i ) {
117 0         0 $self->throw("need an arrayref for the -rownames option");
118             }
119             # insure we copy the values
120 5         16 $self->{'_rownames'} = [ @$rownames ];
121 5         8 my $count = 0;
122 5         9 %{$self->{'_rownamesmap'}} = map { $_ => $count++ } @$rownames;
  5         30  
  63         70  
123              
124 5 50       19 if( ref($colnames) !~ /ARRAY/i ) {
125 0         0 $self->throw("need an arrayref for the -colnames option");
126             }
127             # insure we copy the values
128 5         16 $self->{'_colnames'} = [ @$colnames ];
129 5         5 $count = 0;
130 5         8 %{$self->{'_colnamesmap'}} = map { $_ => $count++ } @$colnames;
  5         16  
  63         70  
131              
132 5         11 $self->{'_values'} = [];
133 5 50       11 if( defined $values ) {
134 5 50       13 if( ref($values) !~ /ARRAY/i ) {
135 0         0 $self->throw("Need an arrayref of arrayrefs (matrix) for -values option");
136             }
137 5         10 for my $v ( @$values ) {
138 63 50       129 if( ref($v) !~ /ARRAY/i ) {
139 0         0 $self->throw("Need and array of arrayrefs (matrix) for -values option");
140             }
141 63         52 push @{$self->{'_values'}}, [@$v];
  63         291  
142             }
143             } else {
144 0         0 my @fill = ($init_val) x scalar @$colnames; # undef init_val will be default
145 0         0 for ( @$rownames ) {
146 0         0 push @{$self->{'_values'}}, [@fill];
  0         0  
147             }
148             }
149             } elsif( ! defined $rownames && ! defined $colnames && ! defined $values ) {
150 0         0 $self->{'_values'} = [];
151 0         0 $self->{'_rownames'} = [];
152 0         0 $self->{'_colnames'} = [];
153             } else {
154 0         0 $self->throw("Must have either provided no values/colnames/rownames or provided all three");
155             }
156              
157 5         13 return $self;
158             }
159              
160              
161             =head2 matrix_id
162              
163             Title : matrix_id
164             Usage : my $id = $matrix->matrix_id
165             Function: Get/Set the matrix ID
166             Returns : scalar value
167             Args : [optional] new id value to store
168              
169              
170             =cut
171              
172             sub matrix_id{
173 2     2 1 3 my $self = shift;
174 2 100       5 return $self->{'_matid'} = shift if @_;
175 1         4 return $self->{'_matid'};
176              
177            
178             }
179              
180             =head2 matrix_name
181              
182             Title : matrix_name
183             Usage : my $name = $matrix->matrix_name();
184             Function: Get/Set the matrix name
185             Returns : scalar value
186             Args : [optional] new matrix name value
187              
188              
189             =cut
190              
191             sub matrix_name{
192 3     3 1 7 my $self = shift;
193 3 100       7 return $self->{'_matname'} = shift if @_;
194 1         4 return $self->{'_matname'};
195             }
196              
197              
198             =head2 entry
199              
200             Title : entry
201             Usage : my $entry = $matrix->entry($row,$col,$value)
202             Function: Get the value for a specific cell as specified
203             by the row and column names
204             Returns : scalar value or undef if row or col does not
205             exist
206             Args : $rowname - name of the row
207             $colname - column name
208             $value - [optional] New value for the entry
209              
210             =cut
211              
212             sub entry{
213 16     16 1 31 my ($self,$row,$column,$newvalue) = @_;
214 16 50 33     59 if( ! defined $row || ! defined $column ) {
215 0         0 $self->throw("Need at least 2 ids");
216             }
217              
218 16         39 my ($rownum) = $self->row_num_for_name($row);
219 16         34 my ($colnum) = $self->column_num_for_name($column);
220 16         31 return $self->entry_by_num($rownum,$colnum,$newvalue);
221             }
222              
223             =head2 get_entry
224              
225             Title : get_entry
226             Usage : my $entry = $matrix->get_entry($rowname,$columname,$value)
227             Function: Get the entry for a given row,column pair
228             Returns : scalar
229             Args : $row name
230             $column name
231             $value
232              
233              
234             =cut
235              
236 14     14 1 43 sub get_entry{ $_[0]->entry($_[1],$_[2]) }
237              
238             =head2 entry_by_num
239              
240             Title : entry_by_num
241             Usage : my $entry = $matrix->entry_by_num($rownum,$colnum)
242             Function: Get an entry by row and column numbers instead of by name
243             (rows and columns start at 0)
244             Returns : scalar value or undef if row or column name does not
245             exist
246             Args : $row - row number
247             $col - column number
248             [optional] $newvalue to store at this cell
249              
250             =cut
251              
252             sub entry_by_num {
253 169     169 1 193 my ($self,$row,$col,$newvalue) = @_;
254 169 50 33     921 if( ! defined $row || ! defined $col ||
      33        
      33        
255             $row !~ /^\d+$/ ||
256             $col !~ /^\d+$/ ) {
257 0         0 $self->warn("expected to get 2 number for entry_by_num");
258 0         0 return;
259             }
260            
261 169 100       216 if( defined $newvalue ) {
262 15         18 return $self->_values->[$row][$col] = $newvalue;
263             } else {
264 154         180 return $self->_values->[$row][$col];
265             }
266             }
267              
268             sub get_element {
269 0     0 0 0 my $self = shift;
270 0         0 $self->entry(@_);
271             }
272              
273              
274             =head2 column
275              
276             Title : column
277             Usage : my @col = $matrix->column('ALPHA');
278             OR
279             $matrix->column('ALPHA', \@col);
280             Function: Get/Set a particular column
281             Returns : Array (in array context) or arrayref (in scalar context)
282             of values.
283             For setting will warn if the new column is of a different
284             length from the rest of the columns.
285             Args : name of the column
286             [optional] new column to store here
287              
288             =cut
289              
290             sub column{
291 1     1 1 3 my ($self,$column,$newcol) = @_;
292              
293 1 50       3 if( ! defined $column ) {
294 0         0 $self->warn("Need at least a column id");
295 0         0 return;
296             }
297 1         3 my $colnum = $self->column_num_for_name($column);
298 1 50       3 if( ! defined $colnum ) {
299 0         0 $self->warn("could not find column number for $column");
300 0         0 return;
301             }
302 1         2 return $self->column_by_num($colnum,$newcol);
303             }
304              
305              
306             =head2 get_column
307              
308             Title : get_column
309             Usage : my @row = $matrix->get_column('ALPHA');
310             Function: Get a particular column
311             Returns : Array (in array context) or arrayref (in scalar context)
312             of values
313             Args : name of the column
314              
315              
316             =cut
317              
318 1     1 1 4 sub get_column { $_[0]->column($_[1]) }
319              
320              
321             =head2 column_by_num
322              
323             Title : column_by_num
324             Usage : my @col = $matrix->column_by_num(1);
325             OR
326             $matrix->column_by_num(1,\@newcol);
327             Function: Get/Set a column by its number instead of name
328             (cols/rows start at 0)
329             Returns : Array (in array context) or arrayref (in scalar context)
330             of values
331             Args : name of the column
332             [optional] new value to store for a particular column
333              
334             =cut
335              
336             sub column_by_num{
337 1     1 1 2 my ($self,$colnum,$newcol) = @_;
338 1 50       3 if( ! defined $colnum ) {
339 0         0 $self->warn("need at least a column number");
340 0         0 return;
341             }
342 1         2 my $rowcount = $self->num_rows;
343 1         3 my $colcount = $self->num_columns;
344 1         1 my $ret;
345            
346 1 50       3 if( defined $newcol ) {
347 0 0       0 if( ref($newcol) !~ /ARRAY/i) {
348 0         0 $self->warn("expected a valid arrayref for resetting a column");
349 0         0 return;
350             }
351 0 0       0 if( scalar @$newcol != $rowcount ) {
352 0         0 $self->warn("new column is not the correct length ($rowcount) - call add or remove row to shrink or grow the number of rows first");
353 0         0 return;
354             }
355 0         0 for(my $i=0; $i < $rowcount; $i++) {
356 0         0 $self->entry_by_num($i,$colnum,$newcol->[$i]);
357             }
358 0         0 $ret = $newcol;
359             } else {
360 1         1 $ret = [];
361 1         3 for(my $i=0; $i < $rowcount; $i++) {
362 3         5 push @$ret,$self->entry_by_num($i,$colnum);
363             }
364             }
365 1 50       4 if( wantarray ) { return @$ret }
  1         3  
366 0         0 return $ret;
367              
368             }
369              
370             =head2 row
371              
372             Title : row
373             Usage : my @row = $matrix->row($rowname);
374             OR
375             $matrix->row($rowname,\@rowvalues);
376             Function: Get/Set the row of the matrix
377             Returns : Array (in array context) or arrayref (in scalar context)
378             Args : rowname
379             [optional] new value of row to store
380              
381              
382             =cut
383              
384             sub row {
385 9     9 1 14 my ($self,$row,$newrow) = @_;
386 9 50       16 if( ! defined $row) {
387 0         0 $self->warn("Need at least a row id");
388 0         0 return;
389             }
390 9         16 my $rownum = $self->row_num_for_name($row);
391 9         17 return $self->row_by_num($rownum,$newrow);
392             }
393              
394              
395             =head2 get_row
396              
397             Title : get_row
398             Usage : my @row = $matrix->get_row('ALPHA');
399             Function: Get a particular row
400             Returns : Array (in array context) or arrayref (in scalar context)
401             of values
402             Args : name of the row
403              
404             =cut
405              
406 9     9 1 2666 sub get_row { $_[0]->row($_[1]) }
407              
408             =head2 row_by_num
409              
410             Title : row_by_num
411             Usage : my @row = $matrix->row_by_num($rownum);
412             OR
413             $matrix->row($rownum,\@rowvalues);
414             Function: Get/Set the row of the matrix
415             Returns : Array (in array context) or arrayref (in scalar context)
416             Args : rowname
417             [optional] new value of row to store
418              
419             =cut
420              
421             sub row_by_num{
422 9     9 1 12 my ($self,$rownum,$newrow) = @_;
423 9 50       17 if( ! defined $rownum ) {
424 0         0 $self->warn("need at least a row number");
425 0         0 return;
426             }
427 9         16 my $colcount = $self->num_columns;
428 9         11 my $ret;
429 9 50       15 if( defined $newrow ) {
430 0 0       0 if( ref($newrow) !~ /ARRAY/i) {
431 0         0 $self->warn("expected a valid arrayref for resetting a row");
432 0         0 return;
433             }
434 0 0       0 if( scalar @$newrow != $colcount ) {
435 0         0 $self->warn("new row is not the correct length ($colcount) - call add or remove column to shrink or grow the number of columns first");
436 0         0 return;
437             }
438 0         0 for(my $i=0; $i < $colcount; $i++) {
439 0         0 $self->entry_by_num($rownum,$i, $newrow->[$i]);
440             }
441 0         0 $ret = $newrow;
442             } else {
443 9         12 $ret = [];
444 9         15 for(my $i=0; $i < $colcount; $i++) {
445             # we're doing this to explicitly
446             # copy the entire row
447 87         126 push @$ret, $self->entry_by_num($rownum,$i);
448             }
449             }
450 9 50       14 if( wantarray ) { return @$ret }
  9         42  
451 0         0 return $ret;
452              
453              
454             }
455              
456              
457             =head2 diagonal
458              
459             Title : diagonal
460             Usage : my @diagonal = $matrix->get_diagonal()
461             Function: Get the diagonal of a matrix
462             Returns : Array (in array context) or arrayref (in scalar context)
463             of values which lie along the diagonal
464             Args : none
465              
466              
467             =cut
468              
469             sub get_diagonal{
470 2     2 1 3 my ($self) = @_;
471 2         3 my @diag;
472 2         6 my $rowcount = $self->num_rows;
473 2         4 my $colcount = $self->num_columns;
474 2         6 for(my $i = 0; $i < $rowcount; $i++ ) {
475 48         61 push @diag, $self->entry_by_num($i,$i);
476             }
477 2         16 return @diag;
478             }
479              
480              
481             =head2 add_row
482              
483             Title : add_row
484             Usage : $matrix->add_row($index,\@newrow);
485             Function: Adds a row at particular location in the matrix.
486             If $index < the rowcount will shift all the rows down
487             by the number of new rows.
488             To add a single empty row, simply call
489             $matrix->add_row($index,undef);
490             Returns : the updated number of total rows in the matrix
491             Args : index to store
492             name of the row (header)
493             newrow to add, if this is undef will add a single
494             row with all values set to undef
495              
496             =cut
497              
498             sub add_row{
499 2     2 1 5 my ($self,$index,$name,$newrow) = @_;
500 2 50 33     20 if( !defined $index ||
    50          
    50          
501             $index !~ /^\d+$/ ) {
502 0         0 $self->warn("expected a valid row index in add_row");
503 0         0 return;
504             } elsif( ! defined $name) {
505 0         0 $self->warn("Need a row name or heading");
506 0         0 return;
507             } elsif( defined $self->row_num_for_name($name) ) {
508 0         0 $self->warn("Need a unqiue name for the column heading, $name is already used");
509 0         0 return;
510             }
511 2         4 my $colcount = $self->num_columns;
512 2         3 my $rowcount = $self->num_rows;
513              
514 2 50       4 if( $index > $rowcount ) {
515 0         0 $self->warn("cannot add a row beyond 1+last row at the end ($rowcount) not $index - adding at $rowcount instead");
516 0         0 $index = $rowcount;
517             }
518              
519 2 50       10 if( ! defined $newrow ) {
    50          
520 0         0 $newrow = [];
521 0         0 $newrow->[$colcount] = undef;
522             } elsif( ref($newrow) !~ /ARRAY/i ) {
523 0         0 $self->throw("Expected either undef or a valid arrayref for add_row");
524             }
525             # add this row to the matrix by carving out space for it with
526             # splice
527 2         2 splice(@{$self->{'_values'}}, $index,0,[]);
  2         5  
528 2         5 for( my $i = 0; $i < $colcount; $i++ ) {
529 7         11 $self->entry_by_num($index,$i,$newrow->[$i]);
530             }
531 2         2 splice(@{$self->{'_rownames'}}, $index,0,$name);
  2         5  
532             # Sadly we have to remap these each time (except for the case
533             # when we're adding a new column to the end, but I don't think
534             # the speedup for that case warrants the extra code at this time.
535 2         3 my $ct = 0;
536 2         3 %{$self->{'_rownamesmap'}} = map { $_ => $ct++} @{$self->{'_rownames'}};
  2         7  
  9         13  
  2         4  
537 2         5 return $self->num_rows;
538             }
539              
540             =head2 remove_row
541              
542             Title : remove_row
543             Usage : $matrix->remove_row($colnum)
544             Function: remove a row from the matrix shifting all the rows
545             up by one
546             Returns : Updated number of rows in the matrix
547             Args : row index
548              
549              
550             =cut
551              
552             sub remove_row{
553 1     1 1 2 my ($self,$rowindex) = @_;
554 1         2 my $rowcount = $self->num_rows;
555            
556 1 50       3 if( $rowindex > $rowcount ) {
557 0         0 $self->warn("rowindex $rowindex is greater than number of rows $rowcount, cannot process");
558 0         0 return 0;
559             } else {
560 1         1 splice(@{$self->_values},$rowindex,1);
  1         2  
561 1         3 delete $self->{'_rownamesmap'}->{$self->{'_rownames'}->[$rowindex]};
562 1         2 splice(@{$self->{'_rownames'}},$rowindex,1);
  1         2  
563             }
564 1         1 my $ct = 0;
565 1         2 %{$self->{'_rownamesmap'}} = map { $_ => $ct++} @{$self->{'_rownames'}};
  1         4  
  4         6  
  1         2  
566 1         2 return $self->num_rows;
567             }
568              
569             =head2 add_column
570              
571             Title : add_column
572             Usage : $matrix->add_column($index,$colname,\@newcol);
573             Function: Adds a column at particular location in the matrix.
574             If $index < the colcount will shift all the columns right
575             by the number of new columns.
576             To add a single empty column, simply call
577             $matrix->add_column($index,undef);
578             Returns : the updated number of total columns in the matrix
579             Args : index to store
580             name of the column (header)
581             newcolumn to add, if this is undef will add a single
582             column with all values set to undef
583              
584              
585             =cut
586              
587              
588             sub add_column{
589 2     2 1 5 my ($self,$index,$name,$newcol) = @_;
590 2 50 33     20 if( !defined $index ||
    50          
    50          
591             $index !~ /^\d+$/ ) {
592 0         0 $self->warn("expected a valid col index in add_column");
593 0         0 return;
594             } elsif( ! defined $name) {
595 0         0 $self->warn("Need a column name or heading");
596 0         0 return;
597             } elsif( defined $self->column_num_for_name($name) ) {
598 0         0 $self->warn("Need a unqiue name for the column heading, $name is already used");
599 0         0 return;
600             }
601 2         4 my $colcount = $self->num_columns;
602 2         3 my $rowcount = $self->num_rows;
603 2 50       4 if( $index > $colcount ) {
604 0         0 $self->warn("cannot add a column beyond 1+last column at the end ($colcount) not $index - adding at $colcount instead");
605 0         0 $index = $colcount;
606             }
607              
608 2 50       9 if( ! defined $newcol ) {
    50          
609 0         0 $newcol = [];
610 0         0 $newcol->[$rowcount] = undef; # make the array '$rowcount' long
611             } elsif( ref($newcol) !~ /ARRAY/i ) {
612 0         0 $self->throw("Expected either undef or a valid arrayref for add_row");
613             }
614 2         4 for( my $i = 0; $i < $rowcount; $i++ ) {
615             # add this column to each row
616 8         8 splice(@{$self->_values->[$i]},$index,0,[]);
  8         8  
617 8         13 $self->entry_by_num($i,$index,$newcol->[$i]);
618             }
619 2         3 splice(@{$self->{'_colnames'}}, $index,0,$name);
  2         4  
620             # Sadly we have to remap these each time (except for the case
621             # when we're adding a new column to the end, but I don't think
622             # the speedup for that case warrants the extra code at this time.
623 2         3 my $ct = 0;
624 2         2 %{$self->{'_colnamesmap'}} = map {$_ => $ct++} @{$self->{'_colnames'}};
  2         8  
  9         13  
  2         4  
625 2         5 return $self->num_columns;
626             }
627              
628             =head2 remove_column
629              
630             Title : remove_column
631             Usage : $matrix->remove_column($colnum)
632             Function: remove a column from the matrix shifting all the columns
633             to the left by one
634             Returns : Updated number of columns in the matrix
635             Args : column index
636              
637             =cut
638              
639             sub remove_column{
640 1     1 1 3 my ($self,$colindex) = @_;
641              
642 1         2 my $colcount = $self->num_columns;
643 1         3 my $rowcount = $self->num_rows;
644 1 50       3 if( $colindex > $colcount ) {
645 0         0 $self->warn("colindex $colindex is greater than number of columns ($colcount), cannot process");
646 0         0 return 0;
647             } else {
648 1         3 for(my $i = 0; $i < $rowcount; $i++ ) {
649 4         5 splice(@{$self->_values->[$i]},$colindex,1);
  4         5  
650             }
651 1         3 delete $self->{'_colnamesmap'}->{$self->{'_colnames'}->[$colindex]};
652 1         1 splice(@{$self->{'_colnames'}},$colindex,1);
  1         3  
653             }
654 1         1 my $ct = 0;
655 1         2 %{$self->{'_colnamesmap'}} = map {$_ => $ct++} @{$self->{'_colnames'}};
  1         4  
  4         7  
  1         2  
656 1         3 return $self->num_columns;
657             }
658              
659             =head2 column_num_for_name
660              
661             Title : column_num_for_name
662             Usage : my $num = $matrix->column_num_for_name($name)
663             Function: Gets the column number for a particular column name
664             Returns : integer
665             Args : string
666              
667              
668             =cut
669              
670             sub column_num_for_name{
671 23     23 1 32 my ($self,$name) = @_;
672            
673 23         45 return $self->{'_colnamesmap'}->{$name};
674             }
675              
676             =head2 row_num_for_name
677              
678             Title : row_num_for_name
679             Usage : my $num = $matrix->row_num_for_name
680             Function: Gets the row number for a particular row name
681             Returns : integer
682             Args : string
683              
684              
685             =cut
686              
687             sub row_num_for_name{
688 30     30 1 1543 my ($self,$name) = @_;
689 30         58 return $self->{'_rownamesmap'}->{$name}
690             }
691              
692              
693             =head2 column_header
694              
695             Title : column_header
696             Usage : my $name = $matrix->column_header(0)
697             Function: Gets the column header for a particular column number
698             Returns : string
699             Args : integer
700              
701              
702             =cut
703              
704             sub column_header{
705 2     2 1 5 my ($self,$num) = @_;
706 2         7 return $self->{'_colnames'}->[$num];
707             }
708              
709              
710             =head2 row_header
711              
712             Title : row_header
713             Usage : my $name = $matrix->row_header(0)
714             Function: Gets the row header for a particular row number
715             Returns : string
716             Args : integer
717              
718              
719             =cut
720              
721             sub row_header{
722 2     2 1 5 my ($self,$num) = @_;
723 2         7 return $self->{'_rownames'}->[$num];
724             }
725              
726             =head2 num_rows
727              
728             Title : num_rows
729             Usage : my $rowcount = $matrix->num_rows;
730             Function: Get the number of rows
731             Returns : integer
732             Args : none
733              
734              
735             =cut
736              
737             sub num_rows{
738 14     14 1 19 my ($self) = @_;
739 14         14 return scalar @{$self->_values};
  14         20  
740             }
741              
742              
743             =head2 num_columns
744              
745             Title : num_columns
746             Usage : my $colcount = $matrix->num_columns
747             Function: Get the number of columns
748             Returns : integer
749             Args : none
750              
751              
752             =cut
753              
754             sub num_columns{
755 21     21 1 27 my ($self) = @_;
756 21 50       17 return scalar @{$self->_values->[0] || []};
  21         28  
757             }
758              
759              
760             =head2 row_names
761              
762             Title : row_names
763             Usage : my @rows = $matrix->row_names
764             Function: The names of all the rows
765             Returns : array in array context, arrayref in scalar context
766             Args : none
767              
768              
769             =cut
770              
771             sub row_names{
772 0 0   0 1 0 if( wantarray ) {
773 0         0 return @{shift->{'_rownames'}};
  0         0  
774             } else {
775 0         0 return shift->{'_rownames'};
776             }
777             }
778              
779              
780             =head2 column_names
781              
782             Title : column_names
783             Usage : my @columns = $matrix->column_names
784             Function: The names of all the columns
785             Returns : array in array context, arrayref in scalar context
786             Args : none
787              
788              
789             =cut
790              
791             sub column_names{
792 0 0   0 1 0 if( wantarray ) {
793 0         0 return @{shift->{'_colnames'}};
  0         0  
794             } else {
795 0         0 return shift->{'_colnames'};
796             }
797             }
798              
799             =head2 private methods
800              
801             Private methods for a Generic Matrix
802              
803             =head2 _values
804              
805             Title : _values
806             Usage : $matrix->_values();
807             Function: get/set for array ref of the matrix containing
808             distance values
809             Returns : an array reference
810             Args : an array reference
811              
812              
813             =cut
814              
815             sub _values{
816 217     217   222 my ($self,$val) = @_;
817 217 50       254 if( $val ){
818 0         0 $self->{'_values'} = $val;
819             }
820 217         583 return $self->{'_values'};
821             }
822              
823             1;