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`)
This commit is contained in:
Pasukhin Dmitry
2025-11-09 15:27:10 +00:00
committed by GitHub
parent 27e61c089c
commit 989f00b9c4
5 changed files with 916 additions and 740 deletions

View File

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

View File

@@ -13,109 +13,159 @@
// commercial license or contractual agreement.
#include <math_Matrix.hxx>
#include <math_Vector.hxx>
#include <math_Gauss.hxx>
#include <math_IntegerVector.hxx>
#include <math_NotSquare.hxx>
#include <math_SingularMatrix.hxx>
#include <math_Vector.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_DivideByZero.hxx>
#include <Standard_RangeError.hxx>
void math_Matrix::SetLowerRow(const Standard_Integer LowerRow)
//==================================================================================================
void math_Matrix::SetRow(const Standard_Integer Row, const math_Vector& V)
{
Standard_DimensionError_Raise_if(ColNumber() != V.Length(),
"math_Matrix::SetRow() - input vector has wrong dimensions");
Array.SetLowerRow(LowerRow);
Standard_Integer Rows = RowNumber();
LowerRowIndex = LowerRow;
UpperRowIndex = LowerRowIndex + Rows - 1;
const Standard_Integer aLowerCol = Array.LowerCol();
const Standard_Integer anUpperCol = Array.UpperCol();
Standard_Integer I = V.Lower();
for (Standard_Integer Index = aLowerCol; Index <= anUpperCol; Index++)
{
Array(Row, Index) = V(I);
I++;
}
}
void math_Matrix::SetLowerCol(const Standard_Integer LowerCol)
{
//==================================================================================================
Array.SetLowerCol(LowerCol);
Standard_Integer Cols = ColNumber();
LowerColIndex = LowerCol;
UpperColIndex = LowerColIndex + Cols - 1;
void math_Matrix::SetCol(const Standard_Integer Col, const math_Vector& V)
{
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 = aLowerRow; Index <= anUpperRow; Index++)
{
Array(Index, Col) = V(I);
I++;
}
}
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)
math_Vector math_Matrix::Row(const Standard_Integer Row) const
{
Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol),
"math_Matrix() - invalid dimensions");
const Standard_Integer aLowerCol = Array.LowerCol();
const Standard_Integer anUpperCol = Array.UpperCol();
math_Vector Result(aLowerCol, anUpperCol);
for (Standard_Integer Index = aLowerCol; Index <= anUpperCol; Index++)
{
Result(Index) = Array(Row, Index);
}
return Result;
}
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)
math_Vector math_Matrix::Col(const Standard_Integer Col) const
{
Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol),
"math_Matrix() - invalid dimensions");
Array.Init(InitialValue);
const Standard_Integer aLowerRow = Array.LowerRow();
const Standard_Integer anUpperRow = Array.UpperRow();
math_Vector Result(aLowerRow, anUpperRow);
for (Standard_Integer Index = aLowerRow; Index <= anUpperRow; Index++)
{
Result(Index) = Array(Index, Col);
}
return Result;
}
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)
void math_Matrix::SwapRow(const Standard_Integer Row1, const Standard_Integer Row2)
{
Standard_RangeError_Raise_if((LowerRow > UpperRow) || (LowerCol > UpperCol),
"math_Matrix() - invalid dimensions");
math_Vector V1 = Row(Row1);
math_Vector V2 = Row(Row2);
SetRow(Row1, V2);
SetRow(Row2, V1);
}
void math_Matrix::Init(const Standard_Real InitialValue)
//==================================================================================================
void math_Matrix::SwapCol(const Standard_Integer Col1, const Standard_Integer Col2)
{
Array.Init(InitialValue);
math_Vector V1 = Col(Col1);
math_Vector V2 = Col(Col2);
SetCol(Col1, V2);
SetCol(Col2, V1);
}
math_Matrix::math_Matrix(const math_Matrix& Other)
:
//==================================================================================================
LowerRowIndex(Other.LowerRow()),
UpperRowIndex(Other.UpperRow()),
LowerColIndex(Other.LowerCol()),
UpperColIndex(Other.UpperCol()),
Array(Other.Array)
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");
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) = Left(I) * Right(J);
}
}
}
math_Matrix math_Matrix::Divided(const Standard_Real Right) const
//==================================================================================================
math_Vector math_Matrix::Multiplied(const math_Vector& Right) const
{
Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(),
"math_Matrix::Divided() - zero divisor");
math_Matrix temp = Multiplied(1. / Right);
return temp;
Standard_DimensionError_Raise_if(
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_Vector Result(aLowerRow, anUpperRow);
for (Standard_Integer I = aLowerRow; I <= anUpperRow; I++)
{
Result(I) = 0.0;
Standard_Integer II = Right.Lower();
for (Standard_Integer J = aLowerCol; J <= anUpperCol; J++)
{
Result(I) = Result(I) + Array(I, J) * Right(II);
II++;
}
}
return Result;
}
//==================================================================================================
math_Vector math_Matrix::operator*(const math_Vector& Right) const
{
return Multiplied(Right);
}
//==================================================================================================
Standard_Real math_Matrix::Determinant() const
{
math_Gauss Sol(*this);
@@ -130,46 +180,12 @@ Standard_Real math_Matrix::Determinant() const
}
}
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_Matrix::Invert() - matrix is not square");
math_Gauss Sol(*this);
if (Sol.IsDone())
@@ -178,540 +194,15 @@ void math_Matrix::Invert()
}
else
{
throw math_SingularMatrix(); // SingularMatrix Exception;
throw math_SingularMatrix();
}
}
//==================================================================================================
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");
Standard_Integer I = V.Lower();
for (Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++)
{
Array(Row, Index) = V.Array(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");
Standard_Integer I = V.Lower();
for (Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++)
{
Array(Index, Col) = V.Array(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
{
math_Vector Result(LowerColIndex, UpperColIndex);
for (Standard_Integer Index = LowerColIndex; Index <= UpperColIndex; Index++)
{
Result.Array(Index) = Array(Row, Index);
}
return Result;
}
math_Vector math_Matrix::Col(const Standard_Integer Col) const
{
math_Vector Result(LowerRowIndex, UpperRowIndex);
for (Standard_Integer Index = LowerRowIndex; Index <= UpperRowIndex; Index++)
{
Result.Array(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
{
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");
math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex);
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++)
{
Result.Array(I, J) = Array(I, J) + Right.Array(I2, J2);
J2++;
}
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
{
Standard_DimensionError_Raise_if(
(RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber()),
"math_Matrix::Subtracted() - input matrix has different dimensions");
math_Matrix Result(LowerRowIndex, UpperRowIndex, LowerColIndex, UpperColIndex);
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++)
{
Result.Array(I, J) = Array(I, J) - Right.Array(I2, J2);
J2++;
}
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)
{
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++;
}
}
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_DimensionError_Raise_if(
(RowNumber() != Right.RowNumber()) || (ColNumber() != Right.ColNumber())
|| (Right.RowNumber() != Left.RowNumber()) || (Right.ColNumber() != Left.ColNumber()),
"math_Matrix::Add() - matrices have incompatible dimensions");
Standard_Integer I1 = Left.LowerRowIndex;
Standard_Integer I2 = Right.LowerRowIndex;
for (Standard_Integer I = LowerRowIndex; I <= UpperRowIndex; I++)
{
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++;
}
}
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++)
{
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++;
}
}
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;
}
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 += aTemp.Array(I, J) * Right.Array(I2, J2);
I2++;
}
Array(I, J2) = Som;
}
}
}
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++)
{
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++;
}
}
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
{
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";
}
}
}

View File

@@ -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 <Right>.
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 <Right>.
//! An exception is raised if <Right> = 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 <Right>.
//! An exception is raised if <Right> = 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 <Right> 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 <Left> and <Right>.
//! 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 <Right> from <me>.
//! 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 <Right> from <me>.
//! 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 <V>.
//! An exception is raised if the dimensions are different.
@@ -300,7 +301,7 @@ public:
//! Sets the diagonal of a matrix to the value <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 <Right>.
//! 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 <TLeft> with the matrix <Right>.
//! 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 <Right>
//! from the matrix <Left>.
//! 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 <Row>
//! and <Col> 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 <LowerRow>
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 <LowerCol>.
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 <LowerRow>
//! and the new lower column of the matrix is set to the column
//! of range <LowerCol>.
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 <math_Matrix.lxx>

View File

@@ -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 <math_NotSquare.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_DivideByZero.hxx>
//==================================================================================================
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";
}
}
}

View File

@@ -388,13 +388,13 @@ void math_VectorBase<TheItemType>::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<TheItemType>::Multiply(const math_VectorBase<TheItemType>&
"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<TheItemType>::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<TheItemType>::TMultiply(const math_VectorBase<TheItemType>&
"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<TheItemType> math_VectorBase<TheItemType>::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++;
}
}