0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / math / math_Matrix.hxx
1 // Created on: 1991-05-07
2 // Created by: Laurent PAINNOT
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef _math_Matrix_HeaderFile
18 #define _math_Matrix_HeaderFile
19
20 #include <Standard.hxx>
21 #include <Standard_DefineAlloc.hxx>
22 #include <Standard_Handle.hxx>
23
24 #include <Standard_Integer.hxx>
25 #include <math_DoubleTab.hxx>
26 #include <Standard_Real.hxx>
27 #include <Standard_Address.hxx>
28 #include <math_Vector.hxx>
29 #include <Standard_OStream.hxx>
30
31 // resolve name collisions with X11 headers
32 #ifdef Opposite
33   #undef Opposite
34 #endif
35
36 //! This class implements the real matrix abstract data type.
37 //! Matrixes can have an arbitrary range which must be defined
38 //! at the declaration and cannot be changed after this declaration
39 //! math_Matrix(-3,5,2,4); //a vector with range [-3..5, 2..4]
40 //! Matrix values may be initialized and
41 //! retrieved using indexes which must lie within the range
42 //! of definition of the matrix.
43 //! Matrix objects follow "value semantics", that is, they
44 //! cannot be shared and are copied through assignment
45 //! Matrices are copied through assignement:
46 //! math_Matrix M2(1, 9, 1, 3);
47 //! ...
48 //! M2 = M1;
49 //! M1(1) = 2.0;//the matrix M2 will not be modified.
50 //!
51 //! The exception RangeError is raised when trying to access
52 //! outside the range of a matrix :
53 //! M1(11, 1)=0.0// --> will raise RangeError.
54 //!
55 //! The exception DimensionError is raised when the dimensions of
56 //! two matrices or vectors are not compatible.
57 //! math_Matrix M3(1, 2, 1, 2);
58 //! M3 = M1;   // will raise DimensionError
59 //! M1.Add(M3) // --> will raise DimensionError.
60 //! A Matrix can be constructed with a a pointer to "c array".
61 //! It allows to carry the bounds inside the matrix.
62 //! Exemple :
63 //! Standard_Real tab1[10][20];
64 //! Standard_Real tab2[200];
65 //!
66 //! math_Matrix A (tab1[0][0], 1, 10, 1, 20);
67 //! math_Matrix B (tab2[0],    1, 10, 1, 20);
68 class math_Matrix 
69 {
70 public:
71
72   DEFINE_STANDARD_ALLOC
73
74   
75   //! Constructs a non-initialized  matrix of range [LowerRow..UpperRow,
76   //! LowerCol..UpperCol]
77   //! For the constructed matrix:
78   //! -   LowerRow and UpperRow are the indexes of the
79   //! lower and upper bounds of a row, and
80   //! -   LowerCol and UpperCol are the indexes of the
81   //! lower and upper bounds of a column.
82   Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
83   
84   //! constructs a non-initialized matrix of range [LowerRow..UpperRow,
85   //! LowerCol..UpperCol]
86   //! whose values are all initialized with the value InitialValue.
87   Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol, const Standard_Real InitialValue);
88   
89   //! constructs a matrix of range [LowerRow..UpperRow,
90   //! LowerCol..UpperCol]
91   //! Sharing data with a "C array" pointed by Tab.
92   Standard_EXPORT math_Matrix(const Standard_Address Tab, const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
93   
94   //! constructs a matrix for copy in initialization.
95   //! An exception is raised if the matrixes have not the same dimensions.
96   Standard_EXPORT math_Matrix(const math_Matrix& Other);
97   
98   //! Initialize all the elements of a matrix to InitialValue.
99   Standard_EXPORT void Init (const Standard_Real InitialValue);
100   
101   //! Returns the number of rows  of this matrix.
102   //! Note that for a matrix A you always have the following relations:
103   //! - A.RowNumber() = A.UpperRow() -   A.LowerRow() + 1
104   //! - A.ColNumber() = A.UpperCol() -   A.LowerCol() + 1
105   //! - the length of a row of A is equal to the number of columns of A,
106   //! - the length of a column of A is equal to the number of
107   //! rows of A.returns the row range of a matrix.
108     Standard_Integer RowNumber() const;
109   
110   //! Returns the number of rows  of this matrix.
111   //! Note that for a matrix A you always have the following relations:
112   //! - A.RowNumber() = A.UpperRow() -   A.LowerRow() + 1
113   //! - A.ColNumber() = A.UpperCol() -   A.LowerCol() + 1
114   //! - the length of a row of A is equal to the number of columns of A,
115   //! - the length of a column of A is equal to the number of
116   //! rows of A.returns the row range of a matrix.
117     Standard_Integer ColNumber() const;
118   
119   //! Returns the value of the Lower index of the row
120   //! range of a matrix.
121     Standard_Integer LowerRow() const;
122   
123   //! Returns the Upper index of the row range
124   //! of a matrix.
125     Standard_Integer UpperRow() const;
126   
127   //! Returns the value of the Lower index of the
128   //! column range of a matrix.
129     Standard_Integer LowerCol() const;
130   
131   //! Returns the value of the upper index of the
132   //! column range of a matrix.
133     Standard_Integer UpperCol() const;
134   
135   //! Computes the determinant of a matrix.
136   //! An exception is raised if the matrix is not a square matrix.
137   Standard_EXPORT Standard_Real Determinant() const;
138   
139   //! Transposes a given matrix.
140   //! An exception is raised if the matrix is not a square matrix.
141   Standard_EXPORT void Transpose();
142   
143   //! Inverts a matrix using Gauss algorithm.
144   //! Exception NotSquare is raised if the matrix is not square.
145   //! Exception SingularMatrix is raised if the matrix is singular.
146   Standard_EXPORT void Invert();
147   
148   //! Sets this matrix to the product of the matrix Left, and the matrix Right.
149   //! Example
150   //! math_Matrix A (1, 3, 1, 3);
151   //! math_Matrix B (1, 3, 1, 3);
152   //! // A = ... , B = ...
153   //! math_Matrix C (1, 3, 1, 3);
154   //! C.Multiply(A, B);
155   //! Exceptions
156   //! Standard_DimensionError if matrices are of incompatible dimensions, i.e. if:
157   //! -   the number of columns of matrix Left, or the number of
158   //! rows of matrix TLeft is not equal to the number of rows
159   //! of matrix Right, or
160   //! -   the number of rows of matrix Left, or the number of
161   //! columns of matrix TLeft is not equal to the number of
162   //! rows of this matrix, or
163   //! -   the number of columns of matrix Right is not equal to
164   //! the number of columns of this matrix.
165   Standard_EXPORT void Multiply (const Standard_Real Right);
166 void operator*= (const Standard_Real Right)
167 {
168   Multiply(Right);
169 }
170   
171   //! multiplies all the elements of a matrix by the
172   //! value <Right>.
173   Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied (const Standard_Real Right) const;
174 Standard_NODISCARD math_Matrix operator* (const Standard_Real Right) const
175 {
176   return Multiplied(Right);
177 }
178   
179   //! Sets this matrix to the product of the
180   //! transposed matrix TLeft, and the matrix Right.
181   //! Example
182   //! math_Matrix A (1, 3, 1, 3);
183   //! math_Matrix B (1, 3, 1, 3);
184   //! // A = ... , B = ...
185   //! math_Matrix C (1, 3, 1, 3);
186   //! C.Multiply(A, B);
187   //! Exceptions
188   //! Standard_DimensionError if matrices are of incompatible dimensions, i.e. if:
189   //! -   the number of columns of matrix Left, or the number of
190   //! rows of matrix TLeft is not equal to the number of rows
191   //! of matrix Right, or
192   //! -   the number of rows of matrix Left, or the number of
193   //! columns of matrix TLeft is not equal to the number of
194   //! rows of this matrix, or
195   //! -   the number of columns of matrix Right is not equal to
196   //! the number of columns of this matrix.
197   Standard_NODISCARD Standard_EXPORT math_Matrix TMultiplied (const Standard_Real Right) const;
198 friend math_Matrix  operator *(const Standard_Real Left,const math_Matrix& Right);
199   
200   //! divides all the elements of a matrix by the value <Right>.
201   //! An exception is raised if <Right> = 0.
202   Standard_EXPORT void Divide (const Standard_Real Right);
203 void operator/= (const Standard_Real Right)
204 {
205   Divide(Right);
206 }
207   
208   //! divides all the elements of a matrix by the value <Right>.
209   //! An exception is raised if <Right> = 0.
210   Standard_NODISCARD Standard_EXPORT math_Matrix Divided (const Standard_Real Right) const;
211 Standard_NODISCARD math_Matrix operator/ (const Standard_Real Right) const
212 {
213   return Divided(Right);
214 }
215   
216   //! adds the matrix <Right> to a matrix.
217   //! An exception is raised if the dimensions are different.
218   //! Warning
219   //! In order to save time when copying matrices, it is
220   //! preferable to use operator += or the function Add
221   //! whenever possible.
222   Standard_EXPORT void Add (const math_Matrix& Right);
223 void operator+= (const math_Matrix& Right)
224 {
225   Add(Right);
226 }
227   
228   //! adds the matrix <Right> to a matrix.
229   //! An exception is raised if the dimensions are different.
230   Standard_NODISCARD Standard_EXPORT math_Matrix Added (const math_Matrix& Right) const;
231 Standard_NODISCARD math_Matrix operator+ (const math_Matrix& Right) const
232 {
233   return Added(Right);
234 }
235   
236   //! sets a  matrix to the addition of <Left> and <Right>.
237   //! An exception is raised if the dimensions are different.
238   Standard_EXPORT void Add (const math_Matrix& Left, const math_Matrix& Right);
239   
240   //! Subtracts the matrix <Right> from <me>.
241   //! An exception is raised if the dimensions are different.
242   //! Warning
243   //! In order to avoid time-consuming copying of matrices, it
244   //! is preferable to use operator -= or the function
245   //! Subtract whenever possible.
246   Standard_EXPORT void Subtract (const math_Matrix& Right);
247 void operator-= (const math_Matrix& Right)
248 {
249   Subtract(Right);
250 }
251   
252   //! Returns the result of the subtraction of <Right> from <me>.
253   //! An exception is raised if the dimensions are different.
254   Standard_NODISCARD Standard_EXPORT math_Matrix Subtracted (const math_Matrix& Right) const;
255 Standard_NODISCARD math_Matrix operator- (const math_Matrix& Right) const
256 {
257   return Subtracted(Right);
258 }
259   
260   //! Sets the values of this matrix,
261   //! -   from index I1 to index I2 on the row dimension, and
262   //! -   from index J1 to index J2 on the column dimension,
263   //! to those of matrix M.
264   //! Exceptions
265   //! Standard_DimensionError if:
266   //! -   I1 is less than the index of the lower row bound of this matrix, or
267   //! -   I2 is greater than the index of the upper row bound of this matrix, or
268   //! -   J1 is less than the index of the lower column bound of this matrix, or
269   //! -   J2 is greater than the index of the upper column bound of this matrix, or
270   //! -   I2 - I1 + 1 is not equal to the number of rows of matrix M, or
271   //! -   J2 - J1 + 1 is not equal to the number of columns of matrix M.
272   Standard_EXPORT void Set (const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer J1, const Standard_Integer J2, const math_Matrix& M);
273   
274   //! Sets the row of index Row of a matrix to the vector <V>.
275   //! An exception is raised if the dimensions are different.
276   //! An exception is raises if <Row> is inferior to the lower
277   //! row of the matrix or <Row> is superior to the upper row.
278   Standard_EXPORT void SetRow (const Standard_Integer Row, const math_Vector& V);
279   
280   //! Sets the column of index Col of a matrix to the vector <V>.
281   //! An exception is raised if the dimensions are different.
282   //! An exception is raises if <Col> is inferior to the lower
283   //! column of the matrix or <Col> is superior to the upper
284   //! column.
285   Standard_EXPORT void SetCol (const Standard_Integer Col, const math_Vector& V);
286   
287   //! Sets the diagonal of a matrix to the value <Value>.
288   //! An exception is raised if the matrix is not square.
289   Standard_EXPORT void SetDiag (const Standard_Real Value);
290   
291   //! Returns the row of index Row of a matrix.
292   Standard_EXPORT math_Vector Row (const Standard_Integer Row) const;
293   
294   //! Returns the column of index <Col> of a matrix.
295   Standard_EXPORT math_Vector Col (const Standard_Integer Col) const;
296   
297   //! Swaps the rows of index Row1 and Row2.
298   //! An exception is raised if <Row1> or <Row2> is out of range.
299   Standard_EXPORT void SwapRow (const Standard_Integer Row1, const Standard_Integer Row2);
300   
301   //! Swaps the columns of index <Col1> and <Col2>.
302   //! An exception is raised if <Col1> or <Col2> is out of range.
303   Standard_EXPORT void SwapCol (const Standard_Integer Col1, const Standard_Integer Col2);
304   
305   //! Teturns the transposed of a matrix.
306   //! An exception is raised if the matrix is not a square matrix.
307   Standard_NODISCARD Standard_EXPORT math_Matrix Transposed() const;
308   
309   //! Returns the inverse of a matrix.
310   //! Exception NotSquare is raised if the matrix is not square.
311   //! Exception SingularMatrix is raised if the matrix is singular.
312   Standard_EXPORT math_Matrix Inverse() const;
313   
314   //! Returns the product of the transpose of a matrix with
315   //! the matrix <Right>.
316   //! An exception is raised if the dimensions are different.
317   Standard_EXPORT math_Matrix TMultiply (const math_Matrix& Right) const;
318   
319   //! Computes a matrix as the product of 2 vectors.
320   //! An exception is raised if the dimensions are different.
321   //! <me> = <Left> * <Right>.
322   Standard_EXPORT void Multiply (const math_Vector& Left, const math_Vector& Right);
323   
324   //! Computes a matrix as the product of 2 matrixes.
325   //! An exception is raised if the dimensions are different.
326   Standard_EXPORT void Multiply (const math_Matrix& Left, const math_Matrix& Right);
327   
328   //! Computes a matrix to the product of the transpose of
329   //! the matrix <TLeft> with the matrix <Right>.
330   //! An exception is raised if the dimensions are different.
331   Standard_EXPORT void TMultiply (const math_Matrix& TLeft, const math_Matrix& Right);
332   
333   //! Sets a matrix to the Subtraction of the matrix <Right>
334   //! from the matrix <Left>.
335   //! An exception is raised if the dimensions are different.
336   Standard_EXPORT void Subtract (const math_Matrix& Left, const math_Matrix& Right);
337   
338   //! Accesses (in read or write mode) the value of index <Row>
339   //! and <Col> of a matrix.
340   //! An exception is raised if <Row> and <Col> are not
341   //! in the correct range.
342     Standard_Real& Value (const Standard_Integer Row, const Standard_Integer Col) const;
343   Standard_Real& operator() (const Standard_Integer Row, const Standard_Integer Col) const
344 {
345   return Value(Row,Col);
346 }
347   
348   //! Matrixes are copied through assignement.
349   //! An exception is raised if the dimensions are differents.
350   Standard_EXPORT math_Matrix& Initialized (const math_Matrix& Other);
351 math_Matrix& operator= (const math_Matrix& Other)
352 {
353   return Initialized(Other);
354 }
355   
356   //! Returns the product of 2 matrices.
357   //! An exception is raised if the dimensions are different.
358   Standard_EXPORT void Multiply (const math_Matrix& Right);
359 void operator*= (const math_Matrix& Right)
360 {
361   Multiply(Right);
362 }
363   
364   //! Returns the product of 2 matrices.
365   //! An exception is raised if the dimensions are different.
366   Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied (const math_Matrix& Right) const;
367 Standard_NODISCARD math_Matrix operator* (const math_Matrix& Right) const
368 {
369   return Multiplied(Right);
370 }
371   
372   //! Returns the product of a matrix by a vector.
373   //! An exception is raised if the dimensions are different.
374   Standard_NODISCARD Standard_EXPORT math_Vector Multiplied (const math_Vector& Right) const;
375 Standard_NODISCARD math_Vector operator* (const math_Vector& Right) const
376 {
377   return Multiplied(Right);
378 }
379   
380   //! Returns the opposite of a matrix.
381   //! An exception is raised if the dimensions are different.
382   Standard_EXPORT math_Matrix Opposite();
383 math_Matrix operator-()
384 {
385   return Opposite();
386 }
387   
388   //! Prints information on the current state of the object.
389   //! Is used to redefine the operator <<.
390   Standard_EXPORT void Dump (Standard_OStream& o) const;
391
392
393 friend class math_Vector;
394
395
396 protected:
397
398   
399   //! The new lower row of the matrix is set to <LowerRow>
400   Standard_EXPORT void SetLowerRow (const Standard_Integer LowerRow);
401   
402   //! The new lower column of the matrix is set to the column
403   //! of range <LowerCol>.
404   Standard_EXPORT void SetLowerCol (const Standard_Integer LowerCol);
405   
406   //! The new lower row of the matrix is set to <LowerRow>
407   //! and the new lower column of the matrix is set to the column
408   //! of range <LowerCol>.
409     void SetLower (const Standard_Integer LowerRow, const Standard_Integer LowerCol);
410
411
412
413
414 private:
415
416
417
418   Standard_Integer LowerRowIndex;
419   Standard_Integer UpperRowIndex;
420   Standard_Integer LowerColIndex;
421   Standard_Integer UpperColIndex;
422   math_DoubleTab Array;
423
424
425 };
426
427
428 #include <math_Matrix.lxx>
429
430
431
432
433
434 #endif // _math_Matrix_HeaderFile