1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
20 #define No_Standard_RangeError
21 #define No_Standard_OutOfRange
22 #define No_Standard_DimensionError
25 #include <math_Matrix.ixx>
26 #include <math_Vector.hxx>
28 #include <Standard_DimensionError.hxx>
29 #include <Standard_DivideByZero.hxx>
30 #include <Standard_RangeError.hxx>
31 #include <math_SingularMatrix.hxx>
32 #include <math_NotSquare.hxx>
33 #include <math_Gauss.hxx>
36 void math_Matrix::SetLowerRow(const Standard_Integer LowerRow) {
38 Array.SetLowerRow(LowerRow);
39 Standard_Integer Rows = RowNumber();
40 LowerRowIndex = LowerRow;
41 UpperRowIndex = LowerRowIndex + Rows - 1;
44 void math_Matrix::SetLowerCol(const Standard_Integer LowerCol) {
46 Array.SetLowerCol(LowerCol);
47 Standard_Integer Cols = ColNumber();
48 LowerColIndex = LowerCol;
49 UpperColIndex = LowerColIndex + Cols - 1;
52 math_Matrix::math_Matrix (const Standard_Integer LowerRow,
53 const Standard_Integer UpperRow,
54 const Standard_Integer LowerCol,
55 const Standard_Integer UpperCol):
57 LowerRowIndex(LowerRow),
58 UpperRowIndex(UpperRow),
59 LowerColIndex(LowerCol),
60 UpperColIndex(UpperCol),
61 Array(LowerRow, UpperRow,
65 Standard_RangeError_Raise_if((LowerRow > UpperRow) ||
66 (LowerCol > UpperCol), "");
69 math_Matrix::math_Matrix (const Standard_Integer LowerRow,
70 const Standard_Integer UpperRow,
71 const Standard_Integer LowerCol,
72 const Standard_Integer UpperCol,
73 const Standard_Real InitialValue):
75 LowerRowIndex(LowerRow),
76 UpperRowIndex(UpperRow),
77 LowerColIndex(LowerCol),
78 UpperColIndex(UpperCol),
79 Array(LowerRow, UpperRow,
83 Standard_RangeError_Raise_if((LowerRow > UpperRow) ||
84 (LowerCol > UpperCol), "");
85 Array.Init(InitialValue);
88 math_Matrix::math_Matrix (const Standard_Address Tab,
89 const Standard_Integer LowerRow,
90 const Standard_Integer UpperRow,
91 const Standard_Integer LowerCol,
92 const Standard_Integer UpperCol) :
94 LowerRowIndex(LowerRow),
95 UpperRowIndex(UpperRow),
96 LowerColIndex(LowerCol),
97 UpperColIndex(UpperCol),
98 Array(*((const Standard_Real *)Tab),
103 Standard_RangeError_Raise_if((LowerRow > UpperRow) ||
104 (LowerCol > UpperCol), "");
107 void math_Matrix::Init(const Standard_Real InitialValue)
109 Array.Init(InitialValue);
112 math_Matrix::math_Matrix (const math_Matrix& Other):
114 LowerRowIndex(Other.LowerRow()),
115 UpperRowIndex(Other.UpperRow()),
116 LowerColIndex(Other.LowerCol()),
117 UpperColIndex(Other.UpperCol()),
124 math_Matrix math_Matrix::Divided (const Standard_Real Right) const
126 Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), "");
127 math_Matrix temp = Multiplied(1./Right);
132 Standard_Real math_Matrix::Determinant() const
134 math_Gauss Sol(*this);
137 return Sol.Determinant();
144 void math_Matrix::Transpose()
146 math_NotSquare_Raise_if(RowNumber() != ColNumber(), "");
148 Standard_Integer Row = LowerRowIndex;
149 Standard_Integer Col = LowerColIndex;
150 SetLowerCol(LowerRowIndex);
152 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
153 for(Standard_Integer J = I; J <= UpperColIndex; J++) {
155 Array(I, J) = Array(J, I);
163 math_Matrix math_Matrix::Transposed() const
165 math_Matrix Result(LowerColIndex, UpperColIndex,
166 LowerRowIndex, UpperRowIndex);
168 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
169 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
170 Result.Array(J, I) = Array(I, J);
176 void math_Matrix::Invert()
178 math_NotSquare_Raise_if(RowNumber() != ColNumber(), "");
180 math_Gauss Sol(*this);
185 math_SingularMatrix::Raise(); // SingularMatrix Exception;
189 math_Matrix math_Matrix::Inverse() const
192 math_Matrix Result = *this;
197 void math_Matrix::Multiply (const Standard_Real Right)
199 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
200 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
201 Array(I, J) = Array(I, J) * Right;
206 math_Matrix math_Matrix::Multiplied (const Standard_Real Right) const
208 math_Matrix Result(LowerRowIndex, UpperRowIndex,
209 LowerColIndex, UpperColIndex);
210 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
211 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
212 Result.Array(I, J) = Array(I, J) * Right;
218 math_Matrix math_Matrix::TMultiplied (const Standard_Real Right) const
220 math_Matrix Result(LowerRowIndex, UpperRowIndex,
221 LowerColIndex, UpperColIndex);
222 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
223 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
224 Result.Array(I, J) = Array(I, J) * Right;
232 void math_Matrix::Divide (const Standard_Real Right)
234 Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), "");
236 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
237 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
238 Array(I, J) = Array(I, J) / Right;
243 void math_Matrix::Add (const math_Matrix& Right)
245 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
246 (ColNumber() != Right.ColNumber()),
249 Standard_Integer I2 = Right.LowerRowIndex;
250 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
251 Standard_Integer J2 = Right.LowerColIndex;
252 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
253 Array(I, J) = Array(I, J) + Right.Array(I2, J2);
260 void math_Matrix::Subtract (const math_Matrix& Right)
262 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
263 (ColNumber() != Right.ColNumber()),
266 Standard_Integer I2 = Right.LowerRowIndex;
267 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
268 Standard_Integer J2 = Right.LowerColIndex;
269 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
270 Array(I, J) = Array(I, J) - Right.Array(I2, J2);
277 void math_Matrix::Set(const Standard_Integer I1,const Standard_Integer I2,
278 const Standard_Integer J1,const Standard_Integer J2,
279 const math_Matrix& M)
282 Standard_DimensionError_Raise_if((I1 < LowerRowIndex) ||
283 (I2 > UpperRowIndex) ||
284 (J1 < LowerColIndex) ||
285 (J2 > UpperColIndex) ||
286 (I1 > I2) || (J1 > J2) ||
287 (I2-I1+1 != M.RowNumber()) ||
288 (J2-J1+1 != M.ColNumber()), "");
290 Standard_Integer II = M.LowerRow();
291 for(Standard_Integer I = I1; I <= I2; I++) {
292 Standard_Integer JJ = M.LowerCol();
293 for(Standard_Integer J = J1; J <= J2; J++) {
294 Array(I, J) = M.Array(II, JJ);
301 void math_Matrix::SetRow (const Standard_Integer Row,
302 const math_Vector& V)
305 Standard_RangeError_Raise_if((Row < LowerRowIndex) ||
306 (Row > UpperRowIndex) , "");
308 Standard_DimensionError_Raise_if(ColNumber() != V.Length(), "");
310 Standard_Integer I = V.LowerIndex;
311 for(Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++) {
312 Array(Row, Index) = V.Array(I);
317 void math_Matrix::SetCol (const Standard_Integer Col,
318 const math_Vector& V)
321 Standard_RangeError_Raise_if((Col < LowerColIndex) ||
322 (Col > UpperColIndex) , "");
324 Standard_DimensionError_Raise_if(RowNumber() != V.Length(), "");
326 Standard_Integer I = V.LowerIndex;
327 for(Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++) {
328 Array(Index, Col) = V.Array(I);
333 void math_Matrix::SetDiag(const Standard_Real Value)
336 math_NotSquare_Raise_if(RowNumber() != ColNumber(), "");
338 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
342 math_Vector math_Matrix::Row (const Standard_Integer Row) const
345 math_Vector Result(LowerColIndex, UpperColIndex);
347 for(Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++) {
348 Result.Array(Index) = Array(Row, Index);
353 math_Vector math_Matrix::Col (const Standard_Integer Col) const
356 math_Vector Result(LowerRowIndex, UpperRowIndex);
358 for(Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++) {
359 Result.Array(Index) = Array(Index, Col);
364 void math_Matrix::SwapRow(const Standard_Integer Row1,
365 const Standard_Integer Row2)
368 Standard_RangeError_Raise_if((Row1 < LowerRowIndex) ||
369 (Row1 > UpperRowIndex) ||
370 (Row2 < LowerRowIndex) ||
371 (Row2 > UpperRowIndex), "");
373 math_Vector V1 = Row(Row1);
374 math_Vector V2 = Row(Row2);
379 void math_Matrix::SwapCol(const Standard_Integer Col1,
380 const Standard_Integer Col2)
383 Standard_RangeError_Raise_if((Col1 < LowerColIndex) ||
384 (Col1 > UpperColIndex) ||
385 (Col2 < LowerColIndex) ||
386 (Col2 > UpperColIndex), "");
388 math_Vector V1 = Col(Col1);
389 math_Vector V2 = Col(Col2);
396 math_Matrix math_Matrix::Multiplied (const math_Matrix& Right) const
399 Standard_DimensionError_Raise_if(ColNumber() != Right.RowNumber(), "");
401 math_Matrix Result(LowerRowIndex, UpperRowIndex,
402 Right.LowerColIndex, Right.UpperColIndex);
405 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
406 for(Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) {
408 Standard_Integer I2 = Right.LowerRowIndex;
409 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
410 Som = Som + Array(I, J) * Right.Array(I2, J2);
413 Result.Array(I, J2) = Som;
419 math_Matrix math_Matrix::TMultiply (const math_Matrix& Right) const
422 Standard_DimensionError_Raise_if(RowNumber() != Right.RowNumber(), "");
424 math_Matrix Result(LowerColIndex, UpperColIndex,
425 Right.LowerColIndex, Right.UpperColIndex);
428 for(Standard_Integer I = LowerColIndex; I <= UpperColIndex; I++) {
429 for(Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) {
431 Standard_Integer I2 = Right.LowerRowIndex;
432 for(Standard_Integer J = LowerRowIndex; J <= UpperRowIndex; J++) {
433 Som = Som + Array(J, I) * Right.Array(I2, J2);
436 Result.Array(I, J2) = Som;
442 math_Matrix math_Matrix::Added (const math_Matrix& Right) const
445 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
446 (ColNumber() != Right.ColNumber()),
449 math_Matrix Result(LowerRowIndex, UpperRowIndex,
450 LowerColIndex, UpperColIndex);
452 Standard_Integer I2 = Right.LowerRowIndex;
453 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
454 Standard_Integer J2 = Right.LowerColIndex;
455 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
456 Result.Array(I, J) = Array(I, J) + Right.Array(I2, J2);
464 math_Matrix math_Matrix::Opposite ()
467 math_Matrix Result(LowerRowIndex, UpperRowIndex,
468 LowerColIndex, UpperColIndex);
470 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
471 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
472 Result.Array(I, J) = - Array(I, J);
478 math_Matrix math_Matrix::Subtracted (const math_Matrix& Right) const
481 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
482 (ColNumber() != Right.ColNumber()),
485 math_Matrix Result(LowerRowIndex, UpperRowIndex,
486 LowerColIndex, UpperColIndex);
488 Standard_Integer I2 = Right.LowerRowIndex;
489 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
490 Standard_Integer J2 = Right.LowerColIndex;
491 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
492 Result.Array(I, J) = Array(I, J) - Right.Array(I2, J2);
500 void math_Matrix::Multiply(const math_Vector& Left,
501 const math_Vector& Right)
504 Standard_DimensionError_Raise_if((RowNumber() != Left.Length()) ||
505 (ColNumber() != Right.Length()),
508 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
509 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
510 Array(I, J) = Left.Array(I) * Right.Array(J);
515 void math_Matrix::Multiply(const math_Matrix& Left,
516 const math_Matrix& Right)
519 Standard_DimensionError_Raise_if((Left.ColNumber() != Right.RowNumber()) ||
520 (RowNumber() != Left.RowNumber()) ||
521 (ColNumber() != Right.ColNumber()),
525 Standard_Integer I1 = Left.LowerRowIndex;
526 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
527 Standard_Integer J2 = Right.LowerColIndex;
528 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
530 Standard_Integer J1 = Left.LowerColIndex;
531 Standard_Integer I2 = Right.LowerRowIndex;
532 for(Standard_Integer K = Left.LowerColIndex; K <= Left.UpperColIndex; K++) {
533 Som = Som + Left.Array(I1, J1) * Right.Array(I2, J2);
544 void math_Matrix::TMultiply(const math_Matrix& TLeft,
545 const math_Matrix& Right)
548 Standard_DimensionError_Raise_if((TLeft.RowNumber() != Right.RowNumber()) ||
549 (RowNumber() != TLeft.ColNumber()) ||
550 (ColNumber() != Right.ColNumber()),
554 Standard_Integer I1 = TLeft.LowerColIndex;
555 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
556 Standard_Integer J2 = Right.LowerColIndex;
557 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
559 Standard_Integer J1 = TLeft.LowerRowIndex;
560 Standard_Integer I2 = Right.LowerRowIndex;
561 for(Standard_Integer K = TLeft.LowerRowIndex; K <= TLeft.UpperRowIndex; K++) {
562 Som = Som + TLeft.Array(J1, I1) * Right.Array(I2, J2);
573 void math_Matrix::Add (const math_Matrix& Left,
574 const math_Matrix& Right)
577 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
578 (ColNumber() != Right.ColNumber()) ||
579 (Right.RowNumber() != Left.RowNumber()) ||
580 (Right.ColNumber() != Left.ColNumber()),
583 Standard_Integer I1 = Left.LowerRowIndex;
584 Standard_Integer I2 = Right.LowerRowIndex;
585 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
586 Standard_Integer J1 = Left.LowerColIndex;
587 Standard_Integer J2 = Right.LowerColIndex;
588 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
589 Array(I, J) = Left.Array(I1, J1) + Right.Array(I2, J2);
598 void math_Matrix::Subtract(const math_Matrix& Left,
599 const math_Matrix& Right)
602 Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) ||
603 (ColNumber() != Right.ColNumber()) ||
604 (Right.RowNumber() != Left.RowNumber()) ||
605 (Right.ColNumber() != Left.ColNumber()),
608 Standard_Integer I1 = Left.LowerRowIndex;
609 Standard_Integer I2 = Right.LowerRowIndex;
610 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
611 Standard_Integer J1 = Left.LowerColIndex;
612 Standard_Integer J2 = Right.LowerColIndex;
613 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
614 Array(I, J) = Left.Array(I1, J1) - Right.Array(I2, J2);
624 void math_Matrix::Multiply(const math_Matrix& Right)
627 Standard_DimensionError_Raise_if(ColNumber() != Right.RowNumber(), "");
630 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
631 for(Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) {
633 Standard_Integer I2 = Right.LowerRowIndex;
634 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
635 Som = Som + Array(I, J) * Right.Array(I2, J2);
645 math_Vector math_Matrix::Multiplied(const math_Vector& Right)const
648 Standard_DimensionError_Raise_if(ColNumber() != Right.Length(), "");
650 math_Vector Result(LowerRowIndex, UpperRowIndex);
652 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
653 Result.Array(I) = 0.0;
654 Standard_Integer II = Right.LowerIndex;
655 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
656 Result.Array(I) = Result.Array(I) + Array(I, J) * Right.Array(II);
663 math_Matrix& math_Matrix::Initialized(const math_Matrix& Other)
666 Standard_DimensionError_Raise_if((RowNumber() != Other.RowNumber()) ||
667 (ColNumber() != Other.ColNumber()), "");
669 (Other.Array).Copy(Array);
676 void math_Matrix::Dump(Standard_OStream& o)const
679 o << "math_Matrix of RowNumber = " << RowNumber();
680 o << " and ColNumber = " << ColNumber() << "\n";
682 for(Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) {
683 for(Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) {
684 o << "math_Matrix ( " << I << ", " << J << " ) = ";
685 o << Array(I, J) << "\n";