0
|
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
|