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   464 use strict;
  1         1  
  1         25  
85              
86              
87 1     1   3 use base qw(Bio::Root::Root Bio::Matrix::MatrixI);
  1         0  
  1         278  
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 142 my($class,@args) = @_;
106              
107 5         20 my $self = $class->SUPER::new(@args);
108 5         23 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       17 $self->matrix_id($id) if defined $id;
114 5 100       18 $self->matrix_name($name) if defined $name;
115 5 50 33     17 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         15 $self->{'_rownames'} = [ @$rownames ];
121 5         5 my $count = 0;
122 5         6 %{$self->{'_rownamesmap'}} = map { $_ => $count++ } @$rownames;
  5         23  
  63         52  
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         13 $self->{'_colnames'} = [ @$colnames ];
129 5         4 $count = 0;
130 5         6 %{$self->{'_colnamesmap'}} = map { $_ => $count++ } @$colnames;
  5         14  
  63         53  
131              
132 5         12 $self->{'_values'} = [];
133 5 50       24 if( defined $values ) {
134 5 50       17 if( ref($values) !~ /ARRAY/i ) {
135 0         0 $self->throw("Need an arrayref of arrayrefs (matrix) for -values option");
136             }
137 5         8 for my $v ( @$values ) {
138 63 50       126 if( ref($v) !~ /ARRAY/i ) {
139 0         0 $self->throw("Need and array of arrayrefs (matrix) for -values option");
140             }
141 63         30 push @{$self->{'_values'}}, [@$v];
  63         284  
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         14 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         3 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 6 my $self = shift;
193 3 100       6 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)
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              
209             =cut
210              
211             sub entry{
212 16     16 1 21 my ($self,$row,$column,$newvalue) = @_;
213 16 50 33     52 if( ! defined $row || ! defined $column ) {
214 0         0 $self->throw("Need at least 2 ids");
215             }
216              
217 16         27 my ($rownum) = $self->row_num_for_name($row);
218 16         25 my ($colnum) = $self->column_num_for_name($column);
219 16         27 return $self->entry_by_num($rownum,$colnum,$newvalue);
220             }
221              
222             =head2 get_entry
223              
224             Title : get_entry
225             Usage : my $entry = $matrix->get_entry($rowname,$columname)
226             Function: Get the entry for a given row,column pair
227             Returns : scalar
228             Args : $row name
229             $column name
230              
231              
232             =cut
233              
234 14     14 1 36 sub get_entry{ $_[0]->entry($_[1],$_[2]) }
235              
236             =head2 entry_by_num
237              
238             Title : entry_by_num
239             Usage : my $entry = $matrix->entry_by_num($rownum,$colnum)
240             Function: Get an entry by row and column numbers instead of by name
241             (rows and columns start at 0)
242             Returns : scalar value or undef if row or column name does not
243             exist
244             Args : $row - row number
245             $col - column number
246             [optional] $newvalue to store at this cell
247              
248             =cut
249              
250             sub entry_by_num {
251 169     169 1 128 my ($self,$row,$col,$newvalue) = @_;
252 169 50 33     752 if( ! defined $row || ! defined $col ||
      33        
      33        
253             $row !~ /^\d+$/ ||
254             $col !~ /^\d+$/ ) {
255 0         0 $self->warn("expected to get 2 number for entry_by_num");
256 0         0 return;
257             }
258            
259 169 100       175 if( defined $newvalue ) {
260 15         15 return $self->_values->[$row][$col] = $newvalue;
261             } else {
262 154         156 return $self->_values->[$row][$col];
263             }
264             }
265              
266             sub get_element {
267 0     0 0 0 my $self = shift;
268 0         0 $self->entry(@_);
269             }
270              
271              
272             =head2 column
273              
274             Title : column
275             Usage : my @col = $matrix->column('ALPHA');
276             OR
277             $matrix->column('ALPHA', \@col);
278             Function: Get/Set a particular column
279             Returns : Array (in array context) or arrayref (in scalar context)
280             of values.
281             For setting will warn if the new column is of a different
282             length from the rest of the columns.
283             Args : name of the column
284             [optional] new column to store here
285              
286             =cut
287              
288             sub column{
289 1     1 1 2 my ($self,$column,$newcol) = @_;
290              
291 1 50       3 if( ! defined $column ) {
292 0         0 $self->warn("Need at least a column id");
293 0         0 return;
294             }
295 1         2 my $colnum = $self->column_num_for_name($column);
296 1 50       3 if( ! defined $colnum ) {
297 0         0 $self->warn("could not find column number for $column");
298 0         0 return;
299             }
300 1         4 return $self->column_by_num($colnum,$newcol);
301             }
302              
303              
304             =head2 get_column
305              
306             Title : get_column
307             Usage : my @row = $matrix->get_column('ALPHA');
308             Function: Get a particular column
309             Returns : Array (in array context) or arrayref (in scalar context)
310             of values
311             Args : name of the column
312              
313              
314             =cut
315              
316 1     1 1 4 sub get_column { $_[0]->column($_[1]) }
317              
318              
319             =head2 column_by_num
320              
321             Title : column_by_num
322             Usage : my @col = $matrix->column_by_num(1);
323             OR
324             $matrix->column_by_num(1,\@newcol);
325             Function: Get/Set a column by its number instead of name
326             (cols/rows start at 0)
327             Returns : Array (in array context) or arrayref (in scalar context)
328             of values
329             Args : name of the column
330             [optional] new value to store for a particular column
331              
332             =cut
333              
334             sub column_by_num{
335 1     1 1 1 my ($self,$colnum,$newcol) = @_;
336 1 50       2 if( ! defined $colnum ) {
337 0         0 $self->warn("need at least a column number");
338 0         0 return;
339             }
340 1         2 my $rowcount = $self->num_rows;
341 1         4 my $colcount = $self->num_columns;
342 1         1 my $ret;
343            
344 1 50       3 if( defined $newcol ) {
345 0 0       0 if( ref($newcol) !~ /ARRAY/i) {
346 0         0 $self->warn("expected a valid arrayref for resetting a column");
347 0         0 return;
348             }
349 0 0       0 if( scalar @$newcol != $rowcount ) {
350 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");
351 0         0 return;
352             }
353 0         0 for(my $i=0; $i < $rowcount; $i++) {
354 0         0 $self->entry_by_num($i,$colnum,$newcol->[$i]);
355             }
356 0         0 $ret = $newcol;
357             } else {
358 1         1 $ret = [];
359 1         3 for(my $i=0; $i < $rowcount; $i++) {
360 3         5 push @$ret,$self->entry_by_num($i,$colnum);
361             }
362             }
363 1 50       3 if( wantarray ) { return @$ret }
  1         4  
364 0         0 return $ret;
365              
366             }
367              
368             =head2 row
369              
370             Title : row
371             Usage : my @row = $matrix->row($rowname);
372             OR
373             $matrix->row($rowname,\@rowvalues);
374             Function: Get/Set the row of the matrix
375             Returns : Array (in array context) or arrayref (in scalar context)
376             Args : rowname
377             [optional] new value of row to store
378              
379              
380             =cut
381              
382             sub row {
383 9     9 1 10 my ($self,$row,$newrow) = @_;
384 9 50       16 if( ! defined $row) {
385 0         0 $self->warn("Need at least a row id");
386 0         0 return;
387             }
388 9         12 my $rownum = $self->row_num_for_name($row);
389 9         15 return $self->row_by_num($rownum,$newrow);
390             }
391              
392              
393             =head2 get_row
394              
395             Title : get_row
396             Usage : my @row = $matrix->get_row('ALPHA');
397             Function: Get a particular row
398             Returns : Array (in array context) or arrayref (in scalar context)
399             of values
400             Args : name of the row
401              
402             =cut
403              
404 9     9 1 1531 sub get_row { $_[0]->row($_[1]) }
405              
406             =head2 row_by_num
407              
408             Title : row_by_num
409             Usage : my @row = $matrix->row_by_num($rownum);
410             OR
411             $matrix->row($rownum,\@rowvalues);
412             Function: Get/Set the row of the matrix
413             Returns : Array (in array context) or arrayref (in scalar context)
414             Args : rowname
415             [optional] new value of row to store
416              
417             =cut
418              
419             sub row_by_num{
420 9     9 1 10 my ($self,$rownum,$newrow) = @_;
421 9 50       13 if( ! defined $rownum ) {
422 0         0 $self->warn("need at least a row number");
423 0         0 return;
424             }
425 9         13 my $colcount = $self->num_columns;
426 9         6 my $ret;
427 9 50       12 if( defined $newrow ) {
428 0 0       0 if( ref($newrow) !~ /ARRAY/i) {
429 0         0 $self->warn("expected a valid arrayref for resetting a row");
430 0         0 return;
431             }
432 0 0       0 if( scalar @$newrow != $colcount ) {
433 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");
434 0         0 return;
435             }
436 0         0 for(my $i=0; $i < $colcount; $i++) {
437 0         0 $self->entry_by_num($rownum,$i, $newrow->[$i]);
438             }
439 0         0 $ret = $newrow;
440             } else {
441 9         9 $ret = [];
442 9         13 for(my $i=0; $i < $colcount; $i++) {
443             # we're doing this to explicitly
444             # copy the entire row
445 87         92 push @$ret, $self->entry_by_num($rownum,$i);
446             }
447             }
448 9 50       12 if( wantarray ) { return @$ret }
  9         45  
449 0         0 return $ret;
450              
451              
452             }
453              
454              
455             =head2 diagonal
456              
457             Title : diagonal
458             Usage : my @diagonal = $matrix->get_diagonal()
459             Function: Get the diagonal of a matrix
460             Returns : Array (in array context) or arrayref (in scalar context)
461             of values which lie along the diagonal
462             Args : none
463              
464              
465             =cut
466              
467             sub get_diagonal{
468 2     2 1 3 my ($self) = @_;
469 2         2 my @diag;
470 2         5 my $rowcount = $self->num_rows;
471 2         4 my $colcount = $self->num_columns;
472 2         5 for(my $i = 0; $i < $rowcount; $i++ ) {
473 48         48 push @diag, $self->entry_by_num($i,$i);
474             }
475 2         17 return @diag;
476             }
477              
478              
479             =head2 add_row
480              
481             Title : add_row
482             Usage : $matrix->add_row($index,\@newrow);
483             Function: Adds a row at particular location in the matrix.
484             If $index < the rowcount will shift all the rows down
485             by the number of new rows.
486             To add a single empty row, simply call
487             $matrix->add_row($index,undef);
488             Returns : the updated number of total rows in the matrix
489             Args : index to store
490             name of the row (header)
491             newrow to add, if this is undef will add a single
492             row with all values set to undef
493              
494             =cut
495              
496             sub add_row{
497 2     2 1 3 my ($self,$index,$name,$newrow) = @_;
498 2 50 33     20 if( !defined $index ||
    50          
    50          
499             $index !~ /^\d+$/ ) {
500 0         0 $self->warn("expected a valid row index in add_row");
501 0         0 return;
502             } elsif( ! defined $name) {
503 0         0 $self->warn("Need a row name or heading");
504 0         0 return;
505             } elsif( defined $self->row_num_for_name($name) ) {
506 0         0 $self->warn("Need a unqiue name for the column heading, $name is already used");
507 0         0 return;
508             }
509 2         5 my $colcount = $self->num_columns;
510 2         3 my $rowcount = $self->num_rows;
511              
512 2 50       4 if( $index > $rowcount ) {
513 0         0 $self->warn("cannot add a row beyond 1+last row at the end ($rowcount) not $index - adding at $rowcount instead");
514 0         0 $index = $rowcount;
515             }
516              
517 2 50       11 if( ! defined $newrow ) {
    50          
518 0         0 $newrow = [];
519 0         0 $newrow->[$colcount] = undef;
520             } elsif( ref($newrow) !~ /ARRAY/i ) {
521 0         0 $self->throw("Expected either undef or a valid arrayref for add_row");
522             }
523             # add this row to the matrix by carving out space for it with
524             # splice
525 2         2 splice(@{$self->{'_values'}}, $index,0,[]);
  2         5  
526 2         6 for( my $i = 0; $i < $colcount; $i++ ) {
527 7         9 $self->entry_by_num($index,$i,$newrow->[$i]);
528             }
529 2         2 splice(@{$self->{'_rownames'}}, $index,0,$name);
  2         5  
530             # Sadly we have to remap these each time (except for the case
531             # when we're adding a new column to the end, but I don't think
532             # the speedup for that case warrants the extra code at this time.
533 2         3 my $ct = 0;
534 2         1 %{$self->{'_rownamesmap'}} = map { $_ => $ct++} @{$self->{'_rownames'}};
  2         6  
  9         10  
  2         3  
535 2         5 return $self->num_rows;
536             }
537              
538             =head2 remove_row
539              
540             Title : remove_row
541             Usage : $matrix->remove_row($colnum)
542             Function: remove a row from the matrix shifting all the rows
543             up by one
544             Returns : Updated number of rows in the matrix
545             Args : row index
546              
547              
548             =cut
549              
550             sub remove_row{
551 1     1 1 2 my ($self,$rowindex) = @_;
552 1         2 my $rowcount = $self->num_rows;
553            
554 1 50       3 if( $rowindex > $rowcount ) {
555 0         0 $self->warn("rowindex $rowindex is greater than number of rows $rowcount, cannot process");
556 0         0 return 0;
557             } else {
558 1         1 splice(@{$self->_values},$rowindex,1);
  1         2  
559 1         3 delete $self->{'_rownamesmap'}->{$self->{'_rownames'}->[$rowindex]};
560 1         1 splice(@{$self->{'_rownames'}},$rowindex,1);
  1         2  
561             }
562 1         2 my $ct = 0;
563 1         2 %{$self->{'_rownamesmap'}} = map { $_ => $ct++} @{$self->{'_rownames'}};
  1         3  
  4         6  
  1         1  
564 1         2 return $self->num_rows;
565             }
566              
567             =head2 add_column
568              
569             Title : add_column
570             Usage : $matrix->add_column($index,$colname,\@newcol);
571             Function: Adds a column at particular location in the matrix.
572             If $index < the colcount will shift all the columns right
573             by the number of new columns.
574             To add a single empty column, simply call
575             $matrix->add_column($index,undef);
576             Returns : the updated number of total columns in the matrix
577             Args : index to store
578             name of the column (header)
579             newcolumn to add, if this is undef will add a single
580             column with all values set to undef
581              
582              
583             =cut
584              
585              
586             sub add_column{
587 2     2 1 4 my ($self,$index,$name,$newcol) = @_;
588 2 50 33     22 if( !defined $index ||
    50          
    50          
589             $index !~ /^\d+$/ ) {
590 0         0 $self->warn("expected a valid col index in add_column");
591 0         0 return;
592             } elsif( ! defined $name) {
593 0         0 $self->warn("Need a column name or heading");
594 0         0 return;
595             } elsif( defined $self->column_num_for_name($name) ) {
596 0         0 $self->warn("Need a unqiue name for the column heading, $name is already used");
597 0         0 return;
598             }
599 2         5 my $colcount = $self->num_columns;
600 2         3 my $rowcount = $self->num_rows;
601 2 50       4 if( $index > $colcount ) {
602 0         0 $self->warn("cannot add a column beyond 1+last column at the end ($colcount) not $index - adding at $colcount instead");
603 0         0 $index = $colcount;
604             }
605              
606 2 50       9 if( ! defined $newcol ) {
    50          
607 0         0 $newcol = [];
608 0         0 $newcol->[$rowcount] = undef; # make the array '$rowcount' long
609             } elsif( ref($newcol) !~ /ARRAY/i ) {
610 0         0 $self->throw("Expected either undef or a valid arrayref for add_row");
611             }
612 2         5 for( my $i = 0; $i < $rowcount; $i++ ) {
613             # add this column to each row
614 8         6 splice(@{$self->_values->[$i]},$index,0,[]);
  8         9  
615 8         11 $self->entry_by_num($i,$index,$newcol->[$i]);
616             }
617 2         1 splice(@{$self->{'_colnames'}}, $index,0,$name);
  2         5  
618             # Sadly we have to remap these each time (except for the case
619             # when we're adding a new column to the end, but I don't think
620             # the speedup for that case warrants the extra code at this time.
621 2         2 my $ct = 0;
622 2         1 %{$self->{'_colnamesmap'}} = map {$_ => $ct++} @{$self->{'_colnames'}};
  2         7  
  9         10  
  2         3  
623 2         5 return $self->num_columns;
624             }
625              
626             =head2 remove_column
627              
628             Title : remove_column
629             Usage : $matrix->remove_column($colnum)
630             Function: remove a column from the matrix shifting all the columns
631             to the left by one
632             Returns : Updated number of columns in the matrix
633             Args : column index
634              
635             =cut
636              
637             sub remove_column{
638 1     1 1 2 my ($self,$colindex) = @_;
639              
640 1         3 my $colcount = $self->num_columns;
641 1         2 my $rowcount = $self->num_rows;
642 1 50       3 if( $colindex > $colcount ) {
643 0         0 $self->warn("colindex $colindex is greater than number of columns ($colcount), cannot process");
644 0         0 return 0;
645             } else {
646 1         4 for(my $i = 0; $i < $rowcount; $i++ ) {
647 4         4 splice(@{$self->_values->[$i]},$colindex,1);
  4         4  
648             }
649 1         3 delete $self->{'_colnamesmap'}->{$self->{'_colnames'}->[$colindex]};
650 1         1 splice(@{$self->{'_colnames'}},$colindex,1);
  1         2  
651             }
652 1         2 my $ct = 0;
653 1         1 %{$self->{'_colnamesmap'}} = map {$_ => $ct++} @{$self->{'_colnames'}};
  1         3  
  4         4  
  1         2  
654 1         3 return $self->num_columns;
655             }
656              
657             =head2 column_num_for_name
658              
659             Title : column_num_for_name
660             Usage : my $num = $matrix->column_num_for_name($name)
661             Function: Gets the column number for a particular column name
662             Returns : integer
663             Args : string
664              
665              
666             =cut
667              
668             sub column_num_for_name{
669 23     23 1 24 my ($self,$name) = @_;
670            
671 23         33 return $self->{'_colnamesmap'}->{$name};
672             }
673              
674             =head2 row_num_for_name
675              
676             Title : row_num_for_name
677             Usage : my $num = $matrix->row_num_for_name
678             Function: Gets the row number for a particular row name
679             Returns : integer
680             Args : string
681              
682              
683             =cut
684              
685             sub row_num_for_name{
686 30     30 1 911 my ($self,$name) = @_;
687 30         53 return $self->{'_rownamesmap'}->{$name}
688             }
689              
690              
691             =head2 column_header
692              
693             Title : column_header
694             Usage : my $name = $matrix->column_header(0)
695             Function: Gets the column header for a particular column number
696             Returns : string
697             Args : integer
698              
699              
700             =cut
701              
702             sub column_header{
703 2     2 1 3 my ($self,$num) = @_;
704 2         7 return $self->{'_colnames'}->[$num];
705             }
706              
707              
708             =head2 row_header
709              
710             Title : row_header
711             Usage : my $name = $matrix->row_header(0)
712             Function: Gets the row header for a particular row number
713             Returns : string
714             Args : integer
715              
716              
717             =cut
718              
719             sub row_header{
720 2     2 1 3 my ($self,$num) = @_;
721 2         6 return $self->{'_rownames'}->[$num];
722             }
723              
724             =head2 num_rows
725              
726             Title : num_rows
727             Usage : my $rowcount = $matrix->num_rows;
728             Function: Get the number of rows
729             Returns : integer
730             Args : none
731              
732              
733             =cut
734              
735             sub num_rows{
736 14     14 1 15 my ($self) = @_;
737 14         9 return scalar @{$self->_values};
  14         41  
738             }
739              
740              
741             =head2 num_columns
742              
743             Title : num_columns
744             Usage : my $colcount = $matrix->num_columns
745             Function: Get the number of columns
746             Returns : integer
747             Args : none
748              
749              
750             =cut
751              
752             sub num_columns{
753 21     21 1 18 my ($self) = @_;
754 21 50       13 return scalar @{$self->_values->[0] || []};
  21         25  
755             }
756              
757              
758             =head2 row_names
759              
760             Title : row_names
761             Usage : my @rows = $matrix->row_names
762             Function: The names of all the rows
763             Returns : array in array context, arrayref in scalar context
764             Args : none
765              
766              
767             =cut
768              
769             sub row_names{
770 0 0   0 1 0 if( wantarray ) {
771 0         0 return @{shift->{'_rownames'}};
  0         0  
772             } else {
773 0         0 return shift->{'_rownames'};
774             }
775             }
776              
777              
778             =head2 column_names
779              
780             Title : column_names
781             Usage : my @columns = $matrix->column_names
782             Function: The names of all the columns
783             Returns : array in array context, arrayref in scalar context
784             Args : none
785              
786              
787             =cut
788              
789             sub column_names{
790 0 0   0 1 0 if( wantarray ) {
791 0         0 return @{shift->{'_colnames'}};
  0         0  
792             } else {
793 0         0 return shift->{'_colnames'};
794             }
795             }
796              
797             =head2 private methods
798              
799             Private methods for a Generic Matrix
800              
801             =head2 _values
802              
803             Title : _values
804             Usage : $matrix->_values();
805             Function: get/set for array ref of the matrix containing
806             distance values
807             Returns : an array reference
808             Args : an array reference
809              
810              
811             =cut
812              
813             sub _values{
814 217     217   155 my ($self,$val) = @_;
815 217 50       230 if( $val ){
816 0         0 $self->{'_values'} = $val;
817             }
818 217         527 return $self->{'_values'};
819             }
820              
821             1;