comparison lib/Matrix.pm @ 0:4816e4a8ae95 draft default tip

Uploaded
author deepakjadmin
date Wed, 20 Jan 2016 09:23:18 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4816e4a8ae95
1 package Matrix;
2 #
3 # $RCSfile: Matrix.pm,v $
4 # $Date: 2015/02/28 20:47:17 $
5 # $Revision: 1.16 $
6 #
7 # Author: Manish Sud <msud@san.rr.com>
8 #
9 # Copyright (C) 2015 Manish Sud. All rights reserved.
10 #
11 # This file is part of MayaChemTools.
12 #
13 # MayaChemTools is free software; you can redistribute it and/or modify it under
14 # the terms of the GNU Lesser General Public License as published by the Free
15 # Software Foundation; either version 3 of the License, or (at your option) any
16 # later version.
17 #
18 # MayaChemTools is distributed in the hope that it will be useful, but without
19 # any warranty; without even the implied warranty of merchantability of fitness
20 # for a particular purpose. See the GNU Lesser General Public License for more
21 # details.
22 #
23 # You should have received a copy of the GNU Lesser General Public License
24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
26 # Boston, MA, 02111-1307, USA.
27 #
28
29 use strict;
30 use Carp;
31 use Exporter;
32 use Scalar::Util ();
33 use Vector;
34
35 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
36
37 @ISA = qw(Exporter);
38 @EXPORT = qw(IsMatrix IdentityMatrix NewFromRows NewFromColumns NewFromDiagonal UnitMatrix ZeroMatrix);
39 @EXPORT_OK = qw(SetValuePrintFormat);
40
41 %EXPORT_TAGS = (
42 all => [@EXPORT, @EXPORT_OK]
43 );
44
45 # Setup class variables...
46 my($ClassName, $ValueFormat, $MatrixPrintStyle);
47 _InitializeClass();
48
49 #
50 # Using the following explicity overloaded operators, Perl automatically generates methods
51 # for operations with no explicitly defined methods. Autogenerated methods are possible for
52 # these operators:
53 #
54 # o Arithmetic operators: += -= *= /= **= %= ++ -- x= .=
55 # o Increment and decrement: ++ --
56 #
57 # 'fallback' is set to 'false' to raise exception for all other operators.
58 #
59 use overload '""' => 'StringifyMatrix',
60
61 '@{}' => '_MatrixToArrayOperator',
62
63 '+' => '_MatrixAdditionOperator',
64 '-' => '_MatrixSubtractionOperator',
65 '*' => '_MatrixMultiplicationOperator',
66 '/' => '_MatrixDivisionOperator',
67 '**' => '_MatrixExponentiationOperator',
68 '%' => '_MatrixModulusOperator',
69
70 'bool' => '_MatrixBooleanOperator',
71 '!' => '_MatrixNotBooleanOperator',
72
73 '==' => '_MatrixEqualOperator',
74 '!=' => '_MatrixNotEqualOperator',
75 '<' => '_MatrixLessThanOperator',
76 '<=' => '_MatrixLessThanEqualOperator',
77 '>' => '_MatrixGreatarThanOperator',
78 '>=' => '_MatrixGreatarThanEqualOperator',
79
80 'neg' => '_MatrixNegativeValueOperator',
81
82 'abs' => '_MatrixAbsoluteValueOperator',
83 'exp' => '_MatrixExpNaturalBaseOperator',
84 'log' => '_MatrixLogNaturalBaseOperator',
85 'sqrt' => '_MatrixSquareRootOperator',
86 'cos' => '_MatrixCosineOperator',
87 'sin' => '_MatrixSineOperator',
88
89 'fallback' => undef;
90
91 # Class constructor...
92 sub new {
93 my($Class, $NumOfRows, $NumOfCols) = @_;
94
95 # Initialize object...
96 my $This = {};
97 bless $This, ref($Class) || $Class;
98 $This->_InitializeMatrix($NumOfRows, $NumOfCols);
99
100 return $This;
101 }
102
103 # Initialize object data...
104 #
105 sub _InitializeMatrix {
106 my($This, $NumOfRows, $NumOfCols) = @_;
107
108 if (!(defined($NumOfRows) && defined($NumOfCols))) {
109 croak "Error: ${ClassName}->_InitializeMatrix: NumOfRows and NumOfCols must be specified...";
110 }
111 if (!(($NumOfRows > 0) && ($NumOfRows > 0))) {
112 croak "Error: ${ClassName}->_InitializeMatrix: NumOfRows and NumOfCols must be a positive number...";
113 }
114 # Initialize matrix elements to zero...
115 @{$This->{Values}} = ();
116
117 my($RowIndex, @EmptyRow);
118
119 @EmptyRow = ();
120 @EmptyRow = ('0') x $NumOfCols;
121
122 for $RowIndex (0 .. ($NumOfRows - 1)) {
123 @{$This->{Values}[$RowIndex]} = ();
124 @{$This->{Values}[$RowIndex]} = @EmptyRow;
125 }
126 }
127
128 # Initialize class ...
129 sub _InitializeClass {
130 #Class name...
131 $ClassName = __PACKAGE__;
132
133 # Print style for matrix rows during StringifyMatrix operation.
134 # Possible values: AllRowsInOneLine, OneRowPerLine
135 #
136 $MatrixPrintStyle = "AllRowsInOneLine";
137
138 # Print format for matrix values...
139 $ValueFormat = "%g";
140 }
141
142 # Get matrix size...
143 #
144 sub GetSize {
145 my($This) = @_;
146
147 return ($This->GetNumOfRows(), $This->GetNumOfColumns());
148 }
149
150 # Get matrix dimensions...
151 #
152 sub GetDimension {
153 my($This) = @_;
154
155 return $This->GetSize();
156 }
157
158 # Get number of rows in matrix
159 #
160 sub GetNumOfRows {
161 my($This) = @_;
162 my($NumOfRows);
163
164 # Size of row array...
165 $NumOfRows = $#{$This->{Values}} + 1;
166
167 return $NumOfRows;
168 }
169
170 # Get number of columns in matrix
171 #
172 sub GetNumOfColumns {
173 my($This) = @_;
174 my($NumOfCols);
175
176 # Size of column array for first row assuming sizes of columns are same...
177 $NumOfCols = $#{$This->{Values}[0]} + 1;
178
179 return $NumOfCols;
180 }
181
182 # Get reference to array holding matrix values in order to directly manipulate these values...
183 #
184 sub GetMatrixValuesReference {
185 my($This) = @_;
186
187 return \@{$This->{Values}};
188 }
189
190 # Copy matrix...
191 #
192 sub Copy {
193 my($This) = @_;
194 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $Matrix);
195
196 # Create a new matrix...
197 ($NumOfRows, $NumOfCols) = $This->GetSize();
198 $Matrix = new Matrix($NumOfRows, $NumOfCols);
199
200 # Set matrix values...
201 for $RowIndex (0 .. ($NumOfRows -1)) {
202 for $ColIndex (0 .. ($NumOfCols -1)) {
203 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex];
204 }
205 }
206 return $Matrix;
207 }
208
209 # Create a new matrix using rows specified in one of the following formats:
210 # o List of vector objects
211 # o References to list of values
212 # o List of strings containing row values delimited by space
213 #
214 # Each row must contain the same number of values.
215 #
216 # This functionality can be either invoked as a class function or an
217 # object method.
218 #
219 sub NewFromRows {
220 my($FirstParameter, @OtherParamaters) = @_;
221
222 if (IsMatrix($FirstParameter)) {
223 return _NewFromRowsOrColumns('FromRows', @OtherParamaters);
224 }
225 else {
226 return _NewFromRowsOrColumns('FromRows', @_);
227 }
228 }
229
230 # Create a new matrix using columns specified in one of the following formats:
231 # o List of vector objects
232 # o References to list of values
233 # o List of strings containing columns values delimited by space
234 #
235 # Each columns must contain the same number of values.
236 #
237 # This functionality can be either invoked as a class function or an
238 # object method.
239 #
240 sub NewFromColumns {
241 my($FirstParameter, @OtherParamaters) = @_;
242
243 if (IsMatrix($FirstParameter)) {
244 return _NewFromRowsOrColumns('FromColumns', @OtherParamaters);
245 }
246 else {
247 return _NewFromRowsOrColumns('FromColumns', @_);
248 }
249 }
250
251 # Create a new matrix using diagonal values specified in one of the following formats:
252 # o A vector object
253 # o Reference to list of values
254 # o Strings containing diagonal values delimited by space
255 #
256 # This functionality can be either invoked as a class function or an
257 # object method.
258 #
259 sub NewFromDiagonal {
260 my($FirstParameter, @OtherParamaters) = @_;
261
262 if (IsMatrix($FirstParameter)) {
263 return _NewFromDiagonal(@OtherParamaters);
264 }
265 else {
266 return _NewFromDiagonal(@_);
267 }
268 }
269
270 # Create a new matrix using diagonal values specified in one of the following formats:
271 # o A vector object
272 # o Reference to list of values
273 # o Strings containing diagonal values delimited by space
274 #
275 sub _NewFromDiagonal {
276 my(@SpecifiedDiagonalValues) = @_;
277 my($ErrorMsgPrefix, $CheckSizes, $CombineValues, $ValuesRefs, $DiagonalValuesRef);
278
279 $ErrorMsgPrefix = "Error: ${ClassName}::_NewFromDiagonal";
280 if (!@SpecifiedDiagonalValues) {
281 croak "$ErrorMsgPrefix: No diagonal values specified...";
282 }
283
284 # Collect specified diagonal values...
285 $CheckSizes = 0; $CombineValues = 1;
286 $ValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedDiagonalValues);
287 $DiagonalValuesRef = $ValuesRefs->[0];
288
289 # Create a new matrix...
290 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex);
291
292 $NumOfRows = @{$DiagonalValuesRef};
293 $NumOfCols = $NumOfRows;
294
295 $Matrix = new Matrix($NumOfRows, $NumOfCols);
296
297 # Set diagonal values...
298 for $RowIndex (0 .. ($NumOfRows - 1)) {
299 $Matrix->{Values}[$RowIndex][$RowIndex] = $DiagonalValuesRef->[$RowIndex];
300 }
301
302 return $Matrix;
303 }
304
305 # Create a new matrix using rows or columns specified in one of the following formats:
306 # o List of vector objects
307 # o References to list of values
308 # o List of strings containing row values delimited by space
309 #
310 # Each row or column must contain the same number of values.
311 #
312 sub _NewFromRowsOrColumns {
313 my($Mode, @SpecifiedValues) = @_;
314
315 if ($Mode !~ /^(FromRows|FromColumns)$/i) {
316 croak "Error: ${ClassName}::_NewFromRowsOrColumns: Unknown mode: $Mode...";
317 }
318 my($ErrorMsgPrefix, $CheckSizes, $CombineValues, $ValuesRefs);
319
320 # Retrieve information about specified values and make sure similar number of values
321 # are specified for each row or column...
322 if ($Mode =~ /^FromRows$/i) {
323 $ErrorMsgPrefix = "Error: ${ClassName}::_NewFromRows";
324 }
325 else {
326 $ErrorMsgPrefix = "Error: ${ClassName}::_NewFromColumns";
327 }
328 $CheckSizes = 1; $CombineValues = 0;
329 $ValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedValues);
330
331 # Create a new matrix...
332 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $RowMode, $Value);
333
334 if ($Mode =~ /^FromRows$/i) {
335 $NumOfRows = scalar @{$ValuesRefs};
336 $NumOfCols = scalar @{$ValuesRefs->[0]};
337 $RowMode = 1;
338 }
339 elsif ($Mode =~ /^FromColumns$/i) {
340 $NumOfRows = scalar @{$ValuesRefs->[0]};
341 $NumOfCols = scalar @{$ValuesRefs};
342 $RowMode = 0;
343 }
344 $Matrix = new Matrix($NumOfRows, $NumOfCols);
345
346 # Setup matrix values...
347 for $RowIndex (0 .. ($NumOfRows - 1)) {
348 for $ColIndex (0 .. ($NumOfCols - 1)) {
349 $Value = $RowMode ? $ValuesRefs->[$RowIndex]->[$ColIndex]: $ValuesRefs->[$ColIndex]->[$RowIndex];
350 $Matrix->{Values}[$RowIndex][$ColIndex] = $Value;
351 }
352 }
353
354 return $Matrix;
355 }
356
357 # Process specified matrix values in any of the following supported formats:
358 #
359 # o List of vector objects
360 # o References to list of values
361 # o List of strings containing row values delimited by space
362 #
363 # And return a reference to an array containing references to arrays with specified values.
364 #
365 # Value of CombineValuesStatus determines whether all the values specified are combined
366 # into one array and return its reference as the only entry in the array being returned.
367 #
368 sub _ProcessSpecifiedMatrixValues {
369 my($ErrorMsgPrefix, $CheckSizesStatus, $CombineValuesStatus, @SpecifiedValues) = @_;
370 my($Value, $TypeOfValue, @ValuesRefs);
371
372 @ValuesRefs = ();
373 if (!@SpecifiedValues) {
374 croak "$ErrorMsgPrefix: No values specified...";
375 }
376
377 # Collect values...
378 for $Value (@SpecifiedValues) {
379 $TypeOfValue = ref $Value;
380
381 if (Vector::IsVector($Value)) {
382 # Feference to vector object...
383 my($ValuesRef);
384 $ValuesRef = $Value->GetValues();
385 if (!@{$ValuesRef}) {
386 croak "$ErrorMsgPrefix: Specified vector object must contain some values...";
387 }
388 push @ValuesRefs, $ValuesRef;
389 }
390 elsif ($TypeOfValue =~ /^ARRAY/) {
391 # Refernece to an array...
392 if (!@{$Value}) {
393 croak "$ErrorMsgPrefix: Specified array reference must contain some values...";
394 }
395 push @ValuesRefs, $Value;
396 }
397 elsif ($TypeOfValue eq '') {
398 # String value...
399 my(@Values);
400 @Values = split(' ', $Value);
401 if (!@Values) {
402 croak "$ErrorMsgPrefix: Specified string must contain some values...";
403 }
404 push @ValuesRefs, \@Values;
405 }
406 else {
407 croak "$ErrorMsgPrefix: Value format, $TypeOfValue, of a specified value to be added to matrix object is not supported...";
408 }
409 }
410
411 # Combine all specified values into one array...
412 if ($CombineValuesStatus) {
413 my($ValuesRef, @Values);
414
415 @Values = ();
416 for $ValuesRef (@ValuesRefs) {
417 push @Values, @{$ValuesRef};
418 }
419 @ValuesRefs = ();
420 push @ValuesRefs, \@Values;
421 }
422
423 # Make sure reference to all specified value arrays contain the same number of values...
424 if ($CheckSizesStatus) {
425 my($Index, $FirstValueSize);
426 $FirstValueSize = $#{$ValuesRefs[0]};
427 for $Index (1 .. $#ValuesRefs) {
428 if ($FirstValueSize != $#{$ValuesRefs[$Index]}) {
429 croak "$ErrorMsgPrefix: Number of values in each specified value type to be added to matrix object must be same...";
430 }
431 }
432 }
433
434 return \@ValuesRefs;
435 }
436
437 # Create a new zero matrix of specified size or default size of 3 x 3.
438 #
439 # This functionality can be either invoked as a class function or an
440 # object method.
441 #
442 sub ZeroMatrix (;$$$) {
443 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
444 my($This, $NumOfRows, $NumOfCols, $Matrix);
445
446 $This = undef;
447 if (defined($FirstParameter) && IsMatrix($FirstParameter)) {
448 ($This, $NumOfRows, $NumOfCols) = ($FirstParameter, $SecondParameter, $ThirdParameter);
449 }
450 else {
451 ($This, $NumOfRows, $NumOfCols) = (undef, $FirstParameter, $SecondParameter);
452 }
453 ($NumOfRows, $NumOfCols) = (defined($NumOfRows) && defined($NumOfCols)) ? ($NumOfRows, $NumOfCols) : (3, 3);
454
455 # Set up a new zero matrix
456 $Matrix = new Matrix($NumOfRows, $NumOfCols);
457
458 return $Matrix;
459 }
460
461 # Create a new unit matrix of specified size or default size of 3 x 3.
462 #
463 # This functionality can be either invoked as a class function or an
464 # object method.
465 #
466 sub UnitMatrix (;$$$) {
467 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
468 my($This, $NumOfRows, $NumOfCols, $Matrix, $RowIndex);
469
470 $This = undef;
471 if (defined($FirstParameter) && IsMatrix($FirstParameter)) {
472 ($This, $NumOfRows, $NumOfCols) = ($FirstParameter, $SecondParameter, $ThirdParameter);
473 }
474 else {
475 ($This, $NumOfRows, $NumOfCols) = (undef, $FirstParameter, $SecondParameter);
476 }
477 ($NumOfRows, $NumOfCols) = (defined($NumOfRows) && defined($NumOfCols)) ? ($NumOfRows, $NumOfCols) : (3, 3);
478
479 # Set up a new zero matrix
480 $Matrix = new Matrix($NumOfRows, $NumOfCols);
481
482 if ($NumOfRows != $NumOfCols) {
483 carp "Warning: ${ClassName}::UnitMatrix: Specified matrix, $NumOfRows x $NumOfCols, is not a square matrix...";
484 }
485
486 # Initialize diagonal elements to 1...
487 for $RowIndex (0 .. ($NumOfRows - 1)) {
488 $Matrix->{Values}[$RowIndex][$RowIndex] = 1.0;
489 }
490
491 return $Matrix;
492 }
493
494 # Identity matrix of specified size or size 3 x 3...
495 #
496 sub IdentityMatrix (;$$$) {
497 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
498
499 return UnitMatrix($FirstParameter, $SecondParameter, $ThirdParameter);
500 }
501
502 # Set all matrix values to 0s...
503 #
504 sub Zero {
505 my($This) = @_;
506
507 return $This->SetAllValues(0.0);
508 }
509
510 # Set all matrix values to 1s...
511 #
512 sub One {
513 my($This) = @_;
514
515 return $This->SetAllValues(1.0);
516 }
517
518 # Get a matrix value with row and column indicies starting from 0...
519 #
520 sub GetValue {
521 my($This, $RowIndex, $ColIndex, $SkipIndexCheck) = @_;
522
523 if ($SkipIndexCheck) {
524 $This->_GetValue($RowIndex, $ColIndex);
525 }
526
527 $This->_ValidateRowAndColumnIndicies("Error: ${ClassName}::GetValue", $RowIndex, $ColIndex);
528
529 return $This->_GetValue($RowIndex, $ColIndex);
530 }
531
532 # Get a matrix value...
533 #
534 sub _GetValue {
535 my($This, $RowIndex, $ColIndex) = @_;
536
537 return $This->{Values}[$RowIndex][$ColIndex];
538 }
539
540 # Set a matrix value with row and column indicies starting from 0...
541 #
542 sub SetValue {
543 my($This, $RowIndex, $ColIndex, $Value, $SkipIndexCheck) = @_;
544
545 if ($SkipIndexCheck) {
546 $This->_SetValue($RowIndex, $ColIndex, $Value);
547 }
548
549 $This->_ValidateRowAndColumnIndicies("Error: ${ClassName}::SetValue", $RowIndex, $ColIndex);
550
551 return $This->_SetValue($RowIndex, $ColIndex, $Value);
552 }
553
554 # Set a matrix value...
555 #
556 sub _SetValue {
557 my($This, $RowIndex, $ColIndex, $Value) = @_;
558
559 $This->{Values}[$RowIndex][$ColIndex] = $Value;
560
561 return $This;
562 }
563
564 # Set all matrix values to a specified value...
565 #
566 sub SetAllValues {
567 my($This, $Value) = @_;
568 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
569
570 ($NumOfRows, $NumOfCols) = $This->GetSize();
571 for $RowIndex (0 .. ($NumOfRows - 1)) {
572 for $ColIndex (0 .. ($NumOfCols - 1)) {
573 $This->{Values}[$RowIndex][$ColIndex] = $Value;
574 }
575 }
576 return $This;
577 }
578
579 # Set values of a row in a matrix value with row index starting from 0...
580 #
581 sub SetRowValues {
582 my($This, $RowIndex, @SpecifiedValues) = @_;
583 my($NumOfRows, $NumOfCols, $ColIndex, $ErrorMsgPrefix, $CheckSizes, $CombineValues, $ValuesRefs, $RowValuesRef, $NumOfRowValues);
584
585 $ErrorMsgPrefix = "Error: ${ClassName}->SetRowValues";
586
587 ($NumOfRows, $NumOfCols) = $This->GetSize();
588 $This->_ValidateRowIndex($ErrorMsgPrefix, $RowIndex);
589
590 # Collect specified row values...
591 $CheckSizes = 0; $CombineValues = 1;
592 $ValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedValues);
593 $RowValuesRef = $ValuesRefs->[0];
594
595 # Check number of specified row values...
596 $NumOfRowValues = @{$RowValuesRef};
597 if ($NumOfRowValues != $NumOfCols) {
598 croak "$ErrorMsgPrefix: Number of specified row values, $NumOfRowValues, must be equal to number of row values, $NumOfCols, in matrix...";
599 }
600
601 # Set row values...
602 for $ColIndex (0 .. ($NumOfRowValues - 1)) {
603 $This->{Values}[$RowIndex][$ColIndex] = $RowValuesRef->[$ColIndex];
604 }
605 return $This;
606 }
607
608 # Add new row values to a matrix...
609 #
610 sub AddRowValues {
611 my($This, @SpecifiedValues) = @_;
612 my($NumOfRows, $NumOfCols, $RowIndex, $ErrorMsgPrefix, $CheckSizes, $CombineValues, $RowValueRef, $RowValuesRefs, $NumOfNewRows, $NumOfNewCols);
613
614 $ErrorMsgPrefix = "Error: ${ClassName}->AddRowValues";
615
616 ($NumOfRows, $NumOfCols) = $This->GetSize();
617
618 # Collect specified row values...
619 $CheckSizes = 1; $CombineValues = 0;
620 $RowValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedValues);
621
622 # Check number of specified row values...
623 $NumOfNewRows = scalar @{$RowValuesRefs};
624 $NumOfNewCols = scalar @{$RowValuesRefs->[0]};
625
626 if ($NumOfNewCols != $NumOfCols) {
627 croak "$ErrorMsgPrefix: Number of values in each specified row, $NumOfNewCols, must be equal to number of row values, $NumOfCols, in matrix...";
628 }
629
630 # Add each row to the matrix...
631 $RowIndex = $NumOfRows - 1;
632 for $RowValueRef (@{$RowValuesRefs}) {
633 $RowIndex++;
634 @{$This->{Values}[$RowIndex]} = @{$RowValueRef};
635 }
636
637 return $This;
638 }
639
640 # Get values of a row in matrix as an array. In scalar context, number of row
641 # values is returned...
642 #
643 sub GetRowValues {
644 my($This, $RowIndex) = @_;
645
646 return $This->_GetRowOrColumnValues('AsArray', 'FromRow', $RowIndex);
647 }
648
649 # Get values of a row in matrix as a vector object...
650 #
651 sub GetRowValuesAsVector {
652 my($This, $RowIndex) = @_;
653
654 return $This->_GetRowOrColumnValues('AsVector', 'FromRow', $RowIndex);
655 }
656
657 # Get values of a row as row matrix object...
658 #
659 sub GetRowValuesAsRowMatrix {
660 my($This, $RowIndex) = @_;
661
662 return $This->_GetRowOrColumnValues('AsRowMatrix', 'FromRow', $RowIndex);
663 }
664
665 # Get values of a row as column matrix object...
666 #
667 sub GetRowValuesAsColumnMatrix {
668 my($This, $RowIndex) = @_;
669
670 return $This->_GetRowOrColumnValues('AsColumnMatrix', 'FromRow', $RowIndex);
671 }
672
673 # Get values of a row in matrix as a space delimited string...
674 #
675 sub GetRowValuesAsString {
676 my($This, $RowIndex) = @_;
677
678 return $This->_GetRowOrColumnValues('AsString', 'FromRow', $RowIndex);
679 }
680
681 # Set values of a column in a matrix value with row index starting from 0...
682 #
683 sub SetColumnValues {
684 my($This, $ColIndex, @SpecifiedValues) = @_;
685 my($NumOfRows, $NumOfCols, $RowIndex, $ErrorMsgPrefix, $CheckSizes, $CombineValues, $ValuesRefs, $ColValuesRef, $NumOfColValues);
686
687 $ErrorMsgPrefix = "Error: ${ClassName}->SetColumnValues";
688
689 ($NumOfRows, $NumOfCols) = $This->GetSize();
690 $This->_ValidateColumnIndex($ErrorMsgPrefix, $ColIndex);
691
692 # Collect specified row values...
693 $CheckSizes = 0; $CombineValues = 1;
694 $ValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedValues);
695 $ColValuesRef = $ValuesRefs->[0];
696
697 # Check number of specified col values...
698 $NumOfColValues = @{$ColValuesRef};
699 if ($NumOfColValues != $NumOfRows) {
700 croak "$ErrorMsgPrefix: Number of specified col values, $NumOfColValues, must be equal to number of column values, $NumOfRows, in matrix...";
701 }
702
703 # Set col values...
704 for $RowIndex (0 .. ($NumOfColValues - 1)) {
705 $This->{Values}[$RowIndex][$ColIndex] = $ColValuesRef->[$RowIndex];
706 }
707 return $This;
708 }
709
710 # Add new column values to a matrix...
711 #
712 sub AddColumnValues {
713 my($This, @SpecifiedValues) = @_;
714 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $ErrorMsgPrefix, $CheckSizes, $CombineValues, $ColValueRef, $ColValuesRefs, $NumOfNewRows, $NumOfNewCols);
715
716 $ErrorMsgPrefix = "Error: ${ClassName}->AddColumnValues";
717
718 ($NumOfRows, $NumOfCols) = $This->GetSize();
719
720 # Collect specified column values...
721 $CheckSizes = 1; $CombineValues = 0;
722 $ColValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedValues);
723
724 # Check number of specified column values...
725 $NumOfNewCols = scalar @{$ColValuesRefs};
726 $NumOfNewRows = scalar @{$ColValuesRefs->[0]};
727
728 if ($NumOfNewRows != $NumOfRows) {
729 croak "$ErrorMsgPrefix: Number of values in each specified column, $NumOfNewRows, must be equal to number of column values, $NumOfRows, in matrix...";
730 }
731
732 # Add each column to the matrix...
733 $ColIndex = $NumOfCols - 1;
734 for $ColValueRef (@{$ColValuesRefs}) {
735 $ColIndex++;
736 for $RowIndex (0 .. ($NumOfCols - 1)) {
737 $This->{Values}[$RowIndex][$ColIndex] = $ColValueRef->[$RowIndex];
738 }
739 }
740
741 return $This;
742 }
743
744 # Get values of a column in matrix as an array. In scalar context, number of column
745 # values is returned...
746 #
747 sub GetColumnValues {
748 my($This, $ColIndex) = @_;
749
750 return $This->_GetRowOrColumnValues('AsArray', 'FromColumn', $ColIndex);
751 }
752
753 # Get values of a column in matrix as a vector object...
754 #
755 sub GetColumnValuesAsVector {
756 my($This, $ColIndex) = @_;
757
758 return $This->_GetRowOrColumnValues('AsVector', 'FromColumn', $ColIndex);
759 }
760
761 # Get values of a column as row matrix object...
762 #
763 sub GetColumnValuesAsRowMatrix {
764 my($This, $ColIndex) = @_;
765
766 return $This->_GetRowOrColumnValues('AsRowMatrix', 'FromColumn', $ColIndex);
767 }
768
769 # Get values of a column as column matrix object...
770 #
771 sub GetColumnValuesAsColumnMatrix {
772 my($This, $ColIndex) = @_;
773
774 return $This->_GetRowOrColumnValues('AsColumnMatrix', 'FromColumn', $ColIndex);
775 }
776
777 # Get values of a column in matrix as a space delimited string...
778 #
779 sub GetColumnValuesAsString {
780 my($This, $ColIndex) = @_;
781
782 return $This->_GetRowOrColumnValues('AsString', 'FromColumn', $ColIndex);
783 }
784
785 # Get row or column values...
786 #
787 sub _GetRowOrColumnValues {
788 my($This, $Mode, $ValueMode, $ValueModeIndex) = @_;
789
790 if ($Mode !~ /^(AsArray|AsVector|AsRowMatrix|AsColumnMatrix|AsString)$/i) {
791 croak "Error: ${ClassName}->_GetRowOrColumnValues: Unknown mode, $Mode, specified...";
792 }
793 if ($ValueMode !~ /^(FromRow|FromColumn)$/i) {
794 croak "Error: ${ClassName}->_GetRowOrColumnValues: Unknown value mode, $ValueMode, specified...";
795 }
796
797 # Setup error message prefix...
798 my($ErrorMsgPrefix);
799
800 $ErrorMsgPrefix = "${ClassName}->_GetRowOrColumnValues";
801 if ($ValueMode =~ /^FromRow$/i) {
802 $ErrorMsgPrefix = "Error: ${ClassName}->GetRowValues${Mode}";
803 }
804 elsif ($ValueMode =~ /^FromColumn$/i) {
805 $ErrorMsgPrefix = "Error: ${ClassName}->GetColumnValues${Mode}";
806 }
807
808 # Validate specified index and collect values...
809 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, @Values);
810
811 @Values = ();
812 ($NumOfRows, $NumOfCols) = $This->GetSize();
813
814 if ($ValueMode =~ /^FromRow$/i) {
815 $RowIndex = $ValueModeIndex;
816 $This->_ValidateRowIndex($ErrorMsgPrefix, $RowIndex);
817
818 for $ColIndex (0 .. ($NumOfCols - 1)) {
819 push @Values, $This->{Values}[$RowIndex][$ColIndex];
820 }
821 }
822 elsif ($ValueMode =~ /^FromColumn$/i) {
823 $ColIndex = $ValueModeIndex;
824 $This->_ValidateColumnIndex($ErrorMsgPrefix, $ColIndex);
825
826 for $RowIndex (0 .. ($NumOfRows - 1)) {
827 push @Values, $This->{Values}[$RowIndex][$ColIndex];
828 }
829 }
830
831 # Return values...
832 if ($Mode =~ /^AsRowMatrix$/i) {
833 return NewFromRows(\@Values);
834 }
835 elsif ($Mode =~ /^AsColumnMatrix$/i) {
836 return NewFromColumns(\@Values);
837 }
838 elsif ($Mode =~ /^AsVector$/i) {
839 return new Vector(@Values);
840 }
841 elsif ($Mode =~ /^AsString$/i) {
842 return join(' ', @Values);
843 }
844 else {
845 return wantarray ? @Values : scalar @Values;
846 }
847 }
848
849 # Set values of the diagonal in a square matrix...
850 #
851 sub SetDiagonalValues {
852 my($This, @SpecifiedDiagonalValues) = @_;
853 my($ErrorMsgPrefix, $NumOfRows, $NumOfCols, $RowIndex, $CheckSizes, $CombineValues, $ValuesRefs, $NumOfDiagonalValues, $DiagonalValuesRef);
854
855 $ErrorMsgPrefix = "Error: ${ClassName}->SetDiagonalValues";
856 if (!@SpecifiedDiagonalValues) {
857 croak "$ErrorMsgPrefix: No diagonal values specified...";
858 }
859
860 ($NumOfRows, $NumOfCols) = $This->GetSize();
861 if ($NumOfRows != $NumOfCols) {
862 croak "Error: $ErrorMsgPrefix: Specified matrix, $NumOfRows x $NumOfCols, is not a square matrix...";
863 }
864
865 # Collect specified diagonal values...
866 $CheckSizes = 0; $CombineValues = 1;
867 $ValuesRefs = _ProcessSpecifiedMatrixValues($ErrorMsgPrefix, $CheckSizes, $CombineValues, @SpecifiedDiagonalValues);
868 $DiagonalValuesRef = $ValuesRefs->[0];
869 $NumOfDiagonalValues = @{$DiagonalValuesRef};
870
871 if ($NumOfDiagonalValues != $NumOfRows) {
872 croak "Error: $ErrorMsgPrefix: Number of specified diagonal values, $NumOfDiagonalValues, must be equal to number of rows, $NumOfRows, in square matrix...";
873 }
874
875 # Set diagonal values...
876 for $RowIndex (0 .. ($NumOfRows - 1)) {
877 $This->{Values}[$RowIndex][$RowIndex] = $DiagonalValuesRef->[$RowIndex];
878 }
879
880 return $This;
881 }
882
883 # Get values of the diagonal in a square matrix as an array. In scalar context, number of
884 # diagonal values is returned...
885 #
886 sub GetDiagonalValues {
887 my($This) = @_;
888
889 return $This->_GetDiagonalValues('AsArray');
890 }
891
892 # Get values of the diagonal in a square matrix as vector object...
893 #
894 sub GetDiagonalValuesAsVector {
895 my($This) = @_;
896
897 return $This->_GetDiagonalValues('AsVector');
898 }
899
900 # Get values of the diagonal in a square matrix as row matrix object
901 #
902 sub GetDiagonalValuesAsRowMatrix {
903 my($This) = @_;
904
905 return $This->_GetDiagonalValues('AsRowMatrix');
906 }
907
908 # Get values of the diagonal in a square matrix as column matrix object
909 #
910 sub GetDiagonalValuesAsColumnMatrix {
911 my($This) = @_;
912
913 return $This->_GetDiagonalValues('AsColumnMatrix');
914 }
915
916 # Get values of the diagonal in a square matrix as a space delimited string...
917 #
918 sub GetDiagonalValuesAsString {
919 my($This) = @_;
920
921 return $This->_GetDiagonalValues('AsString');
922 }
923
924 # Get diagonal values...
925 sub _GetDiagonalValues {
926 my($This, $Mode) = @_;
927
928 if ($Mode !~ /^(AsArray|AsVector|AsRowMatrix|AsColumnMatrix|AsString)$/i) {
929 croak "Error: ${ClassName}->_GetDiagonalValues: Unknown mode, $Mode, specified...";
930 }
931
932 # Make sure it's a square matrix...
933 my($NumOfRows, $NumOfCols, $ErrorMsgPrefix);
934
935 $ErrorMsgPrefix = "${ClassName}->_GetDiagonalValues${Mode}";
936 ($NumOfRows, $NumOfCols) = $This->GetSize();
937 if ($NumOfRows != $NumOfCols) {
938 croak "Error: $ErrorMsgPrefix: Specified matrix, $NumOfRows x $NumOfCols, is not a square matrix...";
939 }
940
941 # Collect values...
942 my($RowIndex, @Values);
943 @Values = ();
944
945 for $RowIndex (0 .. ($NumOfRows - 1)) {
946 push @Values, $This->{Values}[$RowIndex][$RowIndex];
947 }
948
949 # Return values...
950 if ($Mode =~ /^AsRowMatrix$/i) {
951 return NewFromRows(\@Values);
952 }
953 elsif ($Mode =~ /^AsColumnMatrix$/i) {
954 return NewFromColumns(\@Values);
955 }
956 elsif ($Mode =~ /^AsVector$/i) {
957 return new Vector(@Values);
958 }
959 elsif ($Mode =~ /^AsString$/i) {
960 return join(' ', @Values);
961 }
962 else {
963 return wantarray ? @Values : scalar @Values;
964 }
965 }
966
967 # Is it a square matrix?
968 #
969 sub IsSquare {
970 my($This) = @_;
971 my($NumOfRows, $NumOfCols) = $This->GetSize();
972
973 return ($NumOfRows == $NumOfCols) ? 1 : 0;
974 }
975
976 # Is it a unit matrix?
977 #
978 # A matrix is a unit matrix:
979 # o It's a square matrix
980 # o All its diagonal elements are ones and its off-diagonal elements are zeros
981 #
982 sub IsUnit {
983 my($This) = @_;
984
985 # Is is a square matrix?
986 if (!$This->IsSquare()) {
987 return 0;
988 }
989
990 # Check matrix values...
991 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $ExpectedValue);
992 ($NumOfRows, $NumOfCols) = $This->GetSize();
993
994 for $RowIndex (0 .. ($NumOfRows - 1)) {
995 for $ColIndex (0 .. ($NumOfCols - 1)) {
996 $ExpectedValue = ($RowIndex == $ColIndex) ? 1.0 : 0.0;
997 if ($This->{Values}[$RowIndex][$ColIndex] != $ExpectedValue) {
998 return 0;
999 }
1000 }
1001 }
1002 return 1;
1003 }
1004
1005 # Is it an identity matrix?
1006 #
1007 sub IsIdentity {
1008 my($This) = @_;
1009
1010 return $This->IsUnit();
1011 }
1012
1013 # Is it a diagonal matrix?
1014 #
1015 # A matrix is a diagonal matrix:
1016 # o It's a square matrix
1017 # o All its off-diagonal elements are zeros and its diagonal elements may or may not
1018 # be zeros
1019 #
1020 #
1021 sub IsDiagonal {
1022 my($This) = @_;
1023
1024 # Is is a square matrix?
1025 if (!$This->IsSquare()) {
1026 return 0;
1027 }
1028
1029 # Check off-diagonal matrix values...
1030 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1031 ($NumOfRows, $NumOfCols) = $This->GetSize();
1032
1033 for $RowIndex (0 .. ($NumOfRows - 1)) {
1034 COLINDEX: for $ColIndex (0 .. ($NumOfCols - 1)) {
1035 if ($RowIndex == $ColIndex) {
1036 next COLINDEX;
1037 }
1038 if ($This->{Values}[$RowIndex][$ColIndex] != 0.0) {
1039 return 0;
1040 }
1041 }
1042 }
1043 return 1;
1044 }
1045
1046 # Is it a lower bidiagonal matrix?
1047 #
1048 # A matrix is a lower bidiagonal matrix:
1049 # o It's a square matrix
1050 # o All its main diagonal and lower diagonal elements are non-zeros and all its
1051 # other elements are zeros
1052 #
1053 sub IsLowerBiDiagonal {
1054 my($This) = @_;
1055
1056 # Is is a square matrix?
1057 if (!$This->IsSquare()) {
1058 return 0;
1059 }
1060
1061 # Check matrix values...
1062 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $Value);
1063 ($NumOfRows, $NumOfCols) = $This->GetSize();
1064
1065 for $RowIndex (0 .. ($NumOfRows - 1)) {
1066 for $ColIndex (0 .. ($NumOfCols - 1)) {
1067 $Value = $This->{Values}[$RowIndex][$ColIndex];
1068 if ($RowIndex == $ColIndex) {
1069 # Main diagonal...
1070 if ($Value == 0.0) {
1071 return 0;
1072 }
1073 }
1074 elsif ($RowIndex == ($ColIndex + 1)) {
1075 # Lower diagonal...
1076 if ($Value == 0.0) {
1077 return 0;
1078 }
1079 }
1080 else {
1081 # Other elements...
1082 if ($Value != 0.0) {
1083 return 0;
1084 }
1085 }
1086 }
1087 }
1088 return 1;
1089 }
1090
1091 # Is it an upper bidiagonal matrix?
1092 #
1093 # A matrix is an upper bidiagonal matrix:
1094 # o It's a square matrix
1095 # o All its main diagonal and upper diagonal elements are non-zeros and all its
1096 # other elements are zeros
1097 #
1098 sub IsUpperBiDiagonal {
1099 my($This) = @_;
1100
1101 # Is is a square matrix?
1102 if (!$This->IsSquare()) {
1103 return 0;
1104 }
1105 # Check matrix values...
1106 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $Value);
1107 ($NumOfRows, $NumOfCols) = $This->GetSize();
1108
1109 for $RowIndex (0 .. ($NumOfRows - 1)) {
1110 for $ColIndex (0 .. ($NumOfCols - 1)) {
1111 $Value = $This->{Values}[$RowIndex][$ColIndex];
1112 if ($RowIndex == $ColIndex) {
1113 # Main diagonal...
1114 if ($Value == 0.0) {
1115 return 0;
1116 }
1117 }
1118 elsif ($RowIndex == ($ColIndex - 1)) {
1119 # Upper diagonal...
1120 if ($Value == 0.0) {
1121 return 0;
1122 }
1123 }
1124 else {
1125 # Other elements...
1126 if ($Value != 0.0) {
1127 return 0;
1128 }
1129 }
1130 }
1131 }
1132 return 1;
1133 }
1134
1135 # Is it a bidiagonal matrix?
1136 #
1137 # A matrix is a bidiagonal matrix:
1138 #
1139 sub IsBiDiagonal {
1140 my($This) = @_;
1141
1142 return ($This->IsUpperBiDiagonal() || $This->IsLowerBiDiagonal()) ? 1 : 0;
1143 }
1144
1145 # Is it a tridiagonal matrix?
1146 #
1147 # A matrix is a tribidiagonal matrix:
1148 # o It's a square matrix
1149 # o All its main diagonal, upper diagonal, and lower diagonal elements are non-zeros and all its
1150 # other elements are zeros
1151 #
1152 #
1153 sub IsTriDiagonal {
1154 my($This) = @_;
1155
1156 # Is is a square matrix?
1157 if (!$This->IsSquare()) {
1158 return 0;
1159 }
1160
1161 # Check matrix values...
1162 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $Value);
1163 ($NumOfRows, $NumOfCols) = $This->GetSize();
1164
1165 for $RowIndex (0 .. ($NumOfRows - 1)) {
1166 for $ColIndex (0 .. ($NumOfCols - 1)) {
1167 $Value = $This->{Values}[$RowIndex][$ColIndex];
1168 if ($RowIndex == $ColIndex) {
1169 # Main diagonal...
1170 if ($Value == 0.0) {
1171 return 0;
1172 }
1173 }
1174 elsif ($RowIndex == ($ColIndex - 1)) {
1175 # Upper diagonal...
1176 if ($Value == 0.0) {
1177 return 0;
1178 }
1179 }
1180 elsif ($RowIndex == ($ColIndex + 1)) {
1181 # Lower diagonal...
1182 if ($Value == 0.0) {
1183 return 0;
1184 }
1185 }
1186 else {
1187 # Other elements...
1188 if ($Value != 0.0) {
1189 return 0;
1190 }
1191 }
1192 }
1193 }
1194 return 1;
1195 }
1196
1197 # Is it a lower triangular matrix?
1198 #
1199 # A matrix is a lower triangular matrix:
1200 # o It's a square matrix
1201 # o All its entries above the main diagonal are zero
1202 #
1203 sub IsLowerTriangular {
1204 my($This) = @_;
1205
1206 return $This->_IsLowerTriangularMatrix();
1207 }
1208
1209 # Is it a left triangular matrix?
1210 #
1211 # A matrix is a left triangular matrix:
1212 # o It's a square matrix
1213 # o All its entries above the main diagonal are zero
1214 #
1215 sub IsLeftTriangular {
1216 my($This) = @_;
1217
1218 return $This->IsLowerTriangular();
1219 }
1220
1221 # Is it a strictly lower triangular matrix?
1222 #
1223 # A matrix is a strictly lower triangular matrix:
1224 # o It's a square matrix
1225 # o All its entries on and above the main diagonal are zero
1226 #
1227 sub IsStrictlyLowerTriangular {
1228 my($This) = @_;
1229 my($DiagonalValue);
1230
1231 $DiagonalValue = 0;
1232
1233 return $This->_IsLowerTriangularMatrix($DiagonalValue);
1234 }
1235
1236 # Is it an unit lower triangular matrix?
1237 #
1238 # A matrix is an unit lower triangular matrix:
1239 # o It's a square matrix
1240 # o All its entries main diagonal are one
1241 # o All its entries above the main diagonal are zero
1242 #
1243 sub IsUnitLowerTriangular {
1244 my($This) = @_;
1245 my($DiagonalValue);
1246
1247 $DiagonalValue = 1;
1248
1249 return $This->_IsLowerTriangularMatrix($DiagonalValue);
1250 }
1251
1252 # Is it a lower unitriangular matrix?
1253 #
1254 sub IsLowerUniTriangular {
1255 my($This) = @_;
1256
1257 return $This->IsUnitLowerTriangular();
1258 }
1259
1260 # Is it a lower triangular, strictly lower triangular, or unit lower triangular matrix?
1261 #
1262 sub _IsLowerTriangularMatrix {
1263 my($This, $DiagonalValue) = @_;
1264
1265 # Is is a square matrix?
1266 if (!$This->IsSquare()) {
1267 return 0;
1268 }
1269 # Check matrix values...
1270 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $CheckDiagonalValues);
1271
1272 $CheckDiagonalValues = defined($DiagonalValue) ? 1 : 0;
1273 ($NumOfRows, $NumOfCols) = $This->GetSize();
1274
1275 for $RowIndex (0 .. ($NumOfRows - 1)) {
1276 for $ColIndex (0 .. ($NumOfCols - 1)) {
1277 if ($CheckDiagonalValues && $RowIndex == $ColIndex) {
1278 # Main diagonal...
1279 if ($This->{Values}[$RowIndex][$ColIndex] != $DiagonalValue) {
1280 return 0;
1281 }
1282 }
1283 elsif ($RowIndex < $ColIndex) {
1284 # Elemens above the main diagonal...
1285 if ($This->{Values}[$RowIndex][$ColIndex] != 0.0) {
1286 return 0;
1287 }
1288 }
1289 }
1290 }
1291 return 1;
1292 }
1293
1294 # Is it an upper triangular matrix?
1295 #
1296 # A matrix is an upper triangular matrix:
1297 # o It's a square matrix
1298 # o All its entries below the main diagonal are zero
1299 #
1300 sub IsUpperTriangular {
1301 my($This) = @_;
1302
1303 return $This->_IsUpperTriangularMatrix();
1304 }
1305
1306 # Is it a right triangular matrix?
1307 #
1308 # A matrix is a right triangular matrix:
1309 # o It's a square matrix
1310 # o All its entries below the main diagonal are zero
1311 #
1312 sub IsRightTriangular {
1313 my($This) = @_;
1314
1315 return $This->IsUpperTriangular();
1316 }
1317
1318 # Is it a strictly upper triangular matrix?
1319 #
1320 # A matrix is a strictly upper triangular matrix:
1321 # o It's a square matrix
1322 # o All its entries on and below the main diagonal are zero
1323 #
1324 sub IsStrictlyUpperTriangular {
1325 my($This) = @_;
1326 my($DiagonalValue);
1327
1328 $DiagonalValue = 0;
1329
1330 return $This->_IsUpperTriangularMatrix($DiagonalValue);
1331 }
1332
1333 # Is it a unit upper triangular matrix?
1334 #
1335 # A matrix is an unit upper triangular matrix:
1336 # o It's a square matrix
1337 # o All its entries main diagonal are one
1338 # o All its entries below the main diagonal are zero
1339 #
1340 sub IsUnitUpperTriangular {
1341 my($This) = @_;
1342 my($DiagonalValue);
1343
1344 $DiagonalValue = 1;
1345
1346 return $This->_IsUpperTriangularMatrix($DiagonalValue);
1347 }
1348
1349 # Is it a upper unitriangular matrix?
1350 #
1351 sub IsUpperUniTriangular {
1352 my($This) = @_;
1353
1354 return $This->IsUnitUpperTriangular();
1355 }
1356
1357 # Is it an upper triangular, strictly upper triangular, or unit upper triangular matrix?
1358 #
1359 sub _IsUpperTriangularMatrix {
1360 my($This, $DiagonalValue) = @_;
1361
1362 # Is is a square matrix?
1363 if (!$This->IsSquare()) {
1364 return 0;
1365 }
1366 # Check matrix values...
1367 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex, $CheckDiagonalValues);
1368
1369 $CheckDiagonalValues = defined($DiagonalValue) ? 1 : 0;
1370 ($NumOfRows, $NumOfCols) = $This->GetSize();
1371
1372 for $RowIndex (0 .. ($NumOfRows - 1)) {
1373 for $ColIndex (0 .. ($NumOfCols - 1)) {
1374 if ($CheckDiagonalValues && $RowIndex == $ColIndex) {
1375 # Main diagonal...
1376 if ($This->{Values}[$RowIndex][$ColIndex] != $DiagonalValue) {
1377 return 0;
1378 }
1379 }
1380 elsif ($RowIndex > $ColIndex) {
1381 # Elemens below the main diagonal...
1382 if ($This->{Values}[$RowIndex][$ColIndex] != 0.0) {
1383 return 0;
1384 }
1385 }
1386 }
1387 }
1388 return 1;
1389 }
1390
1391 # Is it a symmetrix matrix?
1392 #
1393 # A matrix is a symmetric matrix:
1394 # o It's a square matrix
1395 # o Its elements are symmetric with respect to main diagonal. In other words,
1396 # elements below the main diagonal are equal to the elements above the main
1397 # diagonal.
1398 #
1399 # Transpose of a symmetric matrix equals the matrix itself.
1400 #
1401 sub IsSymmetric {
1402 my($This) = @_;
1403
1404 # Is is a square matrix?
1405 if (!$This->IsSquare()) {
1406 return 0;
1407 }
1408
1409 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1410 ($NumOfRows, $NumOfCols) = $This->GetSize();
1411
1412 for $RowIndex (0 .. ($NumOfRows - 1)) {
1413 for $ColIndex (0 .. ($RowIndex - 1)) {
1414 if ($This->{Values}[$RowIndex][$ColIndex] != $This->{Values}[$ColIndex][$RowIndex]) {
1415 return 0;
1416 }
1417 }
1418 }
1419 return 1;
1420 }
1421
1422 # Is it a anti symmetrix matrix?
1423 #
1424 # A matrix is an anti symmetric matrix:
1425 # o It's a square matrix
1426 # o Its elements are asymmetric with respect to main diagonal. In other words,
1427 # elements below the main diagonal are equal to the negative of elements above
1428 # the main diagonal.
1429 #
1430 # Transpose of a anti symmetric matrix equals the negative of the matrix.
1431 #
1432 sub IsAntiSymmetric {
1433 my($This) = @_;
1434
1435 # Is is a square matrix?
1436 if (!$This->IsSquare()) {
1437 return 0;
1438 }
1439
1440 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1441 ($NumOfRows, $NumOfCols) = $This->GetSize();
1442
1443 for $RowIndex (0 .. ($NumOfRows - 1)) {
1444 for $ColIndex (0 .. ($RowIndex - 1)) {
1445 if ($This->{Values}[$RowIndex][$ColIndex] != -$This->{Values}[$ColIndex][$RowIndex]) {
1446 return 0;
1447 }
1448 }
1449 }
1450 return 1;
1451 }
1452
1453 # Is it a skew symmetrix matrix?
1454 #
1455 # It's another name for AnitSymmetricMatrix.
1456 #
1457 sub IsSkewSymmetric {
1458 my($This) = @_;
1459
1460 return $This->IsAntiSymmetric();
1461 }
1462
1463 # Is it a positive matrix with all its values >= zero?
1464 #
1465 sub IsPositive {
1466 my($This) = @_;
1467
1468 # Check matrix values...
1469 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1470 ($NumOfRows, $NumOfCols) = $This->GetSize();
1471
1472 for $RowIndex (0 .. ($NumOfRows - 1)) {
1473 for $ColIndex (0 .. ($NumOfCols - 1)) {
1474 if ($This->{Values}[$RowIndex][$ColIndex] < 0.0) {
1475 return 0;
1476 }
1477 }
1478 }
1479 return 1;
1480 }
1481
1482 # Is it a positive matrix with all its values <= zero?
1483 #
1484 sub IsNegative {
1485 my($This) = @_;
1486
1487 return $This->IsPositive() ? 0 : 1;
1488 }
1489
1490 # Transpose the matrix by swaping rows with columns...
1491 #
1492 sub Transpose {
1493 my($This) = @_;
1494 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1495
1496 # Create the transpose matrix of size $NumOfCols x $NumOfRows
1497 #
1498 ($NumOfRows, $NumOfCols) = $This->GetSize();
1499 $Matrix = new Matrix($NumOfCols, $NumOfRows);
1500
1501 # Swap rows and columns...
1502 for $RowIndex (0 .. ($NumOfCols - 1)) {
1503 for $ColIndex (0 .. ($NumOfRows - 1)) {
1504 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$ColIndex][$RowIndex];
1505 }
1506 }
1507 return $Matrix;
1508 }
1509
1510 # Is it a matrix object?
1511 sub IsMatrix ($) {
1512 my($Object) = @_;
1513
1514 return _IsMatrix($Object);
1515 }
1516
1517 # Set value print format for an individual object or the whole class during StringifyMatrix operation...
1518 sub SetValuePrintFormat ($;$) {
1519 my($FirstParameter, $SecondParameter) = @_;
1520
1521 if ((@_ == 2) && (_IsMatrix($FirstParameter))) {
1522 # Set value print format for the specific object...
1523 my($This, $ValuePrintFormat) = ($FirstParameter, $SecondParameter);
1524
1525 $This->{ValueFormat} = $ValuePrintFormat;
1526 }
1527 else {
1528 # Set value print format for the class...
1529 my($ValuePrintFormat) = ($FirstParameter);
1530
1531 $ValueFormat = $ValuePrintFormat;
1532 }
1533 }
1534
1535 # Set print style for matrix rows for an individual object or the whole class during StringifyMatrix
1536 # operation.
1537 #
1538 # Possible values: AllRowsInOneLine, OneRowPerLine. Default: AllRowsInOneLine
1539 #
1540 sub SetMatrixPrintStyle ($;$) {
1541 my($FirstParameter, $SecondParameter) = @_;
1542
1543 if ((@_ == 2) && (_IsMatrix($FirstParameter))) {
1544 # Set value print format for the specific object...
1545 my($This, $MatrixPrintStyleValue) = ($FirstParameter, $SecondParameter);
1546
1547 if ($MatrixPrintStyleValue !~ /^(AllRowsInOneLine|OneRowPerLine)$/i) {
1548 croak "Error: ${ClassName}->SetMatrixPrintStyle: Specified MatrixPrintStyle, $MatrixPrintStyleValue, is not valid. Supported values: AllRowsInOneLine, OneRowPerLine...";
1549 }
1550
1551 $This->{MatrixPrintStyle} = $MatrixPrintStyleValue;
1552 }
1553 else {
1554 # Set value print format for the class...
1555 my($MatrixPrintStyleValue) = ($FirstParameter);
1556
1557 if ($MatrixPrintStyleValue !~ /^(AllRowsInOneLine|OneRowPerLine)$/i) {
1558 croak "Error: ${ClassName}::SetMatrixPrintStyle: Specified MatrixPrintStyle, $MatrixPrintStyleValue, is not valid. Supported values: AllRowsInOneLine, OneRowPerLine...";
1559 }
1560
1561 $MatrixPrintStyle = $MatrixPrintStyleValue;
1562 }
1563 }
1564
1565 # Is it a matrix object?
1566 #
1567 sub _IsMatrix {
1568 my($Object) = @_;
1569
1570 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
1571 }
1572
1573 # Make sure it's a matrix reference...
1574 #
1575 sub _ValidateMatrix {
1576 my($ErrorMsg, $Matrix) = @_;
1577
1578 if (!_IsMatrix($Matrix)) {
1579 croak "Error: ${ClassName}->${ErrorMsg}: Object must be a matrix...";
1580 }
1581 }
1582
1583 # Make sure both row and column indicies are valid...
1584 #
1585 sub _ValidateRowAndColumnIndicies {
1586 my($This, $ErrorMsgPrefix, $RowIndex, $ColumnIndex) = @_;
1587
1588 $This->_ValidateRowIndex($ErrorMsgPrefix, $RowIndex);
1589 $This->_ValidateColumnIndex($ErrorMsgPrefix, $ColumnIndex);
1590
1591 return $This;
1592 }
1593
1594 # Make sure it's a valid row index...
1595 #
1596 sub _ValidateRowIndex {
1597 my($This, $ErrorMsgPrefix, $RowIndex) = @_;
1598 my($NumOfRows);
1599
1600 if (!defined $RowIndex) {
1601 croak "$ErrorMsgPrefix: RowIndex must be defined...";
1602 }
1603 $NumOfRows = $This->GetNumOfRows();
1604 if ($RowIndex < 0 || $RowIndex >= $NumOfRows) {
1605 croak "$ErrorMsgPrefix: RowIndex value $RowIndex must be >= 0 and < $NumOfRows, NumOfRows, in matrix...";
1606 }
1607 return $This;
1608 }
1609
1610 # Make sure it's a valid column index...
1611 #
1612 sub _ValidateColumnIndex {
1613 my($This, $ErrorMsgPrefix, $ColIndex) = @_;
1614 my($NumOfCols);
1615
1616 if (!defined $ColIndex) {
1617 croak "$ErrorMsgPrefix: ColIndex must be defined...";
1618 }
1619 $NumOfCols = $This->GetNumOfColumns();
1620 if ($ColIndex < 0 || $ColIndex >= $NumOfCols) {
1621 croak "$ErrorMsgPrefix: ColIndex value $ColIndex must be >= 0 and < $NumOfCols, NumOfCols, in matrix...";
1622 }
1623 return $This;
1624 }
1625
1626 #
1627 # Matrix addition operator supports two addition modes:
1628 # . Addition of two matrices by adding corresponding matrix values
1629 # . Addition of a scalar value to matrix values ($Matrix + 1)
1630 #
1631 # Caveats:
1632 # . Addition of a matrix to scalar is not allowed (1 + $Matrix)
1633 #
1634 sub _MatrixAdditionOperator {
1635 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1636
1637 $ErrorMsg = "_MatrixAdditionOperator: Matrix addition failed";
1638 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1639
1640 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1641
1642 ($NumOfRows, $NumOfCols) = $This->GetSize();
1643 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1644
1645 if ($OtherIsMatrix) {
1646 # $OrderFlipped is set to false for two matrices...
1647 for $RowIndex (0 .. ($NumOfRows - 1)) {
1648 for $ColIndex (0 .. ($NumOfCols - 1)) {
1649 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] + $Other->{Values}[$RowIndex][$ColIndex];
1650 }
1651 }
1652 }
1653 else {
1654 # Scalar addition...
1655 if ($OrderFlipped) {
1656 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1657 }
1658 for $RowIndex (0 .. ($NumOfRows - 1)) {
1659 for $ColIndex (0 .. ($NumOfCols - 1)) {
1660 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] + $Other;
1661 }
1662 }
1663 }
1664 return $Matrix;
1665 }
1666
1667 #
1668 # Matrix subtraction operator supports two subtraction modes:
1669 # . Subtraction of two matrices by subtracting corresponding matrix values
1670 # . Subtraction of a scalar value from matrix values ($Matrix - 1)
1671 #
1672 # Caveats:
1673 # . Subtraction of a matrix from scalar is not allowed (1 - $Matrix)
1674 #
1675 sub _MatrixSubtractionOperator {
1676 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1677
1678 $ErrorMsg = "_MatrixSubtractionOperator: Matrix subtraction failed";
1679 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1680
1681 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1682
1683 ($NumOfRows, $NumOfCols) = $This->GetSize();
1684 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1685
1686 if ($OtherIsMatrix) {
1687 # $OrderFlipped is set to false for two matrices...
1688 for $RowIndex (0 .. ($NumOfRows - 1)) {
1689 for $ColIndex (0 .. ($NumOfCols - 1)) {
1690 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] - $Other->{Values}[$RowIndex][$ColIndex];
1691 }
1692 }
1693 }
1694 else {
1695 # Scalar subtraction...
1696 if ($OrderFlipped) {
1697 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1698 }
1699 for $RowIndex (0 .. ($NumOfRows - 1)) {
1700 for $ColIndex (0 .. ($NumOfCols - 1)) {
1701 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] - $Other;
1702 }
1703 }
1704 }
1705 return $Matrix;
1706 }
1707
1708 #
1709 # Matrix multiplication operator supports two multiplication modes:
1710 # . Multiplication of two matrices
1711 # . Multiplication of matrix values by a scalar ($Matrix * 1)
1712 #
1713 # Caveats:
1714 # . Multiplication of a scalar by a is not allowed (1 * $Matrix)
1715 #
1716 sub _MatrixMultiplicationOperator {
1717 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg, $CheckSizes);
1718
1719 $ErrorMsg = "_MatrixMultiplicationOperator: Matrix multiplication failed";
1720 $CheckSizes = 0;
1721 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckSizes);
1722
1723 my($Matrix);
1724
1725 if ($OtherIsMatrix) {
1726 # $OrderFlipped is set to false for two matrices...
1727 my($NumOfRows1, $NumOfCols1, $RowIndex1, $ColIndex1, $NumOfRows2, $NumOfCols2, $ColIndex2, $Value, $RowColIndex);
1728
1729 ($NumOfRows1, $NumOfCols1) = $This->GetSize();
1730 ($NumOfRows2, $NumOfCols2) = $Other->GetSize();
1731
1732 if ($NumOfCols1 != $NumOfRows2) {
1733 croak "Error: ${ClassName}->${ErrorMsg}: NumOfCols in first matrix of size $NumOfRows1 x $NumOfCols1 must be equal to NumOfRows in second matrix of size $NumOfRows2 x $NumOfCols2...";
1734 }
1735
1736 $Matrix = new Matrix($NumOfRows1, $NumOfCols2);
1737
1738 for $RowIndex1 (0 .. ($NumOfRows1 - 1)) {
1739 for $ColIndex2 (0 .. ($NumOfCols2 - 1)) {
1740 $Value = 0;
1741 for $RowColIndex (0 .. ($NumOfCols1 - 1)) {
1742 $Value += $This->{Values}[$RowIndex1][$RowColIndex] * $Other->[$RowColIndex][$ColIndex2];
1743 }
1744 $Matrix->{Values}[$RowIndex1][$ColIndex2] = $Value;
1745 }
1746 }
1747 }
1748 else {
1749 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1750
1751 ($NumOfRows, $NumOfCols) = $This->GetSize();
1752 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1753 # Scalar subtraction...
1754 if ($OrderFlipped) {
1755 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1756 }
1757 for $RowIndex (0 .. ($NumOfRows - 1)) {
1758 for $ColIndex (0 .. ($NumOfCols - 1)) {
1759 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] * $Other;
1760 }
1761 }
1762 }
1763 return $Matrix;
1764 }
1765
1766 #
1767 # Matrix division operator supports two division modes:
1768 # . Division of two matrices by dividing corresponding matrix values
1769 # . Division matrix values by a scalar($Matrix/2)
1770 #
1771 # Caveats:
1772 # . Division of scalar value by a matrix is not allowed (2/$Matrix)
1773 #
1774 sub _MatrixDivisionOperator {
1775 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1776
1777 $ErrorMsg = "_MatrixDivisionOperator: Matrix division failed";
1778 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1779
1780 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1781
1782 ($NumOfRows, $NumOfCols) = $This->GetSize();
1783 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1784
1785 if ($OtherIsMatrix) {
1786 # $OrderFlipped is set to false for two matrices...
1787 for $RowIndex (0 .. ($NumOfRows - 1)) {
1788 for $ColIndex (0 .. ($NumOfCols - 1)) {
1789 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] / $Other->{Values}[$RowIndex][$ColIndex];
1790 }
1791 }
1792 }
1793 else {
1794 # Scalar subtraction...
1795 if ($OrderFlipped) {
1796 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1797 }
1798 for $RowIndex (0 .. ($NumOfRows - 1)) {
1799 for $ColIndex (0 .. ($NumOfCols - 1)) {
1800 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] / $Other;
1801 }
1802 }
1803 }
1804 return $Matrix;
1805 }
1806
1807 #
1808 # Matrix exponentiation operator supports two division modes:
1809 # . Exponent of two matrices by exponentiation of corresponding matrix values
1810 # . Exponentiation matrix values by a scalar ($Matrix ** 2)
1811 #
1812 # Caveats:
1813 # . Exponentiation of scalar value by a matrix is not allowed (2 ** $Matrix)
1814 #
1815 sub _MatrixExponentiationOperator {
1816 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1817
1818 $ErrorMsg = "_MatrixExponentiationOperator: Matrix exponentiation failed";
1819 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1820
1821 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1822
1823 ($NumOfRows, $NumOfCols) = $This->GetSize();
1824 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1825
1826 if ($OtherIsMatrix) {
1827 # $OrderFlipped is set to false for two matrices...
1828 for $RowIndex (0 .. ($NumOfRows - 1)) {
1829 for $ColIndex (0 .. ($NumOfCols - 1)) {
1830 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] ** $Other->{Values}[$RowIndex][$ColIndex];
1831 }
1832 }
1833 }
1834 else {
1835 # Scalar subtraction...
1836 if ($OrderFlipped) {
1837 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1838 }
1839 for $RowIndex (0 .. ($NumOfRows - 1)) {
1840 for $ColIndex (0 .. ($NumOfCols - 1)) {
1841 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] ** $Other;
1842 }
1843 }
1844 }
1845 return $Matrix;
1846 }
1847
1848 #
1849 # Matrix modulus operator supports two division modes:
1850 # . Modulus of two matrices by taking modulus between corresponding matrix values
1851 # . Modulus of matrix values by a scalar ($Matrix % 2)
1852 #
1853 # Caveats:
1854 # . Modulus of scalar value by a matrix is not allowed (2 % $Matrix)
1855 #
1856 sub _MatrixModulusOperator {
1857 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1858
1859 $ErrorMsg = "_MatrixModulusOperator: Matrix modulus failed";
1860 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1861
1862 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1863
1864 ($NumOfRows, $NumOfCols) = $This->GetSize();
1865 $Matrix = new Matrix($NumOfRows, $NumOfCols);
1866
1867 if ($OtherIsMatrix) {
1868 # $OrderFlipped is set to false for two matrices...
1869 for $RowIndex (0 .. ($NumOfRows - 1)) {
1870 for $ColIndex (0 .. ($NumOfCols - 1)) {
1871 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] % $Other->{Values}[$RowIndex][$ColIndex];
1872 }
1873 }
1874 }
1875 else {
1876 # Scalar subtraction...
1877 if ($OrderFlipped) {
1878 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1879 }
1880 for $RowIndex (0 .. ($NumOfRows - 1)) {
1881 for $ColIndex (0 .. ($NumOfCols - 1)) {
1882 $Matrix->{Values}[$RowIndex][$ColIndex] = $This->{Values}[$RowIndex][$ColIndex] % $Other;
1883 }
1884 }
1885 }
1886 return $Matrix;
1887 }
1888
1889 #
1890 # Matrix booelan operator checks whether a matrix contains at least one non-zero
1891 # value...
1892 #
1893 sub _MatrixBooleanOperator {
1894 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1895
1896 $ErrorMsg = "_MatrixBooleanOperator: Matrix boolean operation failed";
1897 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1898
1899 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1900
1901 ($NumOfRows, $NumOfCols) = $This->GetSize();
1902 for $RowIndex (0 .. ($NumOfRows - 1)) {
1903 for $ColIndex (0 .. ($NumOfCols - 1)) {
1904 if ($This->{Values}[$RowIndex][$ColIndex] != 0.0) {
1905 return 1;
1906 }
1907 }
1908 }
1909 return 0;
1910 }
1911
1912 #
1913 # Matrix not booelan operator checks whether a matrix contains only zero values...
1914 # value...
1915 #
1916 sub _MatrixNotBooleanOperator {
1917 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
1918
1919 $ErrorMsg = "_MatrixNotBooleanOperator: Matrix not boolean operation failed";
1920 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
1921
1922 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1923
1924 ($NumOfRows, $NumOfCols) = $This->GetSize();
1925 for $RowIndex (0 .. ($NumOfRows - 1)) {
1926 for $ColIndex (0 .. ($NumOfCols - 1)) {
1927 if ($This->{Values}[$RowIndex][$ColIndex] != 0.0) {
1928 return 0;
1929 }
1930 }
1931 }
1932 return 1;
1933 }
1934
1935 #
1936 # Matrix equal operator supports two modes:
1937 # . Comparison of corresponding values in two matrices
1938 # . Comparing matrix values to a scalar ($Matrix == 2)
1939 #
1940 # Caveats:
1941 # . Comparison of a scalar to matrix values is not allowed (2 == $Matrix)
1942 #
1943 sub _MatrixEqualOperator {
1944 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
1945
1946 $ErrorMsg = "_MatrixEqualOperator: Matrix equal failed";
1947 $CheckMatrixSizes = 0;
1948 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
1949
1950 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
1951
1952 ($NumOfRows, $NumOfCols) = $This->GetSize();
1953
1954 if ($OtherIsMatrix) {
1955 # $OrderFlipped is set to false for two matrices...
1956 my($OtherNumOfRows, $OtherNumOfCols);
1957
1958 # Check sizes...
1959 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
1960 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
1961 return 0;
1962 }
1963
1964 # Check values...
1965 for $RowIndex (0 .. ($NumOfRows - 1)) {
1966 for $ColIndex (0 .. ($NumOfCols - 1)) {
1967 if ($This->{Values}[$RowIndex][$ColIndex] != $Other->{Values}[$RowIndex][$ColIndex]) {
1968 return 0;
1969 }
1970 }
1971 }
1972 }
1973 else {
1974 # Scalar comparison...
1975 if ($OrderFlipped) {
1976 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
1977 }
1978 for $RowIndex (0 .. ($NumOfRows - 1)) {
1979 for $ColIndex (0 .. ($NumOfCols - 1)) {
1980 if ($This->{Values}[$RowIndex][$ColIndex] != $Other) {
1981 return 0;
1982 }
1983 }
1984 }
1985 }
1986 return 1;
1987 }
1988
1989 #
1990 # Matrix not equal operator supports two modes:
1991 # . Comparison of corresponding values in two matrices
1992 # . Comparing matrix values to a scalar ($Matrix != 2)
1993 #
1994 # Caveats:
1995 # . Comparison of a scalar to matrix values is not allowed (2 != $Matrix)
1996 #
1997 sub _MatrixNotEqualOperator {
1998 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
1999
2000 $ErrorMsg = "_MatrixNotEqualOperator: Matrix not equal failed";
2001 $CheckMatrixSizes = 0;
2002 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
2003
2004 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2005
2006 ($NumOfRows, $NumOfCols) = $This->GetSize();
2007
2008 if ($OtherIsMatrix) {
2009 # $OrderFlipped is set to false for two matrices...
2010 my($OtherNumOfRows, $OtherNumOfCols);
2011
2012 # Check sizes...
2013 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
2014 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
2015 return 1;
2016 }
2017
2018 # Check values...
2019 for $RowIndex (0 .. ($NumOfRows - 1)) {
2020 for $ColIndex (0 .. ($NumOfCols - 1)) {
2021 if ($This->{Values}[$RowIndex][$ColIndex] == $Other->{Values}[$RowIndex][$ColIndex]) {
2022 return 0;
2023 }
2024 }
2025 }
2026 }
2027 else {
2028 # Scalar comparison...
2029 if ($OrderFlipped) {
2030 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
2031 }
2032 for $RowIndex (0 .. ($NumOfRows - 1)) {
2033 for $ColIndex (0 .. ($NumOfCols - 1)) {
2034 if ($This->{Values}[$RowIndex][$ColIndex] == $Other) {
2035 return 0;
2036 }
2037 }
2038 }
2039 }
2040 return 1;
2041 }
2042
2043 #
2044 # Matrix less than operator supports two modes:
2045 # . Comparison of corresponding values in two matrices
2046 # . Comparing matrix values to a scalar ($Matrix < 2)
2047 #
2048 # Caveats:
2049 # . Comparison of a scalar to matrix values is not allowed (2 < $Matrix)
2050 #
2051 sub _MatrixLessThanOperator {
2052 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
2053
2054 $ErrorMsg = "_MatrixLessThanOperator: Matrix less than failed";
2055 $CheckMatrixSizes = 0;
2056 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
2057
2058 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2059
2060 ($NumOfRows, $NumOfCols) = $This->GetSize();
2061
2062 if ($OtherIsMatrix) {
2063 # $OrderFlipped is set to false for two matrices...
2064 my($OtherNumOfRows, $OtherNumOfCols);
2065
2066 # Check sizes...
2067 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
2068 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
2069 return 0;
2070 }
2071
2072 # Check values...
2073 for $RowIndex (0 .. ($NumOfRows - 1)) {
2074 for $ColIndex (0 .. ($NumOfCols - 1)) {
2075 if ($This->{Values}[$RowIndex][$ColIndex] >= $Other->{Values}[$RowIndex][$ColIndex]) {
2076 return 0;
2077 }
2078 }
2079 }
2080 }
2081 else {
2082 # Scalar comparison...
2083 if ($OrderFlipped) {
2084 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
2085 }
2086 for $RowIndex (0 .. ($NumOfRows - 1)) {
2087 for $ColIndex (0 .. ($NumOfCols - 1)) {
2088 if ($This->{Values}[$RowIndex][$ColIndex] >= $Other) {
2089 return 0;
2090 }
2091 }
2092 }
2093 }
2094 return 1;
2095 }
2096
2097 #
2098 # Matrix less than equal operator supports two modes:
2099 # . Comparion of corresponding values in two matrices
2100 # . Comparing matrix values to a scalar ($Matrix <= 2)
2101 #
2102 # Caveats:
2103 # . Comparison of a scalar to matrix values is not allowed (2 <= $Matrix)
2104 #
2105 sub _MatrixLessThanEqualOperator {
2106 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
2107
2108 $ErrorMsg = "_MatrixLessThanEqualOperator: Matrix less than equal failed";
2109 $CheckMatrixSizes = 0;
2110 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
2111
2112 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2113
2114 ($NumOfRows, $NumOfCols) = $This->GetSize();
2115
2116 if ($OtherIsMatrix) {
2117 # $OrderFlipped is set to false for two matrices...
2118 my($OtherNumOfRows, $OtherNumOfCols);
2119
2120 # Check sizes...
2121 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
2122 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
2123 return 0;
2124 }
2125
2126 # Check values...
2127 for $RowIndex (0 .. ($NumOfRows - 1)) {
2128 for $ColIndex (0 .. ($NumOfCols - 1)) {
2129 if ($This->{Values}[$RowIndex][$ColIndex] > $Other->{Values}[$RowIndex][$ColIndex]) {
2130 return 0;
2131 }
2132 }
2133 }
2134 }
2135 else {
2136 # Scalar comparison...
2137 if ($OrderFlipped) {
2138 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
2139 }
2140 for $RowIndex (0 .. ($NumOfRows - 1)) {
2141 for $ColIndex (0 .. ($NumOfCols - 1)) {
2142 if ($This->{Values}[$RowIndex][$ColIndex] > $Other) {
2143 return 0;
2144 }
2145 }
2146 }
2147 }
2148 return 1;
2149 }
2150
2151 #
2152 # Matrix greatar than operator supports two modes:
2153 # . Comparison of corresponding values in two matrices
2154 # . Comparing matrix values to a scalar ($Matrix > 2)
2155 #
2156 # Caveats:
2157 # . Comparison of a scalar to matrix values is not allowed (2 > $Matrix)
2158 #
2159 sub _MatrixGreatarThanOperator {
2160 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
2161
2162 $ErrorMsg = "_MatrixGreatarThanOperator: Matrix greatar than failed";
2163 $CheckMatrixSizes = 0;
2164 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
2165
2166 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2167
2168 ($NumOfRows, $NumOfCols) = $This->GetSize();
2169
2170 if ($OtherIsMatrix) {
2171 # $OrderFlipped is set to false for two matrices...
2172 my($OtherNumOfRows, $OtherNumOfCols);
2173
2174 # Check sizes...
2175 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
2176 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
2177 return 0;
2178 }
2179
2180 # Check values...
2181 for $RowIndex (0 .. ($NumOfRows - 1)) {
2182 for $ColIndex (0 .. ($NumOfCols - 1)) {
2183 if ($This->{Values}[$RowIndex][$ColIndex] <= $Other->{Values}[$RowIndex][$ColIndex]) {
2184 return 0;
2185 }
2186 }
2187 }
2188 }
2189 else {
2190 # Scalar comparison...
2191 if ($OrderFlipped) {
2192 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
2193 }
2194 for $RowIndex (0 .. ($NumOfRows - 1)) {
2195 for $ColIndex (0 .. ($NumOfCols - 1)) {
2196 if ($This->{Values}[$RowIndex][$ColIndex] <= $Other) {
2197 return 0;
2198 }
2199 }
2200 }
2201 }
2202 return 1;
2203 }
2204
2205 #
2206 # Matrix greatar than equal operator supports two modes:
2207 # . Comparison of corresponding values in two matrices
2208 # . Comparing matrix values to a scalar ($Matrix >= 2)
2209 #
2210 # Caveats:
2211 # . Comparison of a scalar to matrix values is not allowed (2 >= $Matrix)
2212 #
2213 sub _MatrixGreatarThanEqualOperator {
2214 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes, $ErrorMsg);
2215
2216 $ErrorMsg = "_MatrixGreatarThanEqualOperator: Matrix greatar than equal failed";
2217 $CheckMatrixSizes = 0;
2218 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckMatrixSizes);
2219
2220 my($NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2221
2222 ($NumOfRows, $NumOfCols) = $This->GetSize();
2223
2224 if ($OtherIsMatrix) {
2225 # $OrderFlipped is set to false for two matrices...
2226 my($OtherNumOfRows, $OtherNumOfCols);
2227
2228 # Check sizes...
2229 ($OtherNumOfRows, $OtherNumOfCols) = $Other->GetSize();
2230 if (!($NumOfRows == $OtherNumOfRows && $NumOfCols == $OtherNumOfCols)) {
2231 return 0;
2232 }
2233
2234 # Check values...
2235 for $RowIndex (0 .. ($NumOfRows - 1)) {
2236 for $ColIndex (0 .. ($NumOfCols - 1)) {
2237 if ($This->{Values}[$RowIndex][$ColIndex] < $Other->{Values}[$RowIndex][$ColIndex]) {
2238 return 0;
2239 }
2240 }
2241 }
2242 }
2243 else {
2244 # Scalar comparison...
2245 if ($OrderFlipped) {
2246 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a matrix...";
2247 }
2248 for $RowIndex (0 .. ($NumOfRows - 1)) {
2249 for $ColIndex (0 .. ($NumOfCols - 1)) {
2250 if ($This->{Values}[$RowIndex][$ColIndex] < $Other) {
2251 return 0;
2252 }
2253 }
2254 }
2255 }
2256 return 1;
2257 }
2258
2259 #
2260 # Matrix negative value operator returns a matrix with values corresponding to
2261 # negative values of a matrix
2262 #
2263 sub _MatrixNegativeValueOperator {
2264 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2265
2266 $ErrorMsg = "_MatrixNegativeValueOperator: Matrix negative value operation failed";
2267 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2268
2269 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2270
2271 ($NumOfRows, $NumOfCols) = $This->GetSize();
2272 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2273
2274 for $RowIndex (0 .. ($NumOfRows - 1)) {
2275 for $ColIndex (0 .. ($NumOfCols - 1)) {
2276 $Matrix->{Values}[$RowIndex][$ColIndex] = - $This->{Values}[$RowIndex][$ColIndex];
2277 }
2278 }
2279 return $Matrix;
2280 }
2281
2282 #
2283 # Matrix absolute value operator returns a matrix with values corresponding to
2284 # absolute values of a matrix
2285 #
2286 sub _MatrixAbsoluteValueOperator {
2287 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2288
2289 $ErrorMsg = "_MatrixAbsoluteValueOperator: Matrix absolute value operation failed";
2290 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2291
2292 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2293
2294 ($NumOfRows, $NumOfCols) = $This->GetSize();
2295 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2296
2297 for $RowIndex (0 .. ($NumOfRows - 1)) {
2298 for $ColIndex (0 .. ($NumOfCols - 1)) {
2299 $Matrix->{Values}[$RowIndex][$ColIndex] = abs $This->{Values}[$RowIndex][$ColIndex];
2300 }
2301 }
2302 return $Matrix;
2303 }
2304
2305 #
2306 # Matrix exp natural base operator returns a matrix with values corresponding to
2307 # e raised to the power of values in a matrix
2308 #
2309 sub _MatrixExpNaturalBaseOperator {
2310 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2311
2312 $ErrorMsg = "_MatrixExpNaturalBaseOperator: Matrix exp operation failed";
2313 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2314
2315 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2316
2317 ($NumOfRows, $NumOfCols) = $This->GetSize();
2318 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2319
2320 for $RowIndex (0 .. ($NumOfRows - 1)) {
2321 for $ColIndex (0 .. ($NumOfCols - 1)) {
2322 $Matrix->{Values}[$RowIndex][$ColIndex] = exp $This->{Values}[$RowIndex][$ColIndex];
2323 }
2324 }
2325 return $Matrix;
2326 }
2327
2328 #
2329 # Matrix log natural base operator returns a matrix with values corresponding to
2330 # log of values in a matrix
2331 #
2332 sub _MatrixLogNaturalBaseOperator {
2333 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2334
2335 $ErrorMsg = "_MatrixLogNaturalBaseOperator: Matrix log operation failed";
2336 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2337
2338 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2339
2340 ($NumOfRows, $NumOfCols) = $This->GetSize();
2341 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2342
2343 for $RowIndex (0 .. ($NumOfRows - 1)) {
2344 for $ColIndex (0 .. ($NumOfCols - 1)) {
2345 $Matrix->{Values}[$RowIndex][$ColIndex] = log $This->{Values}[$RowIndex][$ColIndex];
2346 }
2347 }
2348 return $Matrix;
2349 }
2350
2351 #
2352 # Matrix square root operator returns a matrix with values corresponding to
2353 # sqrt of values in a matrix
2354 #
2355 sub _MatrixSquareRootOperator {
2356 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2357
2358 $ErrorMsg = "_MatrixSquareRootOperator: Matrix sqrt operation failed";
2359 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2360
2361 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2362
2363 ($NumOfRows, $NumOfCols) = $This->GetSize();
2364 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2365
2366 for $RowIndex (0 .. ($NumOfRows - 1)) {
2367 for $ColIndex (0 .. ($NumOfCols - 1)) {
2368 $Matrix->{Values}[$RowIndex][$ColIndex] = sqrt $This->{Values}[$RowIndex][$ColIndex];
2369 }
2370 }
2371 return $Matrix;
2372 }
2373
2374 #
2375 # Matrix sine root operator returns a matrix with values corresponding to
2376 # sin of values in a matrix
2377 #
2378 sub _MatrixSineOperator {
2379 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2380
2381 $ErrorMsg = "_MatrixSineOperator: Matrix sin operation failed";
2382 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2383
2384 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2385
2386 ($NumOfRows, $NumOfCols) = $This->GetSize();
2387 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2388
2389 for $RowIndex (0 .. ($NumOfRows - 1)) {
2390 for $ColIndex (0 .. ($NumOfCols - 1)) {
2391 $Matrix->{Values}[$RowIndex][$ColIndex] = sin $This->{Values}[$RowIndex][$ColIndex];
2392 }
2393 }
2394 return $Matrix;
2395 }
2396
2397 #
2398 # Matrix cosine root operator returns a matrix with values corresponding to
2399 # cos of values in a matrix
2400 #
2401 sub _MatrixCosineOperator {
2402 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $ErrorMsg);
2403
2404 $ErrorMsg = "_MatrixCosineOperator: Matrix cos operation failed";
2405 ($This, $Other, $OrderFlipped, $OtherIsMatrix) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_);
2406
2407 my($Matrix, $NumOfRows, $NumOfCols, $RowIndex, $ColIndex);
2408
2409 ($NumOfRows, $NumOfCols) = $This->GetSize();
2410 $Matrix = new Matrix($NumOfRows, $NumOfCols);
2411
2412 for $RowIndex (0 .. ($NumOfRows - 1)) {
2413 for $ColIndex (0 .. ($NumOfCols - 1)) {
2414 $Matrix->{Values}[$RowIndex][$ColIndex] = cos $This->{Values}[$RowIndex][$ColIndex];
2415 }
2416 }
2417 return $Matrix;
2418 }
2419
2420 # Turn matrix into array for @{$Matrix} operation...
2421 #
2422 sub _MatrixToArrayOperator {
2423 my($This) = @_;
2424
2425 return \@{$This->{Values}};
2426 }
2427
2428 # Always return true in boolean context...
2429 #
2430 sub _BoolifyMatrix {
2431 my($This) = @_;
2432
2433 return 1;
2434 }
2435
2436 # Process parameters passed to overloaded operators...
2437 #
2438 # For uninary operators, $SecondParameter is not defined.
2439 sub _ProcessOverloadedOperatorParameters {
2440 my($ErrorMsg, $FirstParameter, $SecondParameter, $ParametersOrderStatus, $CheckMatrixSizesStatus) = @_;
2441 my($This, $Other, $OrderFlipped, $OtherIsMatrix, $CheckMatrixSizes);
2442
2443 ($This, $Other) = ($FirstParameter, $SecondParameter);
2444 $OrderFlipped = (defined($ParametersOrderStatus) && $ParametersOrderStatus) ? 1 : 0;
2445 $CheckMatrixSizes = (defined $CheckMatrixSizesStatus) ? $CheckMatrixSizesStatus : 1;
2446
2447 _ValidateMatrix($ErrorMsg, $This);
2448
2449 $OtherIsMatrix = 0;
2450 if (defined($Other) && (ref $Other)) {
2451 # Make sure $Other is a matrix...
2452 _ValidateMatrix($ErrorMsg, $Other);
2453 if ($CheckMatrixSizes) {
2454 _ValidateMatrixSizesAreEqual($ErrorMsg, $This, $Other);
2455 }
2456 $OtherIsMatrix = 1;
2457 }
2458 return ($This, $Other, $OrderFlipped, $OtherIsMatrix);
2459 }
2460
2461 # Make sure size of the two matrices contain the same number of values...
2462 sub _ValidateMatrixSizesAreEqual {
2463 my($ErrorMsg, $Matrix1, $Matrix2) = @_;
2464 my($NumOfRows1, $NumOfCols1, $NumOfRows2, $NumOfCols2);
2465
2466 ($NumOfRows1, $NumOfCols1) = $Matrix1->GetSize();
2467 ($NumOfRows2, $NumOfCols2) = $Matrix2->GetSize();
2468
2469 if (!($NumOfRows1 == $NumOfRows2 && $NumOfCols1 == $NumOfCols2)) {
2470 croak "Error: ${ClassName}->${ErrorMsg}: Size of the matrices must be same...";
2471 }
2472 }
2473
2474 # Return a string containing matrix values...
2475 #
2476 sub StringifyMatrix {
2477 my($This) = @_;
2478 my($MatrixString, $MatrixPrintStyleValue, $PrintFormat, $AllRowsInOneLine, $FormatString, $NumOfRows, $NumOfCols, $RowIndex, $RowNum, $RowString, @ValuesFormat);
2479
2480 ($NumOfRows, $NumOfCols) = $This->GetSize();
2481
2482 $MatrixPrintStyleValue = (exists $This->{MatrixPrintStyle}) ? $This->{MatrixPrintStyle} : $MatrixPrintStyle;
2483 $AllRowsInOneLine = ($MatrixPrintStyleValue =~ /^AllRowsInOneLine$/i) ? 1 : 0;
2484
2485 $PrintFormat = (exists $This->{ValueFormat}) ? $This->{ValueFormat} : $ValueFormat;
2486
2487 @ValuesFormat = ($PrintFormat) x $NumOfCols;
2488 $FormatString = join ' ', @ValuesFormat;
2489
2490 $MatrixString = sprintf "<Size: $NumOfRows x $NumOfCols;";
2491 if ($AllRowsInOneLine) {
2492 $MatrixString .= sprintf " Values:";
2493 }
2494 else {
2495 $MatrixString .= sprintf " Values:\n";
2496 }
2497
2498 $RowNum = 0;
2499 for $RowIndex (0 .. ($NumOfRows -1)) {
2500 $RowNum++;
2501 $RowString = sprintf "Row${RowNum}:[$FormatString]", @{$This->{Values}[$RowIndex]};
2502 if ($AllRowsInOneLine) {
2503 $MatrixString .= " $RowString";
2504 }
2505 else {
2506 $MatrixString .= "$RowString\n";
2507 }
2508 }
2509 $MatrixString .= ">";
2510 return $MatrixString;
2511 }
2512
2513 1;
2514
2515 __END__
2516
2517 =head1 NAME
2518
2519 Matrix
2520
2521 =head1 SYNOPSIS
2522
2523 use Matrix;
2524
2525 use Matrix qw(:all);
2526
2527 =head1 DESCRIPTION
2528
2529 B<Matrix> class provides the following methods:
2530
2531 new, AddColumnValues, AddRowValues, Copy, GetColumnValues,
2532 GetColumnValuesAsColumnMatrix, GetColumnValuesAsRowMatrix,
2533 GetColumnValuesAsString, GetColumnValuesAsVector, GetDiagonalValues,
2534 GetDiagonalValuesAsColumnMatrix, GetDiagonalValuesAsRowMatrix,
2535 GetDiagonalValuesAsString, GetDiagonalValuesAsVector, GetDimension,
2536 GetMatrixValuesReference, GetNumOfColumns, GetNumOfRows, GetRowValues,
2537 GetRowValuesAsColumnMatrix, GetRowValuesAsRowMatrix, GetRowValuesAsString,
2538 GetRowValuesAsVector, GetSize, GetValue, IdentityMatrix, IsAntiSymmetric,
2539 IsBiDiagonal, IsDiagonal, IsIdentity, IsLeftTriangular, IsLowerBiDiagonal,
2540 IsLowerTriangular, IsLowerUniTriangular, IsMatrix, IsNegative, IsPositive,
2541 IsRightTriangular, IsSkewSymmetric, IsSquare, IsStrictlyLowerTriangular,
2542 IsStrictlyUpperTriangular, IsSymmetric, IsTriDiagonal, IsUnit,
2543 IsUnitLowerTriangular, IsUnitUpperTriangular, IsUpperBiDiagonal,
2544 IsUpperTriangular, IsUpperUniTriangular, NewFromColumns, NewFromDiagonal,
2545 NewFromRows, One, SetAllValues, SetColumnValues, SetDiagonalValues,
2546 SetMatrixPrintStyle, SetRowValues, SetValue, SetValuePrintFormat, StringifyMatrix,
2547 Transpose, UnitMatrix, Zero, ZeroMatrix
2548
2549 The following functions are available:
2550
2551 IsMatrix, IdentityMatrix, NewFromRows, NewFromColumns, NewFromDiagonal,
2552 UnitMatrix, ZeroMatrix
2553
2554 The following operators are overloaded:
2555
2556 "" bool !
2557 @{}
2558 + - * / ** %
2559 == != < <= > >=
2560 neg
2561 abs exp log sqrt cos sin
2562
2563 The matrix row and column indicies start from zero.
2564
2565 =head2 FUNCTIONS
2566
2567 =over 4
2568
2569 =item B<new>
2570
2571 $NewMatrix = $Matrix->new($NumOfRows, $NumOfCols);
2572
2573 Creates a new B<Matrix> of size I<NumOfRows x NumOfCol> and returns B<NewMatrix>
2574 object.
2575
2576 =item B<AddColumnValues>
2577
2578 $Matrix->AddColumnValues(@Values);
2579 $Matrix->AddColumnValues(\@Values);
2580 $Matrix->AddColumnValues($VectorObject);
2581 $Matrix->AddColumnValues("Value1 Value2 Value3 ...");
2582
2583 Adds column values to I<Matrix> using an array, reference to an array, another vector, or space
2584 delimited value string and returns I<Matrix>.
2585
2586 =item B<AddRowValues>
2587
2588 $Matrix->AddRowValues(@Values);
2589 $Matrix->AddRowValues(\@Values);
2590 $Matrix->AddRowValues($VectorObject);
2591 $Matrix->AddRowValues("Value1 Value2 Value3 ...");
2592
2593 Adds row values to I<Matrix> using an array, reference to an array, another vector, or space
2594 delimited value string and returns B<Matrix>.
2595
2596 =item B<Copy>
2597
2598 $NewMatrix = $Matrix->Copy();
2599
2600 Creates a copy of I<Matrix> and returns B<NewMatrix>.
2601
2602 =item B<GetColumnValues>
2603
2604 @Values = $Matrix->GetColumnValues($ColIndex);
2605 $ValueCount = $Matrix->GetColumnValues($ColIndex);
2606
2607 Returns an array containing column value specified using I<ColIndex> with column index
2608 starting at 0. In scalar context, number of column values is returned.
2609
2610 =item B<GetColumnValuesAsColumnMatrix>
2611
2612 $ColumnMatrix = $Matrix->GetColumnValuesAsColumnMatrix($ColIndex);
2613
2614 Returns a new B<ColumnMatrix> containing column values specified using I<ColIndex> with
2615 column index starting at 0.
2616
2617 =item B<GetColumnValuesAsRowMatrix>
2618
2619 $RowMatrix = $Matrix->GetColumnValuesAsRowMatrix($ColIndex);
2620
2621 Returns a new B<RowMatrix> containing column values specified using I<ColIndex> with
2622 column index starting at 0.
2623
2624 =item B<GetColumnValuesAsString>
2625
2626 $ColumnValuesString = $Matrix->GetColumnValuesAsString($ColIndex);
2627
2628 Returns a space delimited B<ColumnValuesString> column values specified using I<ColIndex> with
2629 column index starting at 0.
2630
2631 =item B<GetColumnValuesAsVector>
2632
2633 $ColumnVector = $Matrix->GetColumnValuesAsVector($ColIndex);
2634
2635 Returns a new B<ColumnVector> column values specified using I<RowIndex> with
2636 column index starting at 0.
2637
2638 =item B<GetDiagonalValues>
2639
2640 @Values = $Matrix->GetDiagonalValues();
2641 $ValueCount = $Matrix->GetDiagonalValues();
2642
2643 Returns an array containing diagonal values. In scalar context, number of diagonal
2644 values is returned.
2645
2646 =item B<GetDiagonalValuesAsColumnMatrix>
2647
2648 $ColumnMatrix = $Matrix->GetDiagonalValuesAsColumnMatrix();
2649
2650 Returns a new B<ColumnMatrix> containing diagonal values corresponding to I<Matrix>.
2651
2652 =item B<GetDiagonalValuesAsRowMatrix>
2653
2654 $RowMatrix = $Matrix->GetDiagonalValuesAsRowMatrix();
2655
2656 Returns a new B<RowMatrix> containing diagonal values corresponding to I<Matrix>.
2657
2658 =item B<GetDiagonalValuesAsString>
2659
2660 $DiagonalValuesString = $Matrix->GetDiagonalValuesAsString();
2661
2662 Returns a space delimited B<DiagonalValuesString> containing diagonal values corresponding to
2663 I<Matrix>.
2664
2665 =item B<GetDiagonalValuesAsVector>
2666
2667 $DiagonalVector = $Matrix->GetDiagonalValuesAsVector();
2668
2669 Returns a new B<DiagonalVector> containing diagonal values corresponding to I<Matrix>.
2670
2671 =item B<GetDimension>
2672
2673 ($NumOfRows, $NumOfCols) = $Matrix->GetDimension();
2674
2675 Returns size of I<Matrix>.
2676
2677 =item B<GetMatrixValuesReference>
2678
2679 $ValuesRef = $Matrix->GetMatrixValuesReference();
2680
2681 Returns a reference to array containing rows and column values corresponding to I<Matrix>.
2682
2683 =item B<GetNumOfColumns>
2684
2685 $NumOfCols = $Matrix->GetNumOfColumns();
2686
2687 Returns B<NumOfCols> in I<Matrix>.
2688
2689 =item B<GetNumOfRows>
2690
2691 $NumOfRows = $Matrix->GetNumOfRows();
2692
2693 Returns B<NumOfRows> in I<Matrix>.
2694
2695 =item B<GetRowValues>
2696
2697 @Values = $Matrix->GetRowValues($RowIndex);
2698 $ValueCount = $Matrix->GetRowValues($RowIndex);
2699
2700 Returns an array containing row value specified using I<RowIndex> with row index
2701 starting at 0. In scalar context, number of row values is returned.
2702
2703 =item B<GetRowValuesAsColumnMatrix>
2704
2705 $ColumnMatrix = $Matrix->GetRowValuesAsColumnMatrix($RowIndex);
2706
2707 Returns a new B<ColumnMatrix> containing row values specified using I<RowIndex> with
2708 column index starting at 0.
2709
2710 =item B<GetRowValuesAsRowMatrix>
2711
2712 $RowMatrix = $Matrix->GetRowValuesAsRowMatrix($RowIndex);
2713
2714 Returns a new B<RowMatrix> containing row values specified using I<RowIndex> with
2715 row index starting at 0.
2716
2717 =item B<GetRowValuesAsString>
2718
2719 $RowValuesString = $Matrix->GetRowValuesAsString($RowIndex);
2720
2721 Returns a space delimited B<RowValuesString> row values specified using I<RowIndex> with
2722 row index starting at 0.
2723
2724 =item B<GetRowValuesAsVector>
2725
2726 $RowVector = $Matrix->GetColumnValuesAsVector($RowIndex);
2727
2728 Returns a new B<RowVector> row values specified using I<RowIndex> with
2729 row index starting at 0.
2730
2731 =item B<GetSize>
2732
2733 ($NumOfRows, $NumOfCols) = $Matrix->GetSize();
2734
2735 Returns size of I<Matrix>.
2736
2737 =item B<GetValue>
2738
2739 $Value = $Matrix->GetValue($RowIndex, $ColIndex, [$SkipIndexCheck]);
2740
2741 Returns B<Value> of I<Matrix> element specified using I<RowIndex> and I<ColIndex> with indicies
2742 starting at 0 with optional validation of specified index values.
2743
2744 =item B<IdentityMatrix>
2745
2746 $NewIdentityMatrix = $Matrix->IdentityMatrix($NumOfRows, $NumOfCols);
2747 $NewIdentityMatrix = Matrix::IdentityMatrix($NumOfRows, $NumOfCols);
2748 $NewIdentityMatrix = Matrix::IdentityMatrix();
2749
2750 Creates a new B<IdentityMatrix> of specified size I<NumOfRows x NumOfCol> or of size 3 x 3 and
2751 returns B<NewIdentityMatrix> object.
2752
2753 =item B<IsAntiSymmetric>
2754
2755 $Status = $Matrix->IsAntiSymmetric();
2756
2757 Returns 1 or 0 based on whether I<Matrix> is an anti symmetric matrix.
2758
2759 A matrix is an anti symmetric matrix:
2760
2761 . It's a square matrix
2762 . Its elements are asymmetric with respect to main diagonal. In other words,
2763 elements below the main diagonal are equal to the negative of elements above
2764 the main diagonal.
2765
2766 Transpose of an anti symmetric matrix equals the negative of the matrix.
2767
2768 =item B<IsBiDiagonal>
2769
2770 $Status = $Matrix->IsBiDiagonal();
2771
2772 Returns 1 or 0 based on whether I<Matrix> is upper or lower bidiagonal matrix.
2773
2774 =item B<IsDiagonal>
2775
2776 $Status = $Matrix->IsDiagonal();
2777
2778 Returns 1 or 0 based on whether I<Matrix> is a diagonal matrix.
2779
2780 A matrix is a diagonal matrix:
2781
2782 . It's a square matrix
2783 . All its off-diagonal elements are zeros and its diagonal elements may or may not
2784 be zeros
2785
2786 =item B<IsIdentity>
2787
2788 $Status = $Matrix->IsIdentity();
2789
2790 Returns 1 or 0 based on whether I<Matrix> is an identity matrix.
2791
2792 =item B<IsLeftTriangular>
2793
2794 $Status = $Matrix->IsLeftTriangular();
2795
2796 Returns 1 or 0 based on whether I<Matrix> is a left or lower matrix.
2797
2798 A matrix is a left triangular matrix:
2799
2800 . It's a square matrix
2801 . All its entries above the main diagonal are zero
2802
2803 =item B<IsLowerBiDiagonal>
2804
2805 $Status = $Matrix->IsLowerBiDiagonal();
2806
2807 Returns 1 or 0 based on whether I<Matrix> is a lower bidiagonal matrix.
2808
2809 A matrix is a lower bidiagonal matrix:
2810
2811 . It's a square matrix
2812 . All its main diagonal and lower diagonal elements are non-zeros and all its
2813 other elements are zeros
2814
2815 =item B<IsLowerTriangular>
2816
2817 $Status = $Matrix->IsLowerTriangular();
2818
2819 Returns 1 or 0 based on whether I<Matrix> is a left or lower triangular matrix.
2820
2821 A matrix is a lower triangular matrix:
2822
2823 . It's a square matrix
2824 . All its entries above the main diagonal are zero
2825
2826 =item B<IsLowerUniTriangular>
2827
2828 $Status = $Matrix->IsLowerUniTriangular();
2829
2830 Returns 1 or 0 based on whether I<Matrix> is a lower triangular matrix.
2831
2832 =item B<IsMatrix>
2833
2834 $Status = Matrix::IsMatrix($Object);
2835
2836 Returns 1 or 0 based on whether I<Object> is a B<Matrix> object.
2837
2838 =item B<IsNegative>
2839
2840 $Status = $Matrix->IsNegative();
2841
2842 Returns 1 or 0 based on whether I<Matrix> is a negative matrix containing only values
2843 less than or equal to zero.
2844
2845 =item B<IsPositive>
2846
2847 $Status = $Matrix->IsPositive();
2848
2849 Returns 1 or 0 based on whether I<Matrix> is a negative matrix containing only values
2850 greater than or equal to zero.
2851
2852 =item B<IsRightTriangular>
2853
2854 $Status = $Matrix->IsRightTriangular();
2855
2856 Returns 1 or 0 based on whether I<Matrix> is a right or upper triangular matrix.
2857
2858 =item B<IsSkewSymmetric>
2859
2860 $Status = $Matrix->IsSkewSymmetric();
2861
2862 Returns 1 or 0 based on whether I<Matrix> is a skew or anti symmetric matrix.
2863
2864 =item B<IsSquare>
2865
2866 $Status = $Matrix->IsSquare();
2867
2868 Returns 1 or 0 based on whether I<Matrix> is a square matrix containing equal
2869 number of rows and columns.
2870
2871 =item B<IsStrictlyLowerTriangular>
2872
2873 $Status = $Matrix->IsStrictlyLowerTriangular();
2874
2875 Returns 1 or 0 based on whether I<Matrix> is a strictly lower triangular matrix.
2876
2877 A matrix is a strictly lower triangular matrix:
2878
2879 . It's a square matrix
2880 . All its entries on and above the main diagonal are zero
2881
2882 =item B<IsStrictlyUpperTriangular>
2883
2884 $Status = $Matrix->IsStrictlyUpperTriangular();
2885
2886 Returns 1 or 0 based on whether I<Matrix> is a strictly upper triangular matrix.
2887
2888 A matrix is a strictly upper triangular matrix:
2889
2890 . It's a square matrix
2891 . All its entries on and below the main diagonal are zero
2892
2893 =item B<IsSymmetric>
2894
2895 $Status = $Matrix->IsSymmetric();
2896
2897 Returns 1 or 0 based on whether I<Matrix> is a symmetric matrix.
2898
2899 A matrix is a symmetric matrix:
2900
2901 . It's a square matrix
2902 . Its elements are symmetric with respect to main diagonal. In other words,
2903 elements below the main diagonal are equal to the elements above the main
2904 diagonal.
2905
2906 Transpose of a symmetric matrix equals the matrix itself.
2907
2908 =item B<IsTriDiagonal>
2909
2910 $Status = $Matrix->IsTriDiagonal();
2911
2912 Returns 1 or 0 based on whether I<Matrix> is a tridiagonal matrix.
2913
2914 A matrix is a tribidiagonal matrix:
2915
2916 . It's a square matrix
2917 . All its main diagonal, upper diagonal, and lower diagonal elements are non-zeros and all its
2918 other elements are zeros
2919
2920 =item B<IsUnit>
2921
2922 $Status = $Matrix->IsUnit();
2923
2924 Returns 1 or 0 based on whether I<Matrix> is a unit matrix.
2925
2926 A matrix is a unit matrix:
2927
2928 . It's a square matrix
2929 . All its diagonal elements are ones and its off-diagonal elements are zeros
2930
2931 =item B<IsUnitLowerTriangular>
2932
2933 $Status = $Matrix->IsUnitLowerTriangular();
2934
2935 Returns 1 or 0 based on whether I<Matrix> is an unit lower triangular matrix.
2936
2937 A matrix is an unit lower triangular matrix:
2938
2939 . It's a square matrix
2940 . All its entries main diagonal are one
2941 . All its entries above the main diagonal are zero
2942
2943 =item B<IsUnitUpperTriangular>
2944
2945 $Status = $Matrix->IsUnitUpperTriangular();
2946
2947 Returns 1 or 0 based on whether I<Matrix> is an unit upper triangular matrix.
2948
2949 A matrix is an unit upper triangular matrix:
2950
2951 . It's a square matrix
2952 . All its entries main diagonal are one
2953 . All its entries below the main diagonal are zero
2954
2955 =item B<IsUpperBiDiagonal>
2956
2957 $Status = $Matrix->IsUpperBiDiagonal();
2958
2959 Returns 1 or 0 based on whether I<Matrix> is an upper bidiagonal matrix.
2960
2961 A matrix is an upper bidiagonal matrix:
2962
2963 . It's a square matrix
2964 . All its main diagonal and upper diagonal elements are non-zeros and all its
2965 other elements are zeros
2966
2967 =item B<IsUpperTriangular>
2968
2969 $Status = $Matrix->IsUpperTriangular();
2970
2971 Returns 1 or 0 based on whether I<Matrix> is a right or upper triangular matrix.
2972
2973 A matrix is an upper triangular matrix:
2974
2975 . It's a square matrix
2976 . All its entries below the main diagonal are zero
2977
2978 =item B<IsUpperUniTriangular>
2979
2980 $Status = $Matrix->IsUpperUniTriangular();
2981
2982 Returns 1 or 0 based on whether I<Matrix> is a right or upper triangular matrix.
2983
2984 =item B<NewFromColumns>
2985
2986 $NewMatrix = Matrix::NewFromColumns($Col1Vector, $Col2Vector, ...);
2987 $NewMatrix = Matrix::NewFromColumns($Col1ValuesRef, $Col2ValuesRef, ...);
2988 $NewMatrix = Matrix::NewFromColumns("Val1 Val2 ...", "Val1 Val2", ...);
2989
2990 $NewMatrix = $Matrix->NewFromColumns($Col1Vector, $Col2Vector, ...);
2991 $NewMatrix = $Matrix->NewFromColumns($Col1ValuesRef, $Col2ValuesRef, ...);
2992 $NewMatrix = $Matrix->NewFromColumns("Val1 Val2 ...", "Val1 Val2", ...);
2993
2994 Creates a new B<Matrix> using specified column values and returns B<NewMatrix> object.
2995
2996 The column values can be specified in one of the following formats:
2997
2998 . List of vector objects
2999 . References to list of values
3000 . List of strings containing columns values delimited by space
3001
3002 Each column must contain the same number of values.
3003
3004 =item B<NewFromDiagonal>
3005
3006 $NewMatrix = Matrix::NewFromDiagonal($DiagonalVector);
3007 $NewMatrix = Matrix::NewFromDiagonal($DiagonalValuesRef);
3008 $NewMatrix = Matrix::NewFromDiagonal("Val1 Val2 ...");
3009
3010 $NewMatrix = Matrix->NewFromDiagonal($DiagonalVector);
3011 $NewMatrix = Matrix->NewFromDiagonal($DiagonalValuesRef);
3012 $NewMatrix = Matrix->NewFromDiagonal("Val1 Val2 ...");
3013
3014 Creates a new B<Matrix> using specified diagonal values and returns B<NewMatrix> object.
3015
3016 The column values can be specified in one of the following formats:
3017
3018 . A vector object
3019 . Reference to list of values
3020 . Strings containing diagonal values delimited by space
3021
3022 =item B<NewFromRows>
3023
3024 $NewMatrix = Matrix::NewFromRows($Row1Vector, $RowVector, ...);
3025 $NewMatrix = Matrix::NewFromRows($Row1ValuesRef, $Row2ValuesRef, ...);
3026 $NewMatrix = Matrix::NewFromRows("Val1 Val2 ...", "Val1 Val2", ...);
3027
3028 $NewMatrix = $Matrix->NewFromRows($Row1Vector, $Row2Vector, ...);
3029 $NewMatrix = $Matrix->NewFromRows($Row1ValuesRef, $Row2ValuesRef, ...);
3030 $NewMatrix = $Matrix->NewFromRows("Val1 Val2 ...", "Val1 Val2", ...);
3031
3032 Creates a new B<Matrix> using specified row values and returns B<NewMatrix> object.
3033
3034 The row values can be specified in one of the following formats:
3035
3036 . List of vector objects
3037 . References to list of values
3038 . List of strings containing columns values delimited by space
3039
3040 Each row must contain the same number of values.
3041
3042 =item B<One>
3043
3044 $Matrix->One();
3045
3046 Sets values of all I<Matrix> elements to 1 and returns I<Matrix>.
3047
3048 =item B<SetAllValues>
3049
3050 $Matrix->SetAllValues($Value);
3051
3052 Sets values of all I<Matrix> elements to specified I<Value> and returns I<Matrix>.
3053
3054 =item B<SetColumnValues>
3055
3056 $Matrix->SetColumnValues($ColIndex, @Values);
3057 $Matrix->SetColumnValues($ColIndex, \@Values);
3058 $Matrix->SetColumnValues($ColIndex, $VectorObject);
3059 $Matrix->SetColumnValues($ColIndex, "Value1 Value2 Value3 ...");
3060
3061 Sets column values of a specified I<ColIndex> of I<Matrix> using an array, reference to an array,
3062 another vector, or space delimited value string and returns I<Matrix>.
3063
3064 =item B<SetDiagonalValues>
3065
3066 $Matrix->SetDiagonalValues(@Values);
3067 $Matrix->SetDiagonalValues(\@Values);
3068 $Matrix->SetDiagonalValues($VectorObject);
3069 $Matrix->SetDiagonalValues("Value1 Value2 Value3 ...");
3070
3071 Sets values of the diagonal in square I<Matrix> and returns I<Matrix>.
3072
3073 =item B<SetMatrixPrintStyle>
3074
3075 $Matrix->SetMatrixPrintStyle($MatrixStyle);
3076 $Matrix::SetMatrixPrintStyle($MatrixStyle);
3077
3078 Sets print style for matrix rows for an individual object or the whole class during StringifyMatrix
3079 operation. Possible I<MatrixStyle> values: I<AllRowsInOneLine, OneRowPerLine>. Default:
3080 I<AllRowsInOneLine>.
3081
3082 =item B<SetRowValues>
3083
3084 $Matrix->SetRowValues($ColIndex, @Values);
3085 $Matrix->SetRowValues($ColIndex, \@Values);
3086 $Matrix->SetRowValues($ColIndex, $VectorObjext);
3087 $Matrix->SetRowValues($ColIndex, "Value1 Value2 Value3 ...");
3088
3089 Sets row values of a specified I<RowIndex> of I<Matrix> using an array, reference to an array,
3090 another vector, or space delimited value string and returns I<Matrix>.
3091
3092 =item B<SetValue>
3093
3094 $Matrix->SetValue($RowIndex, $ColIndex, $Value, [$SkipIndexCheck]);
3095
3096 Sets B<Value> of I<Matrix> element specified using I<RowIndex> and I<ColIndex> with indicies
3097 starting at 0 with optional validation of specified index values and return I<Matrix>.
3098
3099 =item B<SetValuePrintFormat>
3100
3101 $Matrix->SetValuePrintFormat($ValueFormat);
3102 $Matrix::SetValuePrintFormat($ValueFormat);
3103
3104 Sets value print format for an individual object or the whole class during StringifyMatrix operation
3105 and returns I<Matrix>.
3106
3107 =item B<StringifyMatrix>
3108
3109 $String = $Matrix->StringifyMatrix();
3110
3111 Returns a string containing information about I<Matrix> object.
3112
3113 =item B<Transpose>
3114
3115 $Matrix->Transpose();
3116
3117 Transposes I<Matrix> by swaping rows with columns and returns I<Matrix>.
3118
3119 =item B<UnitMatrix>
3120
3121 $NewUnitMatrix = $Matrix::UnitMatrix($NumOfRows, $NumOfCols);
3122 $NewUnitMatrix = $Matrix::UnitMatrix();
3123 $NewUnitMatrix = $Matrix->UnitMatrix($NumOfRows, $NumOfCols);
3124
3125 Creates a new B<UnitMatrix> of specified size I<NumOfRows x NumOfCol> or of size 3 x 3 and
3126 returns B<NewUnitMatrix> object.
3127
3128 =item B<Zero>
3129
3130 $Matrix->Zero();
3131
3132 Sets values of all I<Matrix> elements to 0 and returns I<Matrix>.
3133
3134 =item B<ZeroMatrix>
3135
3136 $NewZeroMatrix = $Matrix::ZeroMatrix($NumOfRows, $NumOfCols);
3137 $NewZeroMatrix = $Matrix::ZeroMatrix();
3138 $NewZeroMatrix = $Matrix->ZeroMatrix($NumOfRows, $NumOfCols);
3139
3140 Creates a new B<ZeroMatrix> of specified size I<NumOfRows x NumOfCol> or of size 3 x 3 and
3141 returns B<NewZeroMatrix> object.
3142
3143 =back
3144
3145 =head1 AUTHOR
3146
3147 Manish Sud <msud@san.rr.com>
3148
3149 =head1 SEE ALSO
3150
3151 Vector.pm
3152
3153 =head1 COPYRIGHT
3154
3155 Copyright (C) 2015 Manish Sud. All rights reserved.
3156
3157 This file is part of MayaChemTools.
3158
3159 MayaChemTools is free software; you can redistribute it and/or modify it under
3160 the terms of the GNU Lesser General Public License as published by the Free
3161 Software Foundation; either version 3 of the License, or (at your option)
3162 any later version.
3163
3164 =cut