From: Pasukhin Dmitry Date: Sun, 9 Nov 2025 15:27:10 +0000 (+0000) Subject: Foundation Classes, math_Matrix - Remove redundant checks and inline methods (#814) X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=989f00b9c4ed06a1a7327809b4ddec6820b2f8a5;p=occt.git Foundation Classes, math_Matrix - Remove redundant checks and inline methods (#814) - Eliminated redundant member variables (`LowerRowIndex`, `UpperRowIndex`, `LowerColIndex`, `UpperColIndex`) that duplicated information already tracked by the underlying `math_DoubleTab Array` - Inlined most `math_Matrix` methods into the `.lxx` file for better performance - Updated all access patterns to use the `Array` member's methods directly - Added `noexcept` qualifiers to non-throwing methods - Modernized operator implementations (e.g., `operator-()` now returns `const`) --- diff --git a/src/FoundationClasses/TKMath/math/math_DoubleTab.hxx b/src/FoundationClasses/TKMath/math/math_DoubleTab.hxx index 66ff0e6c7a..c386b4d4e1 100644 --- a/src/FoundationClasses/TKMath/math/math_DoubleTab.hxx +++ b/src/FoundationClasses/TKMath/math/math_DoubleTab.hxx @@ -86,6 +86,24 @@ public: //! Set lower column index void SetLowerCol(const Standard_Integer theLowerCol) { myArray.UpdateLowerCol(theLowerCol); } + //! Get lower row index + Standard_Integer LowerRow() const noexcept { return myArray.LowerRow(); } + + //! Get upper row index + Standard_Integer UpperRow() const noexcept { return myArray.UpperRow(); } + + //! Get lower column index + Standard_Integer LowerCol() const noexcept { return myArray.LowerCol(); } + + //! Get upper column index + Standard_Integer UpperCol() const noexcept { return myArray.UpperCol(); } + + //! Get number of rows + Standard_Integer NbRows() const noexcept { return myArray.NbRows(); } + + //! Get number of columns + Standard_Integer NbColumns() const noexcept { return myArray.NbColumns(); } + //! Access element at (theRowIndex, theColIndex) const Standard_Real& Value(const Standard_Integer theRowIndex, const Standard_Integer theColIndex) const diff --git a/src/FoundationClasses/TKMath/math/math_Matrix.cxx b/src/FoundationClasses/TKMath/math/math_Matrix.cxx index b7fa5177ab..2d2933c75d 100644 --- a/src/FoundationClasses/TKMath/math/math_Matrix.cxx +++ b/src/FoundationClasses/TKMath/math/math_Matrix.cxx @@ -13,705 +13,196 @@ // commercial license or contractual agreement. #include - +#include #include -#include #include #include -#include #include -#include -#include - -void math_Matrix::SetLowerRow(const Standard_Integer LowerRow) -{ - - Array.SetLowerRow(LowerRow); - Standard_Integer Rows = RowNumber(); - LowerRowIndex = LowerRow; - UpperRowIndex = LowerRowIndex + Rows - 1; -} - -void math_Matrix::SetLowerCol(const Standard_Integer LowerCol) -{ - - Array.SetLowerCol(LowerCol); - Standard_Integer Cols = ColNumber(); - LowerColIndex = LowerCol; - UpperColIndex = LowerColIndex + Cols - 1; -} - -math_Matrix::math_Matrix(const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol) - : - - LowerRowIndex(LowerRow), - UpperRowIndex(UpperRow), - LowerColIndex(LowerCol), - UpperColIndex(UpperCol), - Array(LowerRow, UpperRow, LowerCol, UpperCol) -{ - Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol), - "math_Matrix() - invalid dimensions"); -} - -math_Matrix::math_Matrix(const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol, - const Standard_Real InitialValue) - : - - LowerRowIndex(LowerRow), - UpperRowIndex(UpperRow), - LowerColIndex(LowerCol), - UpperColIndex(UpperCol), - Array(LowerRow, UpperRow, LowerCol, UpperCol) -{ - Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol), - "math_Matrix() - invalid dimensions"); - Array.Init(InitialValue); -} - -math_Matrix::math_Matrix(const Standard_Address Tab, - const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol) - : - - LowerRowIndex(LowerRow), - UpperRowIndex(UpperRow), - LowerColIndex(LowerCol), - UpperColIndex(UpperCol), - Array(Tab, LowerRow, UpperRow, LowerCol, UpperCol) -{ - Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol), - "math_Matrix() - invalid dimensions"); -} - -void math_Matrix::Init(const Standard_Real InitialValue) -{ - Array.Init(InitialValue); -} - -math_Matrix::math_Matrix(const math_Matrix& Other) - : - - LowerRowIndex(Other.LowerRow()), - UpperRowIndex(Other.UpperRow()), - LowerColIndex(Other.LowerCol()), - UpperColIndex(Other.UpperCol()), - Array(Other.Array) -{ -} - -math_Matrix math_Matrix::Divided(const Standard_Real Right) const -{ - Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), - "math_Matrix::Divided() - zero divisor"); - math_Matrix temp = Multiplied(1. / Right); - return temp; -} - -Standard_Real math_Matrix::Determinant() const -{ - math_Gauss Sol(*this); - - if (Sol.IsDone()) - { - return Sol.Determinant(); - } - else - { - return 0.0; - } -} - -void math_Matrix::Transpose() -{ - math_NotSquare_Raise_if(RowNumber() != ColNumber(), - "math_Matrix::Transpose() - matrix is not square"); - - Standard_Integer Row = LowerRowIndex; - Standard_Integer Col = LowerColIndex; - SetLowerCol(LowerRowIndex); - Standard_Real Temp; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = I; J <= UpperColIndex; J++) - { - Temp = Array(I, J); - Array(I, J) = Array(J, I); - Array(J, I) = Temp; - } - } - SetLowerRow(Col); - SetLowerCol(Row); -} - -math_Matrix math_Matrix::Transposed() const -{ - math_Matrix Result(LowerColIndex, UpperColIndex, LowerRowIndex, UpperRowIndex); - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Result.Array(J, I) = Array(I, J); - } - } - return Result; -} - -void math_Matrix::Invert() -{ - math_NotSquare_Raise_if(RowNumber() != ColNumber(), - "math_Matrix::Transpose() - matrix is not square"); - - math_Gauss Sol(*this); - if (Sol.IsDone()) - { - Sol.Invert(*this); - } - else - { - throw math_SingularMatrix(); // SingularMatrix Exception; - } -} - -math_Matrix math_Matrix::Inverse() const -{ - - math_Matrix Result = *this; - Result.Invert(); - return Result; -} - -void math_Matrix::Multiply(const Standard_Real Right) -{ - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Array(I, J) * Right; - } - } -} - -math_Matrix math_Matrix::Multiplied(const Standard_Real Right) const -{ - math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex); - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Result.Array(I, J) = Array(I, J) * Right; - } - } - return Result; -} -math_Matrix math_Matrix::TMultiplied(const Standard_Real Right) const -{ - math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex); - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Result.Array(I, J) = Array(I, J) * Right; - } - } - return Result; -} - -void math_Matrix::Divide(const Standard_Real Right) -{ - Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), - "math_Matrix::Divide() - zero divisor"); - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Array(I, J) / Right; - } - } -} - -void math_Matrix::Add(const math_Matrix& Right) -{ - Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) - || (ColNumber() != Right.ColNumber()), - "math_Matrix::Add() - input matrix has different dimensions"); - - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Array(I, J) + Right.Array(I2, J2); - J2++; - } - I2++; - } -} - -void math_Matrix::Subtract(const math_Matrix& Right) -{ - Standard_DimensionError_Raise_if( - (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()), - "math_Matrix::Subtract() - input matrix has different dimensions"); - - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Array(I, J) - Right.Array(I2, J2); - J2++; - } - I2++; - } -} - -void math_Matrix::Set(const Standard_Integer I1, - const Standard_Integer I2, - const Standard_Integer J1, - const Standard_Integer J2, - const math_Matrix& M) -{ - - Standard_DimensionError_Raise_if( - (I1 < LowerRowIndex) || (I2 > UpperRowIndex) || (J1 < LowerColIndex) || (J2 > UpperColIndex) - || (I1 > I2) || (J1 > J2) || (I2 - I1 + 1 != M.RowNumber()) || (J2 - J1 + 1 != M.ColNumber()), - "math_Matrix::Set() - invalid indices"); - - Standard_Integer II = M.LowerRow(); - for (Standard_Integer I = I1; I <= I2; I++) - { - Standard_Integer JJ = M.LowerCol(); - for (Standard_Integer J = J1; J <= J2; J++) - { - Array(I, J) = M.Array(II, JJ); - JJ++; - } - II++; - } -} +//================================================================================================== void math_Matrix::SetRow(const Standard_Integer Row, const math_Vector& V) { - Standard_RangeError_Raise_if((Row < LowerRowIndex) || (Row > UpperRowIndex), - "math_Matrix::SetRow() - invalid index"); - Standard_DimensionError_Raise_if(ColNumber() != V.Length(), "math_Matrix::SetRow() - input vector has wrong dimensions"); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + Standard_Integer I = V.Lower(); - for (Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++) + for (Standard_Integer Index = aLowerCol; Index <= anUpperCol; Index++) { - Array(Row, Index) = V.Array(I); + Array(Row, Index) = V(I); I++; } } +//================================================================================================== + void math_Matrix::SetCol(const Standard_Integer Col, const math_Vector& V) { - Standard_RangeError_Raise_if((Col < LowerColIndex) || (Col > UpperColIndex), - "math_Matrix::SetCol() - invalid index"); - Standard_DimensionError_Raise_if(RowNumber() != V.Length(), "math_Matrix::SetCol() - input vector has wrong dimensions"); + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + Standard_Integer I = V.Lower(); - for (Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++) + for (Standard_Integer Index = aLowerRow; Index <= anUpperRow; Index++) { - Array(Index, Col) = V.Array(I); + Array(Index, Col) = V(I); I++; } } -void math_Matrix::SetDiag(const Standard_Real Value) -{ - math_NotSquare_Raise_if(RowNumber() != ColNumber(), - "math_Matrix::SetDiag() - matrix is not square"); - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - Array(I, I) = Value; - } -} +//================================================================================================== math_Vector math_Matrix::Row(const Standard_Integer Row) const { + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); - math_Vector Result(LowerColIndex, UpperColIndex); + math_Vector Result(aLowerCol, anUpperCol); - for (Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++) + for (Standard_Integer Index = aLowerCol; Index <= anUpperCol; Index++) { - Result.Array(Index) = Array(Row, Index); + Result(Index) = Array(Row, Index); } return Result; } +//================================================================================================== + math_Vector math_Matrix::Col(const Standard_Integer Col) const { + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); - math_Vector Result(LowerRowIndex, UpperRowIndex); + math_Vector Result(aLowerRow, anUpperRow); - for (Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++) + for (Standard_Integer Index = aLowerRow; Index <= anUpperRow; Index++) { - Result.Array(Index) = Array(Index, Col); + Result(Index) = Array(Index, Col); } return Result; } +//================================================================================================== + void math_Matrix::SwapRow(const Standard_Integer Row1, const Standard_Integer Row2) { - Standard_RangeError_Raise_if((Row1 < LowerRowIndex) || (Row1 > UpperRowIndex) - || (Row2 < LowerRowIndex) || (Row2 > UpperRowIndex), - "math_Matrix::SetCol() - invalid indices"); - math_Vector V1 = Row(Row1); math_Vector V2 = Row(Row2); SetRow(Row1, V2); SetRow(Row2, V1); } +//================================================================================================== + void math_Matrix::SwapCol(const Standard_Integer Col1, const Standard_Integer Col2) { - Standard_RangeError_Raise_if((Col1 < LowerColIndex) || (Col1 > UpperColIndex) - || (Col2 < LowerColIndex) || (Col2 > UpperColIndex), - "math_Matrix::SetCol() - invalid indices"); - math_Vector V1 = Col(Col1); math_Vector V2 = Col(Col2); SetCol(Col1, V2); SetCol(Col2, V1); } -math_Matrix math_Matrix::Multiplied(const math_Matrix& Right) const -{ - Standard_DimensionError_Raise_if( - ColNumber() != Right.RowNumber(), - "math_Matrix::Multiplied() - matrices have incompatible dimensions"); - - math_Matrix Result(LowerRowIndex, UpperRowIndex, Right.LowerColIndex, Right.UpperColIndex); +//================================================================================================== - Standard_Real Som; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) - { - Som = 0.0; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Som = Som + Array(I, J) * Right.Array(I2, J2); - I2++; - } - Result.Array(I, J2) = Som; - } - } - return Result; -} - -math_Matrix math_Matrix::TMultiply(const math_Matrix& Right) const +void math_Matrix::Multiply(const math_Vector& Left, const math_Vector& Right) { Standard_DimensionError_Raise_if( - RowNumber() != Right.RowNumber(), - "math_Matrix::TMultiply() - matrices have incompatible dimensions"); - - math_Matrix Result(LowerColIndex, UpperColIndex, Right.LowerColIndex, Right.UpperColIndex); - - Standard_Real Som; - for (Standard_Integer I = LowerColIndex; I <= UpperColIndex; I++) - { - for (Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) - { - Som = 0.0; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer J = LowerRowIndex; J <= UpperRowIndex; J++) - { - Som = Som + Array(J, I) * Right.Array(I2, J2); - I2++; - } - Result.Array(I, J2) = Som; - } - } - return Result; -} - -math_Matrix math_Matrix::Added(const math_Matrix& Right) const -{ - Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) - || (ColNumber() != Right.ColNumber()), - "math_Matrix::Added() - input matrix has different dimensions"); + (RowNumber() != Left.Length()) || (ColNumber() != Right.Length()), + "math_Matrix::Multiply() - input vectors have incompatible dimensions"); - math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex); + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) { - Result.Array(I, J) = Array(I, J) + Right.Array(I2, J2); - J2++; + Array(I, J) = Left(I) * Right(J); } - I2++; } - return Result; } -math_Matrix math_Matrix::Opposite() -{ - - math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex); - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Result.Array(I, J) = -Array(I, J); - } - } - return Result; -} +//================================================================================================== -math_Matrix math_Matrix::Subtracted(const math_Matrix& Right) const +math_Vector math_Matrix::Multiplied(const math_Vector& Right) const { Standard_DimensionError_Raise_if( - (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()), - "math_Matrix::Subtracted() - input matrix has different dimensions"); + ColNumber() != Right.Length(), + "math_Matrix::Multiplied() - input vector has incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); - math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex); + math_Vector Result(aLowerRow, anUpperRow); - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) + Result(I) = 0.0; + Standard_Integer II = Right.Lower(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) { - Result.Array(I, J) = Array(I, J) - Right.Array(I2, J2); - J2++; + Result(I) = Result(I) + Array(I, J) * Right(II); + II++; } - I2++; } return Result; } -void math_Matrix::Multiply(const math_Vector& Left, const math_Vector& Right) -{ - Standard_DimensionError_Raise_if( - (RowNumber() != Left.Length()) || (ColNumber() != Right.Length()), - "math_Matrix::Multiply() - input vectors have incompatible dimensions"); +//================================================================================================== - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Left.Array(I) * Right.Array(J); - } - } -} - -void math_Matrix::Multiply(const math_Matrix& Left, const math_Matrix& Right) +math_Vector math_Matrix::operator*(const math_Vector& Right) const { - Standard_DimensionError_Raise_if( - (Left.ColNumber() != Right.RowNumber()) || (RowNumber() != Left.RowNumber()) - || (ColNumber() != Right.ColNumber()), - "math_Matrix::Multiply() - matrices have incompatible dimensions"); - - Standard_Real Som; - Standard_Integer I1 = Left.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Som = 0.0; - Standard_Integer J1 = Left.LowerColIndex; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer K = Left.LowerColIndex; K <= Left.UpperColIndex; K++) - { - Som = Som + Left.Array(I1, J1) * Right.Array(I2, J2); - J1++; - I2++; - } - Array(I, J) = Som; - J2++; - } - I1++; - } + return Multiplied(Right); } -void math_Matrix::TMultiply(const math_Matrix& TLeft, const math_Matrix& Right) -{ - Standard_DimensionError_Raise_if( - (TLeft.RowNumber() != Right.RowNumber()) || (RowNumber() != TLeft.ColNumber()) - || (ColNumber() != Right.ColNumber()), - "math_Matrix::TMultiply() - matrices have incompatible dimensions"); - - Standard_Real Som; - Standard_Integer I1 = TLeft.LowerColIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Som = 0.0; - Standard_Integer J1 = TLeft.LowerRowIndex; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer K = TLeft.LowerRowIndex; K <= TLeft.UpperRowIndex; K++) - { - Som = Som + TLeft.Array(J1, I1) * Right.Array(I2, J2); - J1++; - I2++; - } - Array(I, J) = Som; - J2++; - } - I1++; - } -} +//================================================================================================== -void math_Matrix::Add(const math_Matrix& Left, const math_Matrix& Right) +Standard_Real math_Matrix::Determinant() const { - Standard_DimensionError_Raise_if( - (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()) - || (Right.RowNumber() != Left.RowNumber()) || (Right.ColNumber() != Left.ColNumber()), - "math_Matrix::Add() - matrices have incompatible dimensions"); + math_Gauss Sol(*this); - Standard_Integer I1 = Left.LowerRowIndex; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + if (Sol.IsDone()) { - Standard_Integer J1 = Left.LowerColIndex; - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Left.Array(I1, J1) + Right.Array(I2, J2); - J1++; - J2++; - } - I1++; - I2++; + return Sol.Determinant(); } -} - -void math_Matrix::Subtract(const math_Matrix& Left, const math_Matrix& Right) -{ - Standard_DimensionError_Raise_if( - (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()) - || (Right.RowNumber() != Left.RowNumber()) || (Right.ColNumber() != Left.ColNumber()), - "math_Matrix::Subtract() - matrices have incompatible dimensions"); - - Standard_Integer I1 = Left.LowerRowIndex; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + else { - Standard_Integer J1 = Left.LowerColIndex; - Standard_Integer J2 = Right.LowerColIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Array(I, J) = Left.Array(I1, J1) - Right.Array(I2, J2); - J1++; - J2++; - } - I1++; - I2++; + return 0.0; } } -void math_Matrix::Multiply(const math_Matrix& Right) -{ - Standard_DimensionError_Raise_if( - ColNumber() != Right.RowNumber(), - "math_Matrix::Multiply() - input matrix has incompatible dimensions"); +//================================================================================================== - // Create a temporary copy to avoid corrupting our own data during calculation - math_Matrix aTemp = *this; - if (this == &Right) - { - Multiply(aTemp, aTemp); - return; - } +void math_Matrix::Invert() +{ + math_NotSquare_Raise_if(RowNumber() != ColNumber(), + "math_Matrix::Invert() - matrix is not square"); - Standard_Real Som; - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + math_Gauss Sol(*this); + if (Sol.IsDone()) { - for (Standard_Integer J2 = Right.LowerColIndex; J2 <= Right.UpperColIndex; J2++) - { - Som = 0.0; - Standard_Integer I2 = Right.LowerRowIndex; - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Som += aTemp.Array(I, J) * Right.Array(I2, J2); - I2++; - } - Array(I, J2) = Som; - } + Sol.Invert(*this); } -} - -math_Vector math_Matrix::Multiplied(const math_Vector& Right) const -{ - Standard_DimensionError_Raise_if( - ColNumber() != Right.Length(), - "math_Matrix::Multiplied() - input vector has incompatible dimensions"); - - math_Vector Result(LowerRowIndex, UpperRowIndex); - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) + else { - Result.Array(I) = 0.0; - Standard_Integer II = Right.Lower(); - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - Result.Array(I) = Result.Array(I) + Array(I, J) * Right.Array(II); - II++; - } + throw math_SingularMatrix(); } - return Result; } -//================================================================ -// Function : operator* -// Purpose : -//================================================================ -math_VectorBase<> math_Matrix::operator*(const math_VectorBase<>& Right) const -{ - return Multiplied(Right); -} - -math_Matrix& math_Matrix::Initialized(const math_Matrix& Other) -{ - Standard_DimensionError_Raise_if( - (RowNumber() != Other.RowNumber()) || (ColNumber() != Other.ColNumber()), - "math_Matrix::Initialized() - input matrix has different dimensions"); - - (Other.Array).Copy(Array); - return *this; -} - -void math_Matrix::Dump(Standard_OStream& o) const +//================================================================================================== +math_Matrix math_Matrix::Inverse() const { - o << "math_Matrix of RowNumber = " << RowNumber(); - o << " and ColNumber = " << ColNumber() << "\n"; - - for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++) - { - for (Standard_Integer J = LowerColIndex; J <= UpperColIndex; J++) - { - o << "math_Matrix ( " << I << ", " << J << " ) = "; - o << Array(I, J) << "\n"; - } - } + math_Matrix Result = *this; + Result.Invert(); + return Result; } diff --git a/src/FoundationClasses/TKMath/math/math_Matrix.hxx b/src/FoundationClasses/TKMath/math/math_Matrix.hxx index 80cdb5a6ba..ba1763ee48 100644 --- a/src/FoundationClasses/TKMath/math/math_Matrix.hxx +++ b/src/FoundationClasses/TKMath/math/math_Matrix.hxx @@ -76,8 +76,6 @@ class math_Matrix public: DEFINE_STANDARD_ALLOC - friend class math_VectorBase<>; - //! Constructs a non-initialized matrix of range [LowerRow..UpperRow, //! LowerCol..UpperCol] //! For the constructed matrix: @@ -85,35 +83,38 @@ public: //! lower and upper bounds of a row, and //! - LowerCol and UpperCol are the indexes of the //! lower and upper bounds of a column. - Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol); + inline math_Matrix(const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol); //! constructs a non-initialized matrix of range [LowerRow..UpperRow, //! LowerCol..UpperCol] //! whose values are all initialized with the value InitialValue. - Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol, - const Standard_Real InitialValue); + inline math_Matrix(const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol, + const Standard_Real InitialValue); //! constructs a matrix of range [LowerRow..UpperRow, //! LowerCol..UpperCol] //! Sharing data with a "C array" pointed by Tab. - Standard_EXPORT math_Matrix(const Standard_Address Tab, - const Standard_Integer LowerRow, - const Standard_Integer UpperRow, - const Standard_Integer LowerCol, - const Standard_Integer UpperCol); + inline math_Matrix(const Standard_Address Tab, + const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol); //! constructs a matrix for copy in initialization. //! An exception is raised if the matrixes have not the same dimensions. - Standard_EXPORT math_Matrix(const math_Matrix& Other); + inline math_Matrix(const math_Matrix& Other); + + //! Move constructor + inline math_Matrix(math_Matrix&& Other) noexcept; //! Initialize all the elements of a matrix to InitialValue. - Standard_EXPORT void Init(const Standard_Real InitialValue); + inline void Init(const Standard_Real InitialValue) noexcept; //! Returns the number of rows of this matrix. //! Note that for a matrix A you always have the following relations: @@ -122,7 +123,7 @@ public: //! - the length of a row of A is equal to the number of columns of A, //! - the length of a column of A is equal to the number of //! rows of A.returns the row range of a matrix. - Standard_Integer RowNumber() const; + Standard_Integer RowNumber() const noexcept; //! Returns the number of rows of this matrix. //! Note that for a matrix A you always have the following relations: @@ -131,23 +132,23 @@ public: //! - the length of a row of A is equal to the number of columns of A, //! - the length of a column of A is equal to the number of //! rows of A.returns the row range of a matrix. - Standard_Integer ColNumber() const; + Standard_Integer ColNumber() const noexcept; //! Returns the value of the Lower index of the row //! range of a matrix. - Standard_Integer LowerRow() const; + Standard_Integer LowerRow() const noexcept; //! Returns the Upper index of the row range //! of a matrix. - Standard_Integer UpperRow() const; + Standard_Integer UpperRow() const noexcept; //! Returns the value of the Lower index of the //! column range of a matrix. - Standard_Integer LowerCol() const; + Standard_Integer LowerCol() const noexcept; //! Returns the value of the upper index of the //! column range of a matrix. - Standard_Integer UpperCol() const; + Standard_Integer UpperCol() const noexcept; //! Computes the determinant of a matrix. //! An exception is raised if the matrix is not a square matrix. @@ -155,7 +156,7 @@ public: //! Transposes a given matrix. //! An exception is raised if the matrix is not a square matrix. - Standard_EXPORT void Transpose(); + inline void Transpose(); //! Inverts a matrix using Gauss algorithm. //! Exception NotSquare is raised if the matrix is not square. @@ -179,15 +180,15 @@ public: //! rows of this matrix, or //! - the number of columns of matrix Right is not equal to //! the number of columns of this matrix. - Standard_EXPORT void Multiply(const Standard_Real Right); + inline void Multiply(const Standard_Real Right) noexcept; - void operator*=(const Standard_Real Right) { Multiply(Right); } + void operator*=(const Standard_Real Right) noexcept { Multiply(Right); } //! multiplies all the elements of a matrix by the //! value . - Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied(const Standard_Real Right) const; + Standard_NODISCARD inline math_Matrix Multiplied(const Standard_Real Right) const noexcept; - Standard_NODISCARD math_Matrix operator*(const Standard_Real Right) const + Standard_NODISCARD math_Matrix operator*(const Standard_Real Right) const noexcept { return Multiplied(Right); } @@ -210,18 +211,18 @@ public: //! rows of this matrix, or //! - the number of columns of matrix Right is not equal to //! the number of columns of this matrix. - Standard_NODISCARD Standard_EXPORT math_Matrix TMultiplied(const Standard_Real Right) const; + Standard_NODISCARD inline math_Matrix TMultiplied(const Standard_Real Right) const noexcept; friend math_Matrix operator*(const Standard_Real Left, const math_Matrix& Right); //! divides all the elements of a matrix by the value . //! An exception is raised if = 0. - Standard_EXPORT void Divide(const Standard_Real Right); + inline void Divide(const Standard_Real Right); void operator/=(const Standard_Real Right) { Divide(Right); } //! divides all the elements of a matrix by the value . //! An exception is raised if = 0. - Standard_NODISCARD Standard_EXPORT math_Matrix Divided(const Standard_Real Right) const; + Standard_NODISCARD inline math_Matrix Divided(const Standard_Real Right) const; Standard_NODISCARD math_Matrix operator/(const Standard_Real Right) const { @@ -234,19 +235,19 @@ public: //! In order to save time when copying matrices, it is //! preferable to use operator += or the function Add //! whenever possible. - Standard_EXPORT void Add(const math_Matrix& Right); + inline void Add(const math_Matrix& Right); void operator+=(const math_Matrix& Right) { Add(Right); } //! adds the matrix to a matrix. //! An exception is raised if the dimensions are different. - Standard_NODISCARD Standard_EXPORT math_Matrix Added(const math_Matrix& Right) const; + Standard_NODISCARD inline math_Matrix Added(const math_Matrix& Right) const; Standard_NODISCARD math_Matrix operator+(const math_Matrix& Right) const { return Added(Right); } //! sets a matrix to the addition of and . //! An exception is raised if the dimensions are different. - Standard_EXPORT void Add(const math_Matrix& Left, const math_Matrix& Right); + inline void Add(const math_Matrix& Left, const math_Matrix& Right); //! Subtracts the matrix from . //! An exception is raised if the dimensions are different. @@ -254,13 +255,13 @@ public: //! In order to avoid time-consuming copying of matrices, it //! is preferable to use operator -= or the function //! Subtract whenever possible. - Standard_EXPORT void Subtract(const math_Matrix& Right); + inline void Subtract(const math_Matrix& Right); void operator-=(const math_Matrix& Right) { Subtract(Right); } //! Returns the result of the subtraction of from . //! An exception is raised if the dimensions are different. - Standard_NODISCARD Standard_EXPORT math_Matrix Subtracted(const math_Matrix& Right) const; + Standard_NODISCARD inline math_Matrix Subtracted(const math_Matrix& Right) const; Standard_NODISCARD math_Matrix operator-(const math_Matrix& Right) const { @@ -279,11 +280,11 @@ public: //! - J2 is greater than the index of the upper column bound of this matrix, or //! - I2 - I1 + 1 is not equal to the number of rows of matrix M, or //! - J2 - J1 + 1 is not equal to the number of columns of matrix M. - Standard_EXPORT void Set(const Standard_Integer I1, - const Standard_Integer I2, - const Standard_Integer J1, - const Standard_Integer J2, - const math_Matrix& M); + inline void Set(const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer J1, + const Standard_Integer J2, + const math_Matrix& M); //! Sets the row of index Row of a matrix to the vector . //! An exception is raised if the dimensions are different. @@ -300,7 +301,7 @@ public: //! Sets the diagonal of a matrix to the value . //! An exception is raised if the matrix is not square. - Standard_EXPORT void SetDiag(const Standard_Real Value); + inline void SetDiag(const Standard_Real Value); //! Returns the row of index Row of a matrix. Standard_EXPORT math_VectorBase<> Row(const Standard_Integer Row) const; @@ -318,7 +319,7 @@ public: //! Teturns the transposed of a matrix. //! An exception is raised if the matrix is not a square matrix. - Standard_NODISCARD Standard_EXPORT math_Matrix Transposed() const; + Standard_NODISCARD inline math_Matrix Transposed() const; //! Returns the inverse of a matrix. //! Exception NotSquare is raised if the matrix is not square. @@ -328,7 +329,7 @@ public: //! Returns the product of the transpose of a matrix with //! the matrix . //! An exception is raised if the dimensions are different. - Standard_EXPORT math_Matrix TMultiply(const math_Matrix& Right) const; + inline math_Matrix TMultiply(const math_Matrix& Right) const; //! Computes a matrix as the product of 2 vectors. //! An exception is raised if the dimensions are different. @@ -337,17 +338,17 @@ public: //! Computes a matrix as the product of 2 matrixes. //! An exception is raised if the dimensions are different. - Standard_EXPORT void Multiply(const math_Matrix& Left, const math_Matrix& Right); + inline void Multiply(const math_Matrix& Left, const math_Matrix& Right); //! Computes a matrix to the product of the transpose of //! the matrix with the matrix . //! An exception is raised if the dimensions are different. - Standard_EXPORT void TMultiply(const math_Matrix& TLeft, const math_Matrix& Right); + inline void TMultiply(const math_Matrix& TLeft, const math_Matrix& Right); //! Sets a matrix to the Subtraction of the matrix //! from the matrix . //! An exception is raised if the dimensions are different. - Standard_EXPORT void Subtract(const math_Matrix& Left, const math_Matrix& Right); + inline void Subtract(const math_Matrix& Left, const math_Matrix& Right); //! Accesses the value of index //! and of a matrix. @@ -373,19 +374,22 @@ public: //! Matrixes are copied through assignment. //! An exception is raised if the dimensions are different. - Standard_EXPORT math_Matrix& Initialized(const math_Matrix& Other); + inline math_Matrix& Initialized(const math_Matrix& Other); math_Matrix& operator=(const math_Matrix& Other) { return Initialized(Other); } + //! Move assignment operator + inline math_Matrix& operator=(math_Matrix&& Other) noexcept; + //! Returns the product of 2 matrices. //! An exception is raised if the dimensions are different. - Standard_EXPORT void Multiply(const math_Matrix& Right); + inline void Multiply(const math_Matrix& Right); void operator*=(const math_Matrix& Right) { Multiply(Right); } //! Returns the product of 2 matrices. //! An exception is raised if the dimensions are different. - Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied(const math_Matrix& Right) const; + Standard_NODISCARD inline math_Matrix Multiplied(const math_Matrix& Right) const; Standard_NODISCARD math_Matrix operator*(const math_Matrix& Right) const { @@ -401,33 +405,29 @@ public: //! Returns the opposite of a matrix. //! An exception is raised if the dimensions are different. - Standard_EXPORT math_Matrix Opposite(); + inline math_Matrix Opposite() const; - math_Matrix operator-() { return Opposite(); } + math_Matrix operator-() const { return Opposite(); } //! Prints information on the current state of the object. //! Is used to redefine the operator <<. - Standard_EXPORT void Dump(Standard_OStream& o) const; + inline void Dump(Standard_OStream& o) const; protected: //! The new lower row of the matrix is set to - Standard_EXPORT void SetLowerRow(const Standard_Integer LowerRow); + inline void SetLowerRow(const Standard_Integer LowerRow) noexcept; //! The new lower column of the matrix is set to the column //! of range . - Standard_EXPORT void SetLowerCol(const Standard_Integer LowerCol); + inline void SetLowerCol(const Standard_Integer LowerCol) noexcept; //! The new lower row of the matrix is set to //! and the new lower column of the matrix is set to the column //! of range . - void SetLower(const Standard_Integer LowerRow, const Standard_Integer LowerCol); + void SetLower(const Standard_Integer LowerRow, const Standard_Integer LowerCol) noexcept; private: - Standard_Integer LowerRowIndex; - Standard_Integer UpperRowIndex; - Standard_Integer LowerColIndex; - Standard_Integer UpperColIndex; - math_DoubleTab Array; + math_DoubleTab Array; }; #include diff --git a/src/FoundationClasses/TKMath/math/math_Matrix.lxx b/src/FoundationClasses/TKMath/math/math_Matrix.lxx index aa11c220a0..8d2539a13f 100644 --- a/src/FoundationClasses/TKMath/math/math_Matrix.lxx +++ b/src/FoundationClasses/TKMath/math/math_Matrix.lxx @@ -12,9 +12,11 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// lpa le 29/10/91 - +#include #include +#include + +//================================================================================================== inline Standard_OStream& operator<<(Standard_OStream& o, const math_Matrix& mat) { @@ -22,74 +24,739 @@ inline Standard_OStream& operator<<(Standard_OStream& o, const math_Matrix& mat) return o; } +//================================================================================================== + inline math_Matrix operator*(const Standard_Real Left, const math_Matrix& Right) { return Right.Multiplied(Left); } +//================================================================================================== + inline const Standard_Real& math_Matrix::Value(const Standard_Integer Row, const Standard_Integer Col) const { - Standard_RangeError_Raise_if(((Row < LowerRowIndex) || (Row > UpperRowIndex) - || (Col < LowerColIndex) || (Col > UpperColIndex)), - " "); - return Array.Value(Row, Col); } +//================================================================================================== + inline Standard_Real& math_Matrix::Value(const Standard_Integer Row, const Standard_Integer Col) { - Standard_RangeError_Raise_if(((Row < LowerRowIndex) || (Row > UpperRowIndex) - || (Col < LowerColIndex) || (Col > UpperColIndex)), - " "); - return Array.Value(Row, Col); } -inline Standard_Integer math_Matrix::RowNumber() const +//================================================================================================== + +inline Standard_Integer math_Matrix::RowNumber() const noexcept { - return UpperRowIndex - LowerRowIndex + 1; + return Array.NbRows(); } -// returns the row range of a matrix. +//================================================================================================== -inline Standard_Integer math_Matrix::ColNumber() const +inline Standard_Integer math_Matrix::ColNumber() const noexcept { - return UpperColIndex - LowerColIndex + 1; + return Array.NbColumns(); } -// returns the column range of a matrix. +//================================================================================================== -inline Standard_Integer math_Matrix::LowerRow() const +inline Standard_Integer math_Matrix::LowerRow() const noexcept { - return LowerRowIndex; + return Array.LowerRow(); } -// returns the value of the Lower index of the row range of a matrix. +//================================================================================================== -inline Standard_Integer math_Matrix::UpperRow() const +inline Standard_Integer math_Matrix::UpperRow() const noexcept { - return UpperRowIndex; + return Array.UpperRow(); } -// returns the value of the Upper index of the row range of a matrix. +//================================================================================================== -inline Standard_Integer math_Matrix::LowerCol() const +inline Standard_Integer math_Matrix::LowerCol() const noexcept { - return LowerColIndex; + return Array.LowerCol(); } -// returns the value of the Lower index of the column range of a matrix. +//================================================================================================== -inline Standard_Integer math_Matrix::UpperCol() const +inline Standard_Integer math_Matrix::UpperCol() const noexcept { - return UpperColIndex; + return Array.UpperCol(); } -// returns the value of the Upper index of the column range of a matrix. +//================================================================================================== -inline void math_Matrix::SetLower(const Standard_Integer LowerRow, const Standard_Integer LowerCol) +inline void math_Matrix::SetLower(const Standard_Integer LowerRow, + const Standard_Integer LowerCol) noexcept { SetLowerRow(LowerRow); SetLowerCol(LowerCol); } + +//================================================================================================== + +inline math_Matrix::math_Matrix(const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol) + : Array(LowerRow, UpperRow, LowerCol, UpperCol) +{ +} + +//================================================================================================== + +inline math_Matrix::math_Matrix(const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol, + const Standard_Real InitialValue) + : Array(LowerRow, UpperRow, LowerCol, UpperCol) +{ + Array.Init(InitialValue); +} + +//================================================================================================== + +inline math_Matrix::math_Matrix(const Standard_Address Tab, + const Standard_Integer LowerRow, + const Standard_Integer UpperRow, + const Standard_Integer LowerCol, + const Standard_Integer UpperCol) + : Array(Tab, LowerRow, UpperRow, LowerCol, UpperCol) +{ +} + +//================================================================================================== + +inline math_Matrix::math_Matrix(const math_Matrix& Other) + : Array(Other.Array) +{ +} + +//================================================================================================== + +inline math_Matrix::math_Matrix(math_Matrix&& Other) noexcept + : Array(std::move(Other.Array)) +{ +} + +//================================================================================================== + +inline void math_Matrix::Init(const Standard_Real InitialValue) noexcept +{ + Array.Init(InitialValue); +} + +//================================================================================================== + +inline void math_Matrix::SetLowerRow(const Standard_Integer LowerRow) noexcept +{ + Array.SetLowerRow(LowerRow); +} + +//================================================================================================== + +inline void math_Matrix::SetLowerCol(const Standard_Integer LowerCol) noexcept +{ + Array.SetLowerCol(LowerCol); +} + +//================================================================================================== + +inline void math_Matrix::Multiply(const Standard_Real Right) noexcept +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Array(I, J) * Right; + } + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Multiplied(const Standard_Real Right) const noexcept +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, aLowerCol, anUpperCol); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(I, J) = Array(I, J) * Right; + } + } + return Result; +} + +//================================================================================================== + +inline math_Matrix math_Matrix::TMultiplied(const Standard_Real Right) const noexcept +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, aLowerCol, anUpperCol); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(I, J) = Array(I, J) * Right; + } + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::Divide(const Standard_Real Right) +{ + Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), + "math_Matrix::Divide() - zero divisor"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Array(I, J) / Right; + } + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Divided(const Standard_Real Right) const +{ + Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), + "math_Matrix::Divided() - zero divisor"); + math_Matrix temp = Multiplied(1. / Right); + return temp; +} + +//================================================================================================== + +inline void math_Matrix::Add(const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) + || (ColNumber() != Right.ColNumber()), + "math_Matrix::Add() - input matrix has different dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Array(I, J) + Right.Array(I2, J2); + J2++; + } + I2++; + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Added(const math_Matrix& Right) const +{ + Standard_DimensionError_Raise_if((RowNumber() != Right.RowNumber()) + || (ColNumber() != Right.ColNumber()), + "math_Matrix::Added() - input matrix has different dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, aLowerCol, anUpperCol); + + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(I, J) = Array(I, J) + Right.Array(I2, J2); + J2++; + } + I2++; + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::Add(const math_Matrix& Left, const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()) + || (Right.RowNumber() != Left.RowNumber()) || (Right.ColNumber() != Left.ColNumber()), + "math_Matrix::Add() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Integer I1 = Left.LowerRow(); + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J1 = Left.LowerCol(); + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Left.Array(I1, J1) + Right.Array(I2, J2); + J1++; + J2++; + } + I1++; + I2++; + } +} + +//================================================================================================== + +inline void math_Matrix::Subtract(const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()), + "math_Matrix::Subtract() - input matrix has different dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Array(I, J) - Right.Array(I2, J2); + J2++; + } + I2++; + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Subtracted(const math_Matrix& Right) const +{ + Standard_DimensionError_Raise_if( + (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()), + "math_Matrix::Subtracted() - input matrix has different dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, aLowerCol, anUpperCol); + + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(I, J) = Array(I, J) - Right.Array(I2, J2); + J2++; + } + I2++; + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::Subtract(const math_Matrix& Left, const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + (RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()) + || (Right.RowNumber() != Left.RowNumber()) || (Right.ColNumber() != Left.ColNumber()), + "math_Matrix::Subtract() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Integer I1 = Left.LowerRow(); + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J1 = Left.LowerCol(); + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Array(I, J) = Left.Array(I1, J1) - Right.Array(I2, J2); + J1++; + J2++; + } + I1++; + I2++; + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Opposite() const +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, aLowerCol, anUpperCol); + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(I, J) = -Array(I, J); + } + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::Set(const Standard_Integer I1, + const Standard_Integer I2, + const Standard_Integer J1, + const Standard_Integer J2, + const math_Matrix& M) +{ + Standard_DimensionError_Raise_if((I1 > I2) || (J1 > J2) || (I2 - I1 + 1 != M.RowNumber()) + || (J2 - J1 + 1 != M.ColNumber()), + "math_Matrix::Set() - invalid indices"); + + Standard_Integer II = M.LowerRow(); + for (Standard_Integer I = I1; I <= I2; I++) + { + Standard_Integer JJ = M.LowerCol(); + for (Standard_Integer J = J1; J <= J2; J++) + { + Array(I, J) = M.Array(II, JJ); + JJ++; + } + II++; + } +} + +//================================================================================================== + +inline void math_Matrix::SetDiag(const Standard_Real Value) +{ + math_NotSquare_Raise_if(RowNumber() != ColNumber(), + "math_Matrix::SetDiag() - matrix is not square"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Array(I, I) = Value; + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Transposed() const +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerCol, anUpperCol, aLowerRow, anUpperRow); + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Result.Array(J, I) = Array(I, J); + } + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::Multiply(const math_Matrix& Left, const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + (Left.ColNumber() != Right.RowNumber()) || (RowNumber() != Left.RowNumber()) + || (ColNumber() != Right.ColNumber()), + "math_Matrix::Multiply() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Real Som; + Standard_Integer I1 = Left.LowerRow(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Som = 0.0; + Standard_Integer J1 = Left.LowerCol(); + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer K = Left.LowerCol(); K <= Left.UpperCol(); K++) + { + Som = Som + Left.Array(I1, J1) * Right.Array(I2, J2); + J1++; + I2++; + } + Array(I, J) = Som; + J2++; + } + I1++; + } +} + +//================================================================================================== + +inline void math_Matrix::Multiply(const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + ColNumber() != Right.RowNumber(), + "math_Matrix::Multiply() - input matrix has incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + // Create a temporary copy to avoid corrupting our own data during calculation + math_Matrix aTemp = *this; + if (this == &Right) + { + Multiply(aTemp, aTemp); + return; + } + + Standard_Real Som; + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J2 = Right.LowerCol(); J2 <= Right.UpperCol(); J2++) + { + Som = 0.0; + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Som += aTemp.Array(I, J) * Right.Array(I2, J2); + I2++; + } + Array(I, J2) = Som; + } + } +} + +//================================================================================================== + +inline math_Matrix math_Matrix::Multiplied(const math_Matrix& Right) const +{ + Standard_DimensionError_Raise_if( + ColNumber() != Right.RowNumber(), + "math_Matrix::Multiplied() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerRow, anUpperRow, Right.LowerCol(), Right.UpperCol()); + + Standard_Real Som; + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J2 = Right.LowerCol(); J2 <= Right.UpperCol(); J2++) + { + Som = 0.0; + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Som = Som + Array(I, J) * Right.Array(I2, J2); + I2++; + } + Result.Array(I, J2) = Som; + } + } + return Result; +} + +//================================================================================================== + +inline math_Matrix math_Matrix::TMultiply(const math_Matrix& Right) const +{ + Standard_DimensionError_Raise_if( + RowNumber() != Right.RowNumber(), + "math_Matrix::TMultiply() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + math_Matrix Result(aLowerCol, anUpperCol, Right.LowerCol(), Right.UpperCol()); + + Standard_Real Som; + for (Standard_Integer I = aLowerCol; I <= anUpperCol; I++) + { + for (Standard_Integer J2 = Right.LowerCol(); J2 <= Right.UpperCol(); J2++) + { + Som = 0.0; + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer J = aLowerRow; J <= anUpperRow; J++) + { + Som = Som + Array(J, I) * Right.Array(I2, J2); + I2++; + } + Result.Array(I, J2) = Som; + } + } + return Result; +} + +//================================================================================================== + +inline void math_Matrix::TMultiply(const math_Matrix& TLeft, const math_Matrix& Right) +{ + Standard_DimensionError_Raise_if( + (TLeft.RowNumber() != Right.RowNumber()) || (RowNumber() != TLeft.ColNumber()) + || (ColNumber() != Right.ColNumber()), + "math_Matrix::TMultiply() - matrices have incompatible dimensions"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Real Som; + Standard_Integer I1 = TLeft.LowerCol(); + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + Standard_Integer J2 = Right.LowerCol(); + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + Som = 0.0; + Standard_Integer J1 = TLeft.LowerRow(); + Standard_Integer I2 = Right.LowerRow(); + for (Standard_Integer K = TLeft.LowerRow(); K <= TLeft.UpperRow(); K++) + { + Som = Som + TLeft.Array(J1, I1) * Right.Array(I2, J2); + J1++; + I2++; + } + Array(I, J) = Som; + J2++; + } + I1++; + } +} + +//================================================================================================== + +inline math_Matrix& math_Matrix::Initialized(const math_Matrix& Other) +{ + Standard_DimensionError_Raise_if( + (RowNumber() != Other.RowNumber()) || (ColNumber() != Other.ColNumber()), + "math_Matrix::Initialized() - input matrix has different dimensions"); + + (Other.Array).Copy(Array); + return *this; +} + +//================================================================================================== + +inline math_Matrix& math_Matrix::operator=(math_Matrix&& Other) noexcept +{ + if (this != &Other) + { + Array = std::move(Other.Array); + } + return *this; +} + +//================================================================================================== + +inline void math_Matrix::Transpose() +{ + math_NotSquare_Raise_if(RowNumber() != ColNumber(), + "math_Matrix::Transpose() - matrix is not square"); + + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + Standard_Integer Row = aLowerRow; + Standard_Integer Col = aLowerCol; + SetLowerCol(aLowerRow); + Standard_Real Temp; + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = I; J <= anUpperCol; J++) + { + Temp = Array(I, J); + Array(I, J) = Array(J, I); + Array(J, I) = Temp; + } + } + SetLowerRow(Col); + SetLowerCol(Row); +} + +//================================================================================================== + +inline void math_Matrix::Dump(Standard_OStream& o) const +{ + const Standard_Integer aLowerRow = Array.LowerRow(); + const Standard_Integer anUpperRow = Array.UpperRow(); + const Standard_Integer aLowerCol = Array.LowerCol(); + const Standard_Integer anUpperCol = Array.UpperCol(); + + o << "math_Matrix of RowNumber = " << RowNumber(); + o << " and ColNumber = " << ColNumber() << "\n"; + + for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++) + { + for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++) + { + o << "math_Matrix ( " << I << ", " << J << " ) = "; + o << Array(I, J) << "\n"; + } + } +} diff --git a/src/FoundationClasses/TKMath/math/math_VectorBase.lxx b/src/FoundationClasses/TKMath/math/math_VectorBase.lxx index 1b06c37127..2a652cfbeb 100644 --- a/src/FoundationClasses/TKMath/math/math_VectorBase.lxx +++ b/src/FoundationClasses/TKMath/math/math_VectorBase.lxx @@ -388,13 +388,13 @@ void math_VectorBase::Multiply(const math_Matrix& "math_VectorBase::Multiply() - input matrix and /or vector have wrong dimensions"); Standard_Integer Index = Lower(); - for (Standard_Integer I = theLeft.LowerRowIndex; I <= theLeft.UpperRowIndex; I++) + for (Standard_Integer I = theLeft.LowerRow(); I <= theLeft.UpperRow(); I++) { Array(Index) = 0.0; Standard_Integer K = theRight.Lower(); - for (Standard_Integer J = theLeft.LowerColIndex; J <= theLeft.UpperColIndex; J++) + for (Standard_Integer J = theLeft.LowerCol(); J <= theLeft.UpperCol(); J++) { - Array(Index) = Array(Index) + theLeft.Array(I, J) * theRight.Array(K); + Array(Index) = Array(Index) + theLeft(I, J) * theRight.Array(K); K++; } Index++; @@ -410,13 +410,13 @@ void math_VectorBase::Multiply(const math_VectorBase& "math_VectorBase::Multiply() - input matrix and /or vector have wrong dimensions"); Standard_Integer Index = Lower(); - for (Standard_Integer J = theRight.LowerColIndex; J <= theRight.UpperColIndex; J++) + for (Standard_Integer J = theRight.LowerCol(); J <= theRight.UpperCol(); J++) { Array(Index) = 0.0; Standard_Integer K = theLeft.Lower(); - for (Standard_Integer I = theRight.LowerRowIndex; I <= theRight.UpperRowIndex; I++) + for (Standard_Integer I = theRight.LowerRow(); I <= theRight.UpperRow(); I++) { - Array(Index) = Array(Index) + theLeft.Array(K) * theRight.Array(I, J); + Array(Index) = Array(Index) + theLeft.Array(K) * theRight(I, J); K++; } Index++; @@ -432,13 +432,13 @@ void math_VectorBase::TMultiply(const math_Matrix& "math_VectorBase::TMultiply() - input matrix and /or vector have wrong dimensions"); Standard_Integer Index = Lower(); - for (Standard_Integer I = theTLeft.LowerColIndex; I <= theTLeft.UpperColIndex; I++) + for (Standard_Integer I = theTLeft.LowerCol(); I <= theTLeft.UpperCol(); I++) { Array(Index) = 0.0; Standard_Integer K = theRight.Lower(); - for (Standard_Integer J = theTLeft.LowerRowIndex; J <= theTLeft.UpperRowIndex; J++) + for (Standard_Integer J = theTLeft.LowerRow(); J <= theTLeft.UpperRow(); J++) { - Array(Index) = Array(Index) + theTLeft.Array(J, I) * theRight.Array(K); + Array(Index) = Array(Index) + theTLeft(J, I) * theRight.Array(K); K++; } Index++; @@ -454,13 +454,13 @@ void math_VectorBase::TMultiply(const math_VectorBase& "math_VectorBase::TMultiply() - input matrix and /or vector have wrong dimensions"); Standard_Integer Index = Lower(); - for (Standard_Integer J = theTRight.LowerRowIndex; J <= theTRight.UpperRowIndex; J++) + for (Standard_Integer J = theTRight.LowerRow(); J <= theTRight.UpperRow(); J++) { Array(Index) = 0.0; Standard_Integer K = theLeft.Lower(); - for (Standard_Integer I = theTRight.LowerColIndex; I <= theTRight.UpperColIndex; I++) + for (Standard_Integer I = theTRight.LowerCol(); I <= theTRight.UpperCol(); I++) { - Array(Index) = Array(Index) + theLeft.Array(K) * theTRight.Array(J, I); + Array(Index) = Array(Index) + theLeft.Array(K) * theTRight(J, I); K++; } Index++; @@ -505,14 +505,14 @@ math_VectorBase math_VectorBase::Multiplied( Length() != theRight.RowNumber(), "math_VectorBase::Multiplied() - input matrix has wrong dimensions"); - math_VectorBase Result(theRight.LowerColIndex, theRight.UpperColIndex); - for (Standard_Integer J2 = theRight.LowerColIndex; J2 <= theRight.UpperColIndex; J2++) + math_VectorBase Result(theRight.LowerCol(), theRight.UpperCol()); + for (Standard_Integer J2 = theRight.LowerCol(); J2 <= theRight.UpperCol(); J2++) { Result.Array(J2) = 0.0; - Standard_Integer theI2 = theRight.LowerRowIndex; + Standard_Integer theI2 = theRight.LowerRow(); for (Standard_Integer I = Lower(); I <= Upper(); I++) { - Result.Array(J2) = Result.Array(J2) + Array(I) * theRight.Array(theI2, J2); + Result.Array(J2) = Result.Array(J2) + Array(I) * theRight(theI2, J2); theI2++; } }