Mercurial > repos > deepakjadmin > r_caret_test1
comparison mayachemtool/mayachemtools/lib/Matrix.pm @ 0:a4a2ad5a214e draft default tip
Uploaded
| author | deepakjadmin |
|---|---|
| date | Thu, 05 Nov 2015 02:37:56 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:a4a2ad5a214e |
|---|---|
| 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 |
