25template <
int W
idth,
int Height,
typename Element =
double>
193 template <
int SecondW
idth>
196 for (
int resultY = 0; resultY < Height; ++resultY){
197 for (
int resultX = 0; resultX < SecondWidth; ++resultX){
199 for (
int i = 0; i < Width; ++i){
200 sum += m_elements[i][resultY] * matrix.m_elements[resultX][i];
203 result.m_elements[resultX][resultY] = sum;
211 template <
int SecondW
idth>
309 template <
int SecondW
idth>
334 typedef Element Elements[Width][Height];
342template <
int W
idth,
int Height,
typename Element>
347 GetTransposed(retVal);
353template <
int W
idth,
int Height,
typename Element>
358 GetTransposed(retVal);
364template <
int W
idth,
int Height,
typename Element>
369 GetMultiplied(vector, retVal);
375template <
int W
idth,
int Height,
typename Element>
380 GetAdded(matrix, retVal);
386template <
int W
idth,
int Height,
typename Element>
391 GetSubstracted(matrix, retVal);
397template <
int W
idth,
int Height,
typename Element>
408template <
int W
idth,
int Height,
typename Element>
413 GetScaled(value, retVal);
419template <
int W
idth,
int Height,
typename Element>
422 GetAdded(matrix, *
this);
428template <
int W
idth,
int Height,
typename Element>
431 GetSubstracted(matrix, *
this);
437template <
int W
idth,
int Height,
typename Element>
440 GetScaled(value, *
this);
446template <
int W
idth,
int Height,
typename Element>
449 return matrix * value;
455template <
int W
idth,
int Height,
typename Element>
461template <
int W
idth,
int Height,
typename Element>
466 for (
int x = 0; x < Width; ++x){
467 for (
int y = 0; y < Height; ++y){
468 m_elements[x][y] = 0;
474 for (
int x = 0; x < Width; ++x){
475 for (
int y = 0; y < Height; ++y){
476 m_elements[x][y] = 1;
482 for (
int x = 0; x < Width; ++x){
483 for (
int y = 0; y < Height; ++y){
485 m_elements[x][y] = 1;
488 m_elements[x][y] = 0;
494 case MIM_UPPER_TRIANGLE:
495 for (
int x = 0; x < Width; ++x){
496 for (
int y = 0; y < Height; ++y){
498 m_elements[x][y] = 1;
501 m_elements[x][y] = 0;
507 case MIM_DOWNER_TRIANGLE:
508 for (
int x = 0; x < Width; ++x){
509 for (
int y = 0; y < Height; ++y){
511 m_elements[x][y] = 1;
514 m_elements[x][y] = 0;
523template <
int W
idth,
int Height,
typename Element>
526 for (
int x = 0; x < Width; ++x){
527 for (
int y = 0; y < Height; ++y){
528 m_elements[x][y] = matrix.m_elements[x][y];
536template <
int W
idth,
int Height,
typename Element>
539 for (
int x = 0; x < Width; ++x){
540 for (
int y = 0; y < Height; ++y){
541 m_elements[x][y] = 0;
547template <
int W
idth,
int Height,
typename Element>
554template <
int W
idth,
int Height,
typename Element>
561template <
int W
idth,
int Height,
typename Element>
568template <
int W
idth,
int Height,
typename Element>
575template <
int W
idth,
int Height,
typename Element>
584template <
int W
idth,
int Height,
typename Element>
587 return (sizes[0] == Width) && (sizes[1] == Height);
591template <
int W
idth,
int Height,
typename Element>
607template <
int W
idth,
int Height,
typename Element>
612 return (size == Width);
615 return (size == Height);
623template <
int W
idth,
int Height,
typename Element>
626 return m_elements[index[0]][index[1]];
630template <
int W
idth,
int Height,
typename Element>
633 return m_elements[x][y];
637template <
int W
idth,
int Height,
typename Element>
640 return m_elements[index[0]][index[1]];
644template <
int W
idth,
int Height,
typename Element>
647 return m_elements[x][y];
651template <
int W
idth,
int Height,
typename Element>
654 m_elements[index[0]][index[1]] = value;
658template <
int W
idth,
int Height,
typename Element>
661 m_elements[x][y] = value;
665template <
int W
idth,
int Height,
typename Element>
668 for (
int x = 0; x < Width; ++x){
669 for (
int y = 0; y < Height; ++y){
671 m_elements[x][y] = 0;
674 m_elements[x][y] = 1;
681template <
int W
idth,
int Height,
typename Element>
684 double retVal = m_elements[0][0];
686 for (
int x = 0; x < Width; ++x){
687 for (
int y = 0; y < Height; ++y){
688 double value = m_elements[x][y];
700template <
int W
idth,
int Height,
typename Element>
703 double retVal = m_elements[0][0];
705 for (
int x = 0; x < Width; ++x){
706 for (
int y = 0; y < Height; ++y){
707 double value = m_elements[x][y];
719template <
int W
idth,
int Height,
typename Element>
722 for (
int x = 0; x < Width; ++x){
723 for (
int y = 0; y < Height; ++y){
724 result.m_elements[x][y] = -m_elements[x][y];
730template <
int W
idth,
int Height,
typename Element>
733 for (
int x = 0; x < Width; ++x){
734 for (
int y = 0; y < Height; ++y){
735 result.m_elements[x][y] = m_elements[x][y] + matrix.m_elements[x][y];
741template <
int W
idth,
int Height,
typename Element>
744 for (
int x = 0; x < Width; ++x){
745 for (
int y = 0; y < Height; ++y){
746 result.m_elements[x][y] = m_elements[x][y] - matrix.m_elements[x][y];
752template <
int W
idth,
int Height,
typename Element>
755 for (
int resultY = 0; resultY < Height; ++resultY){
757 for (
int i = 0; i < Width; ++i){
758 sum += m_elements[i][resultY] * vector[i];
761 result[resultY] = sum;
766template <
int W
idth,
int Height,
typename Element>
769 for (
int x = 0; x < Width; ++x){
770 for (
int y = 0; y < Height; ++y){
771 result.m_elements[x][y] = m_elements[x][y] * value;
777template <
int W
idth,
int Height,
typename Element>
780 for (
int x = 0; x < Width; ++x){
781 for (
int y = 0; y < Height; ++y){
782 result.
SetAt(y, x, GetAt(x, y));
788template <
int W
idth,
int Height,
typename Element>
791 int commonSize = qMin(Width, Height);
794 for (
int i = 0; i < commonSize; ++i){
795 retVal += m_elements[i][i];
802template <
int W
idth,
int Height,
typename Element>
807 for (
int x = 0; x < Width; ++x){
808 for (
int y = 0; y < Height; ++y){
809 double value = m_elements[x][y];
810 retVal += double(value * value);
817template <
int W
idth,
int Height,
typename Element>
820 return qSqrt(GetFrobeniusNorm2());
824template <
int W
idth,
int Height,
typename Element>
827 if (Width != Height){
834 for (
int i = 0; i < maxIterations; ++i){
846 for (index[0] = 0; index[0] < Width; ++index[0]){
847 for (index[1] = 0; index[1] < Width; ++index[1]){
848 if (index[0] != index[1]){
849 double element = matrixR.
GetAt(index);
851 residue += element * element;
856 if (residue <= tolerance){
857 for (
int i = 0; i < Height; ++i){
858 diagonalD[i] = matrixR.
GetAt(i, i);
869template <
int W
idth,
int Height,
typename Element>
872 Q_ASSERT(columnIndex < Width);
873 Q_ASSERT(columnIndex >= 0);
875 for (
int y = 0; y < Height; ++y){
876 result[y] = m_elements[columnIndex][y];
881template <
int W
idth,
int Height,
typename Element>
884 Q_ASSERT(columnIndex < Width);
885 Q_ASSERT(columnIndex >= 0);
887 for (
int y = 0; y < Height; ++y){
888 m_elements[columnIndex][y] = columnVector[y];
893template <
int W
idth,
int Height,
typename Element>
896 Q_ASSERT(rowIndex < Height);
898 for (
int x = 0; x < Width; ++x){
899 result[x] = m_elements[x][rowIndex];
904template <
int W
idth,
int Height,
typename Element>
909 double minHhNorm)
const
911 if (&result !=
this){
915 int columnsCount = qMin(Height - 1, Width);
916 if ((maxColumns >= 0) && (maxColumns < columnsCount)){
917 columnsCount = maxColumns;
920 for (
int hhIndex = 0; hhIndex < columnsCount; ++hhIndex){
922 for (
istd::CIndex2d normIndex(hhIndex, hhIndex); normIndex[1] < Height; ++normIndex[1]){
923 double element = result.
GetAt(normIndex);
925 hhNorm2 += element * element;
928 if (hhNorm2 < minHhNorm){
934 double hhLength = (element0 >= 0)? qSqrt(hhNorm2): -qSqrt(hhNorm2);
936 double hhVector0 = element0 + hhLength;
937 double hhVectorNorm2 = hhNorm2 + hhVector0 * hhVector0 - element0 * element0;
941 for (matrixIndex[0] = hhIndex + 1; matrixIndex[0] < Width; ++matrixIndex[0]){
942 matrixIndex[1] = hhIndex;
943 double dotProduct = result[matrixIndex] * hhVector0;
944 for (matrixIndex[1]++; matrixIndex[1] < Height; ++matrixIndex[1]){
948 double reflexionFactor = 2 * dotProduct / hhVectorNorm2;
949 matrixIndex[1] = hhIndex;
950 result[matrixIndex] -= hhVector0 * reflexionFactor;
951 for (matrixIndex[1]++; matrixIndex[1] < Height; ++matrixIndex[1]){
957 if (matrixQPtr !=
NULL){
959 for (matrix2Index[0] = 0; matrix2Index[0] < Height; ++matrix2Index[0]){
960 matrix2Index[1] = hhIndex;
961 double dotProduct = matrixQPtr->
GetAt(matrix2Index) * hhVector0;
962 for (++matrix2Index[1]; matrix2Index[1] < Height; ++matrix2Index[1]){
963 dotProduct += matrixQPtr->
GetAt(matrix2Index) * result[
istd::CIndex2d(hhIndex, matrix2Index[1])];
966 double reflexionFactor = 2 * dotProduct / hhVectorNorm2;
967 matrix2Index[1] = hhIndex;
968 matrixQPtr->
GetAtRef(matrix2Index) -= hhVector0 * reflexionFactor;
969 for (matrix2Index[1]++; matrix2Index[1] < Height; ++matrix2Index[1]){
977 for (
int i = hhIndex + 1; i < Height; ++i){
986template <
int W
idth,
int Height,
typename Element>
994 retVal = retVal && archive.
BeginTag(sizeTag);
999 retVal = retVal && archive.
Process(width);
1000 retVal = retVal && archive.
Process(height);
1006 retVal = retVal && archive.
Process(width);
1007 retVal = retVal && archive.
Process(height);
1009 if (!retVal || (width != Width) || (height != Height)){
1014 retVal = retVal && archive.
EndTag(sizeTag);
1016 retVal = retVal && archive.
BeginTag(cellsTag);
1017 for (
int y = 0; y < Height; ++y){
1018 for (
int x = 0; x < Width; ++x){
1019 retVal = retVal && archive.
Process(m_elements[x][y]);
1022 retVal = retVal && archive.
EndTag(cellsTag);
1028template <
int W
idth,
int Height,
typename Element>
1031 for (
int x = 0; x < Width; ++x){
1032 for (
int y = 0; y < Height; ++y){
1033 if (m_elements[x][y] != matrix.m_elements[x][y]){
1043template <
int W
idth,
int Height,
typename Element>
1046 for (
int x = 0; x < Width; ++x){
1047 for (
int y = 0; y < Height; ++y){
1048 if (m_elements[x][y] != matrix.m_elements[x][y]){
1058template <
int W
idth,
int Height,
typename Element>
1061 return m_elements[index[0]][index[1]];
1065template <
int W
idth,
int Height,
typename Element>
1068 return m_elements[index[0]][index[1]];
Definition of mathematical matrix with fixed dimensions.
TVector< Height, Element > GetMultiplied(const TVector< Width, Element > &vector) const
Get result of multiplication of this matrix and some vector.
bool operator==(const TMatrix< Width, Height, Element > &matrix) const
TMatrix< Height, Width, Element > GetTransposed() const
Get transposed matrix.
void GetAdded(const TMatrix< Width, Height, Element > &matrix, TMatrix< Width, Height, Element > &result) const
Get sum of two matrices.
double GetTrace() const
Get trace of this matrix.
void GetMultiplied(const TMatrix< SecondWidth, Width, Element > &matrix, TMatrix< SecondWidth, Height, Element > &result) const
Get result of multiplication of two matrices.
TMatrix< Width, Height, Element > & operator-=(const TMatrix< Width, Height, Element > &matrix)
TMatrix(const TMatrix &matrix)
Copy constructor.
TMatrix(MatrixInitMode mode)
Create matrix with initialization to some specified one.
int GetDimensionsCount() const
Get number of dimensions of this array.
void GetNegated(TMatrix< Width, Height, Element > &result)
Get result matrix with negated all elements.
bool SetSizes(const SizesType &sizes)
Set list of all sizes.
TMatrix< Width, Height, Element > & operator=(const TMatrix< Width, Height, Element > &matrix)=default
const SizesType & GetSizes() const
Get list of all sizes.
const ElementType & GetAt(int x, int y) const
Get element stored at specified index.
TMatrix< SecondWidth, Height, Element > operator*(const TMatrix< SecondWidth, Width, Element > &matrix) const
TMatrix< Width, Height, Element > operator-(const TMatrix< Width, Height, Element > &matrix) const
double GetFrobeniusNorm2() const
void GetMultiplied(const TVector< Width, Element > &vector, TVector< Height, Element > &result) const
Get result of multiplication of this matrix and some vector.
bool SetSize(int dimension, int size)
Set size of array for specified dimension.
@ MIM_ZERO
All elements initialized to 0.
@ MIM_ONES
All elements initialized to 1.
@ MIM_IDENTITY
Identity matrix.
@ MIM_DOWNER_TRIANGLE
Downer triangle matrix.
@ MIM_UPPER_TRIANGLE
Upper triangle matrix.
double GetFrobeniusNorm() const
void Transpose()
Transpose matrix.
void GetScaled(double value, TMatrix< Width, Height, Element > &result) const
Get result of multiplication of this matrix with scalar value.
void SetAt(int x, int y, const ElementType &value)
Set element at specified index.
void GetRowVector(int rowIndex, TVector< Width, Element > &result)
Get single row as vector.
void InitToIdentity()
Create identity matrix.
ElementType & operator[](const IndexType &index)
TMatrix< Width, Height, Element > & operator*=(double value)
int GetSize(int dimension) const
Get size of array for specified dimension.
TMatrix()
Create matrix without initialization.
TMatrix< Width, Height, Element > & operator+=(const TMatrix< Width, Height, Element > &matrix)
ElementType & GetAtRef(int x, int y)
Get reference to element stored at specified index.
bool GetDecompositionQDQ(TMatrix< Height, Height, Element > &matrixQ, TVector< Height, Element > &diagonalD, double tolerance=I_BIG_EPSILON, int maxIterations=100) const
Calculate decomposition in form of QDQ where Q is orthogonal matrix and D is diagonal one.
bool GetTriangleDecomposed(TMatrix< Width, Height, Element > &result, TMatrix< Height, Height, Element > *matrixQPtr=NULL, int maxColumns=-1, double minHhNorm=I_BIG_EPSILON) const
Transform matrix to upper triangle form using method of Householder reflexions.
TMatrix< Width, Height, Element > operator*(double value) const
double GetMinElement() const
imath::TVector< Width, Element > RowVector
void GetColumnVector(int columnIndex, TVector< Height, Element > &result) const
Get single column as vector.
TMatrix< SecondWidth, Height, Element > GetMultiplied(const TMatrix< SecondWidth, Width, Element > &matrix) const
Get result of multiplication of two matrices.
ElementType & GetAtRef(const IndexType &index)
Get reference to element stored at specified index.
void SetAt(const IndexType &index, const ElementType &value)
Set element at specified index.
void Reset()
Set all matrix cells to zero.
const ElementType & GetAt(const IndexType &index) const
Get element stored at specified index.
void SetColumnVector(int columnIndex, const TVector< Height, Element > &columnVector)
Set a single column vector to matrix.
bool SetDimensionsCount(int count)
Set number of dimensions of this array.
TMatrix< Width, Height, Element > operator-()
bool Serialize(iser::IArchive &archive)
void GetTransposed(TMatrix< Height, Width, Element > &result) const
Get transposed matrix.
void GetSubstracted(const TMatrix< Width, Height, Element > &matrix, TMatrix< Width, Height, Element > &result) const
Get result of substraction of two matrices.
double GetMaxElement() const
TMatrix< Width, Height, Element > operator+(const TMatrix< Width, Height, Element > &matrix) const
bool operator!=(const TMatrix< Width, Height, Element > &matrix) const
imath::TVector< Height, Element > ColumnVector
void Clear()
Set all matrix cells to zero.
bool IsDimensionsCountFixed() const
Check, if number dimensions is fixed.
const ElementType & operator[](const IndexType &index) const
Implementation of fixed-size mathematical vector with specified type of elements.
Process tag used to group data in archive stream.
@ TT_GROUP
Normal tag used for grouping of tags or processed elements.
Represents an input/output persistence archive for object serialization.
virtual bool Process(bool &value)=0
Processes (reads or writes) a boolean value.
virtual bool EndTag(const CArchiveTag &tag)=0
Ends a tagged section in the archive.
virtual bool IsStoring() const =0
Checks if this archive is in storing (writing) or loading (reading) mode.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begins a tagged section in the archive.
Index implementation for addressing elements in 2D-space.
static const double I_BIG_EPSILON
Package with mathematical functions and algebraical primitives.
CVarMatrix operator*(double value, const imath::CVarMatrix &matrix)
Contains general persistence mechanism with basic archives implementations.