1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Mask on a vpMatrix .
33  *
34  * Authors:
35  * Laneurit Jean
36  *
37  *****************************************************************************/
38 
39 #include <stdlib.h>
40 #include <visp3/core/vpDebug.h>
41 #include <visp3/core/vpException.h>
42 #include <visp3/core/vpMatrixException.h>
43 #include <visp3/core/vpSubMatrix.h>
44 
vpSubMatrix()45 vpSubMatrix::vpSubMatrix() : pRowNum(0), pColNum(0), parent(NULL) {}
46 
47 /*!
48   \brief Constructor
49   \param m : parent matrix
50   \param row_offset : row offset
51   \param col_offset : col offset
52   \param nrows : number of rows of the sub matrix
53   \param ncols : number of columns of the sub matrix
54 */
vpSubMatrix(vpMatrix & m,const unsigned int & row_offset,const unsigned int & col_offset,const unsigned int & nrows,const unsigned int & ncols)55 vpSubMatrix::vpSubMatrix(vpMatrix &m, const unsigned int &row_offset, const unsigned int &col_offset,
56                          const unsigned int &nrows, const unsigned int &ncols)
57   : pRowNum(0), pColNum(0), parent(NULL)
58 {
59   init(m, row_offset, col_offset, nrows, ncols);
60 }
61 
62 /*!
63   \brief Initialisation of a sub matrix
64   \param m : parent matrix
65   \param row_offset : row offset
66   \param col_offset : col offset
67   \param nrows : number of rows of the sub matrix
68   \param ncols : number of columns of the sub matrix
69 */
init(vpMatrix & m,const unsigned int & row_offset,const unsigned int & col_offset,const unsigned int & nrows,const unsigned int & ncols)70 void vpSubMatrix::init(vpMatrix &m, const unsigned int &row_offset, const unsigned int &col_offset,
71                        const unsigned int &nrows, const unsigned int &ncols)
72 {
73 
74   if (!m.data) {
75     throw(vpMatrixException(vpMatrixException::subMatrixError, "SubMatrix parent matrix is not allocated"));
76   }
77 
78   if (row_offset + nrows <= m.getRows() && col_offset + ncols <= m.getCols()) {
79     data = m.data;
80     parent = &m;
81     rowNum = nrows;
82     colNum = ncols;
83     pRowNum = m.getRows();
84     pColNum = m.getCols();
85 
86     if (rowPtrs)
87       free(rowPtrs);
88 
89     rowPtrs = (double **)malloc(nrows * sizeof(double *));
90     for (unsigned int r = 0; r < nrows; r++)
91       rowPtrs[r] = m.data + col_offset + (r + row_offset) * pColNum;
92 
93     dsize = pRowNum * pColNum;
94   } else {
95     throw(
96         vpMatrixException(vpMatrixException::incorrectMatrixSizeError, "Submatrix cannot be contain in parent matrix"));
97   }
98 }
99 
100 /*!
101   \brief This method can be used to detect if the parent matrix
102    always exits or its size have not changed and  throw an exception is not
103 */
checkParentStatus() const104 void vpSubMatrix::checkParentStatus() const
105 {
106   if (!data) {
107     throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,
108                             "vpSubMatrix parent vpMatrix has been destroyed"));
109   }
110   if (pRowNum != parent->getRows() || pColNum != parent->getCols()) {
111     throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,
112                             "vpSubMatrix size of parent vpMatrix has been changed"));
113   }
114 }
115 
116 /*!
117   \brief Operation A = B
118   \param B : a matrix
119 */
operator =(const vpMatrix & B)120 vpSubMatrix &vpSubMatrix::operator=(const vpMatrix &B)
121 {
122 
123   if ((colNum != B.getCols()) || (rowNum != B.getRows())) {
124     throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,
125                             "vpSubMatrix mismatch in operator vpSubMatrix=vpMatrix"));
126   }
127 
128   for (unsigned int i = 0; i < rowNum; i++) {
129     for (unsigned int j = 0; j < colNum; j++)
130       rowPtrs[i][j] = B[i][j];
131   }
132 
133   return *this;
134 }
135 
136 /*!
137   \brief Operation A = B
138   \param B : a subMatrix
139 */
operator =(const vpSubMatrix & B)140 vpSubMatrix &vpSubMatrix::operator=(const vpSubMatrix &B)
141 {
142 
143   if ((colNum != B.getCols()) || (rowNum != B.getRows())) {
144     throw(vpMatrixException(vpMatrixException::incorrectMatrixSizeError,
145                             "vpSubMatrix mismatch in operator vpSubMatrix=vpMatrix"));
146   }
147 
148   pRowNum = B.pRowNum;
149   pColNum = B.pColNum;
150   parent = B.parent;
151 
152   double **BrowPtrs = B.rowPtrs;
153 
154   for (unsigned int i = 0; i < rowNum; i++) {
155     for (unsigned int j = 0; j < colNum; j++)
156       rowPtrs[i][j] = BrowPtrs[i][j];
157   }
158 
159   return *this;
160 }
161 
162 /*!
163   \brief Operation A = x
164   \param x : a scalar
165 */
operator =(const double & x)166 vpSubMatrix &vpSubMatrix::operator=(const double &x)
167 {
168   for (unsigned int i = 0; i < rowNum; i++) {
169     for (unsigned int j = 0; j < colNum; j++)
170       rowPtrs[i][j] = x;
171   }
172 
173   return *this;
174 }
175 
~vpSubMatrix()176 vpSubMatrix::~vpSubMatrix() { data = NULL; }
177