1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 /*! \file SimpleMatrix.hpp
20  */
21 
22 #ifndef __SimpleMatrix__
23 #define __SimpleMatrix__
24 
25 #include <iosfwd>                     // for ostream
26 #include "SiconosSerialization.hpp" // For ACCEPT_SERIALIZATION
27 #include "SiconosVisitor.hpp" // for ACCEPT_STD_VISITORS
28 #include "SiconosAlgebraTypeDef.hpp"  // for DENSE, DenseMat, Index, BandedMat
29 #include "SiconosFwd.hpp"             // for SiconosVector, SiconosMatrix
30 #include "SiconosMatrix.hpp"          // for SiconosMatrix, VInt, MATRIX_UBL...
31 #include "SiconosVector.hpp"          // for SiconosVector
32 
33 
34 
35 
36 
37 
38 class BlockVector;
39 
40 /**  Matrix (embedded various types of Boost matrices of double)
41  *
42  * SimpleMatrix is used in the platform to store matrices (mathematical object) of double.
43  *
44  * Possible types: Siconos::DENSE (default),
45  *                          TRIANGULAR, SYMMETRIC, SPARSE, BANDED, ZERO,
46  *                          Siconos::IDENTITY,
47  *                          Siconos::SPARSE_COORDINATE.
48  *
49  * \todo: review resize function for Banded, Symetric and Triangular. Error in tests.
50 
51 \rst
52 
53 See :ref:`siconos_algebra` in :ref:`siconos_users_guide`.
54 
55 \endrst
56 
57  */
58 class SimpleMatrix: public SiconosMatrix
59 {
60 protected:
61   /** serialization hooks
62   */
63   ACCEPT_SERIALIZATION(SimpleMatrix);
64 
65   /** Union of The Boost Matrices : DenseMat, TriangMat, SymMat ...
66       (See SiconosMatrix.h for more details on MATRIX_UBLAS_TYPE);
67   */
68   MATRIX_UBLAS_TYPE mat;
69 
70 
71 private:
72   /** VInt _ipiv;
73    * The pivot indices obtained from DGETRF (PLUFactorizationInPlace)
74    */
75   SP::VInt _ipiv;
76 
77   /** True if the Matrix is PLU Factorized. */
78   bool _isPLUFactorized = false;
79 
80   /** True if the Matrix is PLU Factorized in place.*/
81   bool _isPLUFactorizedInPlace = false;
82 
83   /** True if the Matrix is Cholesky Factorized. */
84   bool _isCholeskyFactorized = false;
85 
86   /** True if the Matrix is Cholesky Factorized in place. */
87   bool _isCholeskyFactorizedInPlace = false;
88 
89   /** True if the Matrix has been QR Factorized in place. */
90   bool _isQRFactorized = false;
91 
92   /** True if the Matrix has been Inversed in Place. */
93   bool _isPLUInversed = false;
94 
95   /** Numerics Matrix structure
96    * This matrix is used to perform  computation using Numerics,
97    * for instance, the LU factorization of a sparse matrix.
98    * It may contains copy or pointer on the SimpleMatrix.
99    */
100   SP::NumericsMatrix _numericsMatrix;
101 
102 
103   /**  computes res = subA*x +res, subA being a submatrix of A (rows from startRow to startRow+sizeY and columns between startCol and startCol+sizeX).
104    * If x is a block vector, it call the present function for all blocks.
105    * \param A a pointer to SiconosMatrix
106    * \param startRow an int, sub-block position
107    * \param startCol an int, sub-block position
108    * \param x a pointer to a SiconosVector
109    * \param res a DenseVect
110    */
111   // friend void private_addprod(const SiconosMatrix& A, unsigned int startRow, unsigned int startCol, const SiconosVector& x, SiconosVector& res);
112 
113 
114   /**  computes res = subA*x +res, subA being a submatrix of trans(A) (rows from startRow to startRow+sizeY and columns between startCol and startCol+sizeX).
115    *  If x is a block vector, it call the present function for all blocks.
116    * \param x a pointer to a SiconosVector
117    * \param A a pointer to SiconosMatrix
118    * \param startRow an int, sub-block position
119    * \param startCol an int, sub-block position
120    * \param res a DenseVect, res.
121    */
122   // friend void private_addprod(SPC::SiconosVector x , SPC::SiconosMatrix A,
123   //                             unsigned int startRow, unsigned int startCol,
124   //                             SP::SiconosVector res);
125 
126   /**  computes y = subA*x (init =true) or += subA * x (init = false), subA being a submatrix of A (all columns, and rows between start and start+sizeY).
127    *  If x is a block vector, it call the present function for all blocks.
128    * \param A a pointer to SiconosMatrix
129    * \param startRow an int, sub-block position
130    * \param x a pointer to a SiconosVector
131    * \param y a pointer to a SiconosVector
132    * \param init a bool
133    */
134   void private_prod(unsigned int startRow, const SiconosVector& x, SiconosVector& y, bool init);
135 
136 
137   /**  computes res = subA*x +res, subA being a submatrix of A (rows from startRow to startRow+sizeY and columns between startCol and startCol+sizeX).
138    * If x is a block vector, it call the present function for all blocks.
139    * \param A a pointer to SiconosMatrix
140    * \param startRow an int, sub-block position
141    * \param startCol an int, sub-block position
142    * \param x a pointer to a SiconosVector
143    * \param res a DenseVect
144    */
145   void private_addprod(unsigned int startRow, unsigned int startCol, const SiconosVector& x, SiconosVector& res);
146 
147    /**  computes res = a*subA*x +res, subA being a submatrix of A (rows from startRow to startRow+sizeY and columns between startCol and startCol+sizeX).
148     *   If x is a block vector, it call the present function for all blocks.
149     *   \param a a double
150     *   \param A a pointer to SiconosMatrix
151     *   \param startRow an int, sub-block position
152     *   \param startCol an int, sub-block position
153     *   \param x a pointer to a SiconosVector
154     *   \param res a DenseVect
155     */
156   // friend void private_addprod(double a, SPC::SiconosMatrix A,
157   //                             unsigned int startRow, unsigned int startCol,
158   //                             SPC::SiconosVector x, SP::SiconosVector res);
159 
160 
161   /**  computes y = a*subA*x (init =true) or += a*subA * x (init = false), subA being a submatrix of A (all columns, and rows between start and start+sizeY).
162    *   If x is a block vector, it call the present function for all blocks.
163    *    \param a a double
164    *    \param A a pointer to SiconosMatrix
165    *    \param start an int, sub-block position
166    *    \param x a pointer to a SiconosVector
167    *    \param y a pointer to a SiconosVector
168    *    \param init, a bool
169    */
170   // friend void private_prod(double a, SPC::SiconosMatrix A, unsigned int start,
171   //                          SPC::SiconosVector x, SP::SiconosVector y, bool init);
172 
173   /**  computes y = subA*x (init =true) or += subA * x (init = false), subA being a submatrix of trans(A) (all columns, and rows between start and start+sizeY).
174    *    If x is a block vector, it call the present function for all blocks.
175    *    \param x a pointer to a SiconosVector
176    *    \param A a pointer to SiconosMatrix
177    *    \param start an int, sub-block position
178    *    \param y a pointer to a SiconosVector
179    *    \param init a bool
180   */
181   // friend void private_prod(SPC::SiconosVector x, SPC::SiconosMatrix A, unsigned int start, SP::SiconosVector y, bool init);
182   // friend void private_prod(SPC::BlockVector, SPC::SiconosMatrix, unsigned int, SP::SiconosVector, bool);
183   // friend void private_prod(SPC::BlockVector, SPC::SiconosMatrix, unsigned int, SP::BlockVector, bool);
184   // friend void private_prod(SPC::SiconosVector, SPC::SiconosMatrix, unsigned int, SP::BlockVector, bool);
185 
186 public:
187   /** Default constructor */
188   SimpleMatrix();
189 
190   /** constructor with the type and the dimension of the Boost matrix
191    *  \param row number of rows.
192    *  \param col number of columns.
193    *  \param typ the type of matrix
194    *  \param upper if Siconos::UBLAS_TYPE==SPARSE, number of non-zero terms, if Siconos::UBLAS_TYPE == BANDED, number of diags. under the main diagonal
195    *  \param lower if Siconos::UBLAS_TYPE == BANDED, number of diags. over the main diagonal
196    */
197   SimpleMatrix(unsigned int row, unsigned int col, Siconos::UBLAS_TYPE typ = Siconos::DENSE, unsigned int upper = 1, unsigned int lower = 1);
198 
199   /** constructor with the the dimensions of the Boost matrix, a default value and the type.
200    *  \param row number of rows.
201    *  \param col number of columns.
202    *  \param inputValue double a, so that *this = [a a a ...]
203    *  \param typ the type of matrix
204    *  \param upper if Siconos::UBLAS_TYPE==SPARSE, number of non-zero terms, if Siconos::UBLAS_TYPE == BANDED, number of diags. under the main diagonal
205    *  \param lower if Siconos::UBLAS_TYPE == BANDED, number of diags. over the main diagonal
206    */
207   SimpleMatrix(unsigned int row, unsigned int col, double inputValue,
208                Siconos::UBLAS_TYPE typ = Siconos::DENSE,
209                unsigned int upper = 1, unsigned int lower = 1);
210 
211   /** copy constructor
212    *  \param smat the matrix to copy
213    */
214   SimpleMatrix(const SimpleMatrix& smat);
215 
216   /** copy constructor of a block given by the coord = [r0A r1A c0A c1A]
217    *  \param A the matrix which contains the block to extract
218    *  \param coord positions of the block to be extracted (row:start, row:end, col:start, col:end)
219    */
220   SimpleMatrix(const SimpleMatrix& A , const Index& coord );
221 
222   /** copy constructor
223    *  \param m the matrix to copy
224    */
225   SimpleMatrix(const SiconosMatrix& m);
226 
227   /** constructor with a DenseMat matrix (see SiconosMatrix.h for details)
228    *  \param m a DenseMat
229    */
230   SimpleMatrix(const DenseMat& m);
231 
232   /** constructor with a TriangMat matrix (see SiconosMatrix.h for details)
233    *  \param m a TriangMat
234    */
235   SimpleMatrix(const TriangMat& m);
236 
237   /** constructor with a SymMat matrix (see SiconosMatrix.h for details)
238    *  \param m a SymMat
239    */
240   SimpleMatrix(const SymMat& m);
241 
242   /** constructor with a BandedMat matrix (see SiconosMatrix.h for details)
243    *  \param m a BandedMat
244    */
245   SimpleMatrix(const BandedMat& m);
246 
247   /** constructor with a SparseMat matrix (see SiconosMatrix.h for details)
248    *  \param m a SparseMat
249    */
250   SimpleMatrix(const SparseMat& m);
251 
252   /** constructor with a SparseCoordinateMat matrix (see SiconosMatrix.h for details)
253    *  \param m a SparseMat
254    */
255   SimpleMatrix(const SparseCoordinateMat& m);
256 
257   /** constructor with a ZeroMat matrix (see SiconosMatrix.h for details)
258    *  \param m a ZeroMat
259    */
260   SimpleMatrix(const ZeroMat& m);
261 
262   /** constructor with a IdentityMat matrix (see SiconosMatrix.h for details)
263    *  \param m a IdentityMat
264    */
265   SimpleMatrix(const IdentityMat& m);
266 
267   /** constructor with an input file
268    *  \param file the input file path
269    *  \param ascii a boolean to indicate if the file is in ascii
270    */
271   SimpleMatrix(const std::string& file, bool ascii = true);
272 
273   /** destructor
274    */
275   ~SimpleMatrix();
276   //************************** GETTERS/SETTERS  **************************
277 
278   void updateNumericsMatrix();
279 
numericsMatrix() const280   NumericsMatrix * numericsMatrix() const
281   {
282     return _numericsMatrix.get();
283   };
284 
285   /** determines if the matrix has been inversed
286    *  \return true if the matrix is inversed
287    */
isPLUInversed() const288   inline bool isPLUInversed() const
289   {
290     return _isPLUInversed;
291   }
292 
293   /** determines if the matrix has been factorized
294    *  \return true if the matrix is factorized
295    */
isPLUFactorized() const296   inline bool isPLUFactorized() const
297   {
298     return _isPLUFactorized;
299   }
300 
301  /** determines if the matrix has been factorized
302    *  \return true if the matrix is factorized
303    */
isPLUFactorizedInPlace() const304   inline bool isPLUFactorizedInPlace() const
305   {
306     return _isPLUFactorizedInPlace;
307   }
308   /** determines if the matrix has been factorized
309    *  \return true if the matrix is factorized
310    */
isCholeskyFactorized() const311   inline bool isCholeskyFactorized() const
312   {
313     return _isCholeskyFactorized;
314   }
315 
316  /** determines if the matrix has been factorized
317    *  \return true if the matrix is factorized
318    */
isCholeskyFactorizedInPlace() const319   inline bool isCholeskyFactorizedInPlace() const
320   {
321     return _isCholeskyFactorizedInPlace;
322   }
323 
324   /** determines if the matrix has been factorized
325    *  \return true if the matrix is factorized
326    */
isQRFactorized() const327   inline bool isQRFactorized() const
328   {
329     return _isQRFactorized;
330   }
331 
332 
ipiv() const333   inline SP::VInt ipiv() const
334   {
335     return _ipiv;
336   }
337 
338 
339   bool checkSymmetry(double tol) const;
340 
341   /** get DenseMat matrix
342    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
343    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
344    *  \return a DenseMat
345    */
346   const DenseMat getDense(unsigned int row = 0, unsigned int col = 0) const;
347 
348   /** get TriangMat matrix
349    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
350    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
351    *  \return a TriangMat
352    */
353   const TriangMat getTriang(unsigned int row = 0, unsigned int col = 0) const;
354 
355   /** get SymMat matrix
356    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
357    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
358    *  \return a SymMat
359    */
360   const SymMat getSym(unsigned int row = 0, unsigned int col = 0) const;
361 
362   /** get BandedMat matrix
363    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
364    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
365    *  \return a BandedMat
366    */
367   const BandedMat getBanded(unsigned int row = 0, unsigned int col = 0) const;
368 
369   /** get SparseMat matrix
370    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
371    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
372    *  \return a SparseMat
373    */
374   const SparseMat getSparse(unsigned int row = 0, unsigned int col = 0) const;
375 
376   /** get SparseCoordinateMat matrix
377    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
378    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
379    *  \return a SparseCoordinateMat
380    */
381   const SparseCoordinateMat getSparseCoordinate(unsigned int row = 0, unsigned int col = 0) const;
382 
383   /** get ZeroMat matrix
384    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
385    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
386    *  \return a ZeroMat
387    */
388   const ZeroMat getZero(unsigned int row = 0, unsigned int col = 0) const;
389 
390   /** get  getIdentity matrix
391    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
392    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
393    *  \return an IdentityMat
394    */
395   const IdentityMat getIdentity(unsigned int row = 0, unsigned int col = 0) const;
396 
397   /** get a pointer on DenseMat matrix
398    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
399    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
400    *  \return a DenseMat*
401    */
402   DenseMat* dense(unsigned int row = 0, unsigned int col = 0) const;
403 
404   /** get a pointer on TriangMat matrix
405    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
406    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
407    *  \return a TriangMat*
408    */
409   TriangMat* triang(unsigned int row = 0, unsigned int col = 0) const;
410 
411   /** get a pointer on SymMat matrix
412    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
413    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
414    *  \return a SymMat*
415    */
416   SymMat* sym(unsigned int row = 0, unsigned int col = 0) const;
417 
418   /** get a pointer on BandedMat matrix
419    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
420    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
421    *  \return a BandedMat*
422    */
423   BandedMat* banded(unsigned int row = 0, unsigned int col = 0) const;
424 
425   /** get a pointer on SparseMat matrix
426    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
427    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
428    *  \return a SparseMat*
429    */
430   SparseMat* sparse(unsigned int row = 0, unsigned int col = 0) const;
431 
432   /** get a pointer on SparseCoordinateMat matrix
433    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
434    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
435    *  \return a SparseCoordinateMat*
436    */
437   SparseCoordinateMat* sparseCoordinate(unsigned int row = 0, unsigned int col = 0) const;
438 
439   /** get a pointer on ZeroMat matrix
440    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
441    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
442    *  \return a ZeroMat*
443    */
444   ZeroMat* zero_mat(unsigned int row = 0, unsigned int col = 0) const;
445 
446   /** get a pointer on Identity matrix
447    *  \param row an unsigned int, position of the block - Useless for SimpleMatrix
448    *  \param col an unsigned int, position of the block - Useless for SimpleMatrix
449    *  \return an IdentityMat*
450    */
451   IdentityMat* identity(unsigned int row = 0, unsigned int col = 0) const;
452 
453   /** return the address of the array of double values of the matrix
454    *  \param row position for the required block ->useless for SimpleMatrix
455    *  \param col position for the required block ->useless for SimpleMatrix
456    *  \return double* : the pointer on the double array
457    */
458   double* getArray(unsigned int row = 0, unsigned int col = 0) const;
459 
460   /** sets all the values of the matrix to 0.0
461    */
462   void zero();
463 
464   /** Initialize the matrix with random values
465    */
466   void randomize();
467 
468   /** Initialize a symmetric matrix with random values
469    */
470   void randomize_sym();
471 
472   /** set an identity matrix
473    */
474   void eye();
475 
476   /** copy the matrix data to the array given in parameter'
477    * Works only for dense matrices !
478    * \param data array where the matrix is copied
479    * \return the size of the matrix
480    */
481   unsigned copyData(double* data) const;
482 
483   void assign(const SimpleMatrix &smat);
484 
485 
486   /** get the number of rows or columns of the matrix
487    *  \param index 0 for rows, 1 for columns
488    *  \return the size
489    */
490   unsigned int size(unsigned int index) const;
491 
492   /** resize the matrix with nbrow rows and nbcol columns The existing elements of the matrix are preseved when specified.
493    *  \param row the new number of rows
494    *  \param col the mew number of columns
495    *  \param lower (only for Banded)
496    *  \param upper (only for Banded)
497    *  \param preserve preserve existing elements
498    */
499   void resize(unsigned int row, unsigned int col, unsigned int lower = 0, unsigned int upper = 0, bool preserve = true);
500 
501   /** compute the infinite norm of the matrix
502    *  \return a double
503    */
504   double normInf() const;
505 
506   /** Compute the normInf for each column
507    * \param vIn column
508    */
509   void normInfByColumn(SP::SiconosVector vIn) const;
510 
511   /** compute the determinant of the matrix (use LU factorization)
512    *  \return a double
513    */
514   double det() const;
515 
516   /** display data on standard output
517    */
518   void display() const;
519 
520   void displayExpert(bool  brief = true) const;
521   /** put data of the matrix into a std::string
522    * \return std::string
523    */
524   std::string toString() const;
525 
526   /** get or set the element matrix[i,j]
527    *  \param i an unsigned int
528    *  \param j an unsigned int
529    *  \return the element matrix[i,j]
530    */
531   double& operator()(unsigned int i, unsigned int j);
532 
533   /** get or set the element matrix[i,j]
534    *  \param i an unsigned int
535    *  \param j an unsigned int
536    *  \return the element matrix[i,j]
537    */
538   double operator()(unsigned int i, unsigned int j) const;
539 
540   /** return the element matrix[i,j]
541    *  \param i an unsigned int
542    *  \param j an unsigned int
543    *  \return a double
544    */
545   double getValue(unsigned int i, unsigned int j) const;
546 
547   /** set the element matrix[i,j]
548    *  \param i an unsigned int
549    *  \param j an unsigned int
550    *  \param value
551    */
552   void setValue(unsigned int i, unsigned int j, double value);
553 
554   /** Copy of the content of a given matrix into the current object,
555       at position (posRow, posCol).
556 
557       Defined in SimpleMatrixSetGet.cpp.
558 
559       \param posRow row-index of the targeted block
560       \param posCol col-index of the targeted block
561       \param m source matrix to be copied. Can be a SimpleMatrix or a BlockMatrix.
562   */
563   void setBlock(unsigned int posRow, unsigned int posCol, const SiconosMatrix& m);
564 
565   // friend void setBlock(SPC::SiconosMatrix , SP::SiconosMatrix , const Index&, const Index&);
566 
567   // /** get block at position row-col, (current matrix in SimpleMatrix case)
568   //  * \param row row index
569   //  * \param col column index
570   //  * \return a sub-matrix
571   //  */
572   // inline SP::SiconosMatrix block(unsigned int row = 0, unsigned int col = 0)
573   // {
574   //   return shared_from_this();
575   // };
576 
577   // /** get block at position row-col, (current matrix in SimpleMatrix case)
578   //  * \param row row index
579   //  * \param col column index
580   //  * \return a sub-matrix
581   //  */
582   // inline SPC::SiconosMatrix block(unsigned int row = 0, unsigned int col = 0) const
583   // {
584   //   return shared_from_this();
585   // };
586 
587   /** get row index of current matrix and save it into vOut
588    *  \param row index row we want to get
589    *  \param[out] vOut SiconosVector that will contain the desired row
590    */
591   void getRow(unsigned int row, SiconosVector& vOut) const;
592 
593   /** get column index of current matrix and save it into vOut
594    *  \param col index column we want to get
595    *  \param[out] vOut SiconosVector that will contain the desired column
596    */
597   void getCol(unsigned int col, SiconosVector& vOut) const;
598 
599   /** set line row of the current matrix with vector v
600    *  \param row index row we want to set
601    *  \param vIn SiconosVector containing the new row
602    */
603   void setRow(unsigned int row , const SiconosVector& vIn);
604 
605   /** set column col of the current matrix with vector v
606    *  \param col index column we want to set
607    *  \param vIn a SiconosVector containing the new column
608    */
609   void setCol(unsigned int col, const SiconosVector& vIn);
610 
611   /** get column number index of current matrix, starting from element at position pos and save it into vOut
612    *  \param index index of required column
613    *  \param pos index of the first required element in the column
614    *  \param[out] vOut a SP::SiconosVector
615    */
616   void getSubCol(unsigned int index, unsigned int pos, SP::SiconosVector vOut) const;
617 
618   /** get row number index of current matrix, starting from element at position pos and save it into vOut
619    *  \param index index of the required row
620    *  \param pos index of the first required element in the row
621    *  \param[out] vOut a SP::SiconosVector that will contain the sub row
622    */
623   void getSubRow(unsigned int index, unsigned int pos, SP::SiconosVector vOut) const;
624 
625   /** set column number index of current matrix, starting from element at position pos, with vIn
626    *  \param index index of required column
627    *  \param pos index of the first required element in the column
628    *  \param vIn a vector
629    */
630   void setSubCol(unsigned int index, unsigned int pos, SP::SiconosVector vIn);
631 
632   /** set row number index of current matrix, starting from element at position pos, with vIn
633    *  \param index index of required row
634    *  \param pos index of the first required element in the row
635    *  \param vIn a vector
636    */
637   void setSubRow(unsigned int index, unsigned int pos, SP::SiconosVector vIn);
638 
639   /** add the input matrix to the elements starting from position i (row) and j (col).
640    *  \param i an unsigned int
641    *  \param j an unsigned int
642    *  \param m a SiconosMatrix
643    */
644   void addBlock(unsigned int i, unsigned int j, const SiconosMatrix& m);
645 
646   /** subtract the input matrix to the elements starting from position i (row) and j (col).
647    *  \param i an unsigned int
648    *  \param j an unsigned int
649    *  \param m a SiconosMatrix
650    */
651   void subBlock(unsigned int i, unsigned int j, const SiconosMatrix& m);
652 
653   /** transpose in place: x->trans() is x = transpose of x.
654    */
655   void trans();
656 
657   /** transpose a matrix: x->trans(m) is x = transpose of m.
658    *  \param mat the matrix to be transposed.
659    */
660   void trans(const SiconosMatrix& mat);
661 
662   /** assignment
663    * \param m the matrix to be copied
664    * \return SimpleMatrix&
665    */
666   SimpleMatrix& operator = (const SiconosMatrix& m);
667 
668   /** assignment
669    *  \param m the matrix to be copied
670    * \return SimpleMatrix&
671    */
672   SimpleMatrix& operator = (const SimpleMatrix& m);
673 
674   /** assignment to a DenseMat
675    * \param m the matrix to be copied
676    * \return SimpleMatrix&
677    */
678   SimpleMatrix& operator = (const DenseMat& m);
679 
680   /** operator +=
681    *  \param m a matrix to add
682    * \return SimpleMatrix&
683    */
684   SimpleMatrix& operator +=(const SiconosMatrix& m);
685 
686   /** operator -=
687    *  \param m a matrix to subtract
688    * \return SimpleMatrix&
689    */
690   SimpleMatrix& operator -=(const SiconosMatrix& m);
691 
692   /** computes an LU factorization of a general M-by-N matrix using partial pivoting with row interchanges.
693    *  The result is returned in this (InPlace). Based on Blas dgetrf function.
694    */
695   void PLUFactorizationInPlace();
696 
697   /** computes a factorization of a general M-by-N matrix
698    */
699   void Factorize();
700 
701   /**  compute inverse of this thanks to LU factorization with Partial pivoting.
702    * This method inverts U and then computes inv(A) by solving the system
703    *  inv(A)*L = inv(U) for inv(A). The result is returned in this (InPlace). Based on Blas dgetri function.
704    */
705   void PLUInverseInPlace();
706 
707   /** solves a system of linear equations A * X = B  (A=this) with a general N-by-N matrix A using the LU factorization computed
708    *   by PLUFactorizationInPlace. Based on Blas dgetrs function.
709    *  \param[in,out] B on input the RHS matrix b; on output the result x
710    */
711   void PLUForwardBackwardInPlace(SiconosMatrix& B);
712   void Solve(SiconosMatrix& B);
713 
714   /** solves a system of linear equations A * X = B  (A=this) with a general N-by-N matrix A using the LU factorization computed
715    *   by PLUFactorizationInPlace.  Based on Blas dgetrs function.
716    *  \param[in,out] B on input the RHS matrix b; on output the result x
717    */
718   void PLUForwardBackwardInPlace(SiconosVector& B);
719   void Solve(SiconosVector& B);
720 
721   /** solves a system of linear equations A * X = B  (A=this)
722       with a general N-by-N matrix A using the Least squares method
723    *  \param[in,out] B on input the RHS matrix b; on output the result x
724    */
725   void SolveByLeastSquares(SiconosMatrix& B);
726 
727   /** solves a system of linear equations A * X = B  (A=this)
728        with a general N-by-N matrix A using the Least squares method
729    *  \param[in,out] B on input the RHS matrix b; on output the result x
730     */
731   void SolveByLeastSquares(SiconosVector& B);
732 
733   /** set to false all LU indicators. Useful in case of
734       assignment for example.
735   */
736 
737   void resetLU();
738 
739   /** set to false all Cholesky indicators. Useful in case of
740       assignment for example.
741   */
742 
743   void resetCholesky();
744 
745   /** set to false all QR indicators. Useful in case of
746       assignment for example.
747   */
748   void resetQR();
749 
750   /** set to false all factorization indicators. Useful in case of
751       assignment for example.
752   */
753   void resetFactorizationFlags();
754 
755 
756 
757   /** Visitors hook
758    */
759   ACCEPT_STD_VISITORS();
760     /** \defgroup SimpleMatrixFriends
761 
762       List of friend functions of the SimpleMatrix class
763 
764       Declared in SimpleMatrixFriends.hpp.
765       Implemented in SimpleMatrixFriends.cpp.
766 
767       @{
768   */
769   friend std::ostream& operator<<(std::ostream& os, const SimpleMatrix& sm);
770 
771   friend const SimpleMatrix operator * (const SiconosMatrix&, double);
772 
773   friend  SP::SimpleMatrix operator * (const SP::SimpleMatrix, const SP::SimpleMatrix);
774 
775   friend  void operator +=(SP::SiconosMatrix, SP::SimpleMatrix);
776 
777   friend  SimpleMatrix operator * (double , const SiconosMatrix&);
778 
779   friend const SimpleMatrix operator /(const SiconosMatrix&, double);
780 
781   friend const SimpleMatrix operator +(const SiconosMatrix&, const SiconosMatrix&);
782 
783   friend SP::SimpleMatrix operator +(const SP::SimpleMatrix, const SP::SimpleMatrix);
784 
785   friend void add(const SiconosMatrix&, const SiconosMatrix&, SiconosMatrix&);
786 
787   friend const SimpleMatrix operator -(const SiconosMatrix&, const SiconosMatrix&);
788 
789   friend void sub(const SiconosMatrix&, const SiconosMatrix&, SiconosMatrix&);
790 
791   friend bool operator == (const SiconosMatrix&, const SiconosMatrix&);
792 
793   friend bool operator!= (const SiconosMatrix&, const SiconosMatrix&);
794 
795   // friend const SimpleMatrix prod(const SiconosMatrix&, const SiconosMatrix&);
796 
797   // friend void prod(const SiconosMatrix&, const SiconosMatrix&, SiconosMatrix&, bool);
798 
799   // friend void axpy_prod(const SiconosMatrix&, const SiconosMatrix&, SiconosMatrix&, bool);
800 
801   // friend const SiconosVector prod(const SiconosMatrix&, const SiconosVector&);
802 
803   // friend void prod(const SiconosMatrix&, const BlockVector&, SiconosVector&, bool);
804 
805   // friend void prod(const SiconosMatrix&, const SiconosVector&, BlockVector&, bool);
806 
807   // friend void prod(double, const SiconosMatrix&, const SiconosVector&, SiconosVector&, bool);
808 
809   // friend void subprod(const SiconosMatrix&, const SiconosVector&, SiconosVector&, const Index&, bool);
810 
811   // friend void axpy_prod(const SiconosMatrix&, const SiconosVector&, SiconosVector&, bool);
812 
813   // friend void gemvtranspose(double, const SiconosMatrix&, const SiconosVector&, double, SiconosVector&);
814 
815   // friend void gemv(double, const SiconosMatrix&, const SiconosVector&, double, SiconosVector&);
816 
817   // friend void gemmtranspose(double, const SiconosMatrix&, const SiconosMatrix&, double, SiconosMatrix&);
818 
819   // friend void gemm(double, const SiconosMatrix&, const SiconosMatrix&, double, SiconosMatrix&);
820 
821   // friend void scal(double, const SiconosMatrix&, SiconosMatrix&, bool);
822 
823   /** End of Friend functions group @} */
824 
825 
826 
827 };
828 
829 
830 
831 #endif
832