IVT
Matd.cpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // This file is part of the Integrating Vision Toolkit (IVT).
3 //
4 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
5 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
6 //
7 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
8 // All rights reserved.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
19 //
20 // 3. Neither the name of the KIT nor the names of its contributors may be
21 // used to endorse or promote products derived from this software
22 // without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
25 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
28 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // ****************************************************************************
35 // ****************************************************************************
36 // Filename: Matd.cpp
37 // Author: Pedram Azad
38 // Date: 2004
39 // ****************************************************************************
40 
41 
42 // ****************************************************************************
43 // Includes
44 // ****************************************************************************
45 
46 #include <new> // for explicitly using correct new/delete operators on VC DSPs
47 
48 #include "Vecd.h"
49 #include "Matd.h"
50 
51 #include <math.h>
52 #include <stdio.h>
53 #include <string.h>
54 
55 
56 
57 // ****************************************************************************
58 // Constructors / Destructor
59 // ****************************************************************************
60 
62 {
63  m_nRows = 0;
64  m_nColumns = 0;
65  m_ppElements = 0;
66 }
67 
68 CMatd::CMatd(int nRows, int nColumns)
69 {
70  m_ppElements = 0;
71 
72  SetSize(nRows, nColumns);
73 }
74 
76 {
77  m_ppElements = 0;
78 
79  SetSize(m.m_nRows, m.m_nColumns);
80 
81  for (int i = 0; i < m_nRows; i++)
82  for (int j = 0; j < m_nColumns; j++)
83  m_ppElements[i][j] = m.m_ppElements[i][j];
84 }
85 
87 {
88  if (m_ppElements)
89  {
90  for (int i = 0; i < m_nRows; i++)
91  delete [] m_ppElements[i];
92 
93  delete [] m_ppElements;
94  }
95 }
96 
97 
98 // ****************************************************************************
99 // Operators
100 // ****************************************************************************
101 
102 double& CMatd::operator() (int nRow, int nColumn) const
103 {
104  //_ASSERTE(nRow >= 0 && nRow < m_nRows && nColumn >= 0 && nColumn < m_nColumns);
105 
106  return m_ppElements[nRow][nColumn];
107 }
108 
110 {
111  SetSize(m.m_nRows, m.m_nColumns);
112 
113  for (int i = 0; i < m_nRows; i++)
114  for (int j = 0; j < m_nColumns; j++)
115  m_ppElements[i][j] = m.m_ppElements[i][j];
116 
117  return *this;
118 }
119 
120 void CMatd::operator*= (const double s)
121 {
122  for (int i = 0; i < m_nRows; i++)
123  for (int j = 0; j < m_nColumns; j++)
124  m_ppElements[i][j] *= s;
125 }
126 
128 {
129  //_ASSERTE(m_nColumns == m.m_nRows && m_nColumns > 0);
130 
131  int i, j, k, newColumns = m.m_nColumns;
132  double constantElement;
133  CMatd result(m_nRows, newColumns);
134 
135  // ikj matrix multiplication
136  for (i = 0; i < m_nRows; i++)
137  {
138  constantElement = m_ppElements[i][0];
139 
140  for (j = 0; j < newColumns; j++)
141  {
142  result.m_ppElements[i][j] = constantElement * m.m_ppElements[0][j];
143  }
144  }
145  for (i = 0; i < m_nRows; i++)
146  {
147  for (k = 1; k < m_nColumns; k++)
148  {
149  constantElement = m_ppElements[i][k];
150 
151  for (j = 0; j < newColumns; j++)
152  {
153  result.m_ppElements[i][j] += constantElement * m.m_ppElements[k][j];
154  }
155  }
156  }
157 
158  return result;
159 }
160 
162 {
163  if (m_nColumns != m.m_nColumns || m_nRows != m.m_nRows)
164  printf("error: incompatible input in CMatd::operator+(const CMatd&)\n");
165 
166  CMatd result(m_nRows, m_nColumns);
167 
168  // ikj matrix multiplication
169  for (int i = 0; i < m_nRows; i++)
170  for (int j = 0; j < m_nColumns; j++)
171  result.m_ppElements[i][j] = m_ppElements[i][j] + m.m_ppElements[i][j];
172 
173  return result;
174 }
175 
177 {
178  if (m_nColumns != m.m_nColumns || m_nRows != m.m_nRows)
179  printf("error: incompatible input in CMatd::operator-(const CMatd&)\n");
180 
181  CMatd result(m_nRows, m_nColumns);
182 
183  // ikj matrix multiplication
184  for (int i = 0; i < m_nRows; i++)
185  for (int j = 0; j < m_nColumns; j++)
186  result.m_ppElements[i][j] = m_ppElements[i][j] - m.m_ppElements[i][j];
187 
188  return result;
189 }
190 
192 {
193  CMatd result(m_nRows, m_nColumns);
194 
195  // ikj matrix multiplication
196  for (int i = 0; i < m_nRows; i++)
197  for (int j = 0; j < m_nColumns; j++)
198  result.m_ppElements[i][j] = s * m_ppElements[i][j];
199 
200  return result;
201 }
202 
204 {
205  //_ASSERTE(m_nColumns == v.GetSize());
206 
207  CVecd result(m_nRows);
208 
209  for (int i = 0; i < m_nRows; i++)
210  {
211  result[i] = 0.0;
212 
213  for (int j = 0; j < m_nColumns; j++)
214  {
215  result[i] += m_ppElements[i][j] * v[j];
216  }
217  }
218 
219  return result;
220 }
221 
222 
223 // ****************************************************************************
224 // Methods
225 // ****************************************************************************
226 
228 {
229  for (int i = 0; i < m_nRows; i++)
230  for (int j = 0; j < m_nColumns; j++)
231  m_ppElements[i][j] = 0.0;
232 }
233 
235 {
236  if (m_nRows != m_nColumns)
237  return false;
238 
239  Zero();
240 
241  for (int i = 0; i < m_nRows; i++)
242  m_ppElements[i][i] = 1.0;
243 
244 
245  return true;
246 }
247 
249 {
250  if (m_nRows != m_nColumns)
251  {
252  printf("error: input matrix must be square matrix for CMatd::Invert\n");
253  CMatd null(0, 0);
254  return null;
255  }
256 
257  const int n = m_nColumns;
258  int i;
259 
260  CMatd copiedMatrix(*this);
261  CMatd resultMatrix(n, n);
262 
263  resultMatrix.Unit();
264 
265  int *pPivotRows = new int[n];
266  for (i = 0; i < n; i++)
267  pPivotRows[i] = 0;
268 
269  // invert by gauss elimination
270  for (i = 0; i < n; i++)
271  {
272  int j, nPivotColumn = 0;
273 
274  double *helper1 = copiedMatrix.m_ppElements[i];
275  double *helper2 = resultMatrix.m_ppElements[i];
276 
277  // determine pivot element
278  double max = 0;
279  for (j = 0; j < n; j++)
280  if (fabs(helper1[j]) > max)
281  {
282  max = fabs(helper1[j]);
283  nPivotColumn = j;
284  }
285 
286  pPivotRows[nPivotColumn] = i;
287 
288  const double dPivotElement = copiedMatrix.m_ppElements[i][nPivotColumn];
289 
290  if (fabs(dPivotElement) < 0.00001)
291  {
292  printf("error: input matrix is not regular for CMatd::Invert\n");
293  delete [] pPivotRows;
294  CMatd null(0, 0);
295  return null;
296  }
297 
298  const double dFactor = 1.0 / dPivotElement;
299 
300  for (j = 0; j < n; j++)
301  {
302  helper1[j] *= dFactor;
303  helper2[j] *= dFactor;
304  }
305 
306  for (j = 0; j < n; j++)
307  {
308  if (i != j)
309  {
310  const double v = copiedMatrix.m_ppElements[j][nPivotColumn];
311  int k;
312 
313  helper1 = copiedMatrix.m_ppElements[j];
314  helper2 = copiedMatrix.m_ppElements[i];
315  for (k = 0; k < n; k++)
316  helper1[k] -= v * helper2[k];
317  helper1[nPivotColumn] = 0; // explicitly set to zero
318 
319  helper1 = resultMatrix.m_ppElements[j];
320  helper2 = resultMatrix.m_ppElements[i];
321  for (k = 0; k < n; k++)
322  helper1[k] -= v * helper2[k];
323  }
324  }
325  }
326 
327  // bring result rows in pivot order
328  double **ppTemp = new double*[n];
329  for (i = 0; i < n; i++)
330  ppTemp[i] = resultMatrix.m_ppElements[i];
331 
332  for (i = 0; i < n; i++)
333  resultMatrix.m_ppElements[i] = ppTemp[pPivotRows[i]];
334 
335  delete [] pPivotRows;
336 
337  return resultMatrix;
338 }
339 
340 void CMatd::SetSize(int nRows, int nColumns)
341 {
342  //_ASSERTE(nRows >= 0 && nColumns >= 0);
343 
344  // free memory first
345  if (m_ppElements)
346  {
347  for (int i = 0; i < m_nRows; i++)
348  delete [] m_ppElements[i];
349  delete [] m_ppElements;
350  }
351 
352  // allocate memory for matrix
353  m_ppElements = new double*[nRows];
354  for (int i = 0; i < nRows; i++)
355  {
356  m_ppElements[i] = new double[nColumns];
357 
358  for (int j = 0; j < nColumns; j++)
359  m_ppElements[i][j] = 0.0;
360  }
361 
362  // save size of matrix
363  m_nRows = nRows;
364  m_nColumns = nColumns;
365 }
366 
368 {
369  CMatd result(m_nColumns, m_nRows);
370 
371  for (int i = 0; i < m_nRows; i++)
372  for (int j = 0; j < m_nColumns; j++)
373  result.m_ppElements[j][i] = m_ppElements[i][j];
374 
375  return result;
376 }
double & operator()(int nRow, int nColumn) const
Definition: Matd.cpp:102
CMatd()
Definition: Matd.cpp:61
CMatd Invert() const
Definition: Matd.cpp:248
~CMatd()
Definition: Matd.cpp:86
void operator*=(const double s)
Definition: Matd.cpp:120
Data structure and operations for calculating with matrices of arbitrary dimension.
Definition: Matd.h:61
CMatd & operator=(const CMatd &v)
Definition: Matd.cpp:109
CMatd operator-(const CMatd &m)
Definition: Matd.cpp:176
void Zero()
Definition: Matd.cpp:227
CMatd operator*(const double s)
Definition: Matd.cpp:191
void SetSize(int nRows, int nColumns)
Definition: Matd.cpp:340
bool Unit()
Definition: Matd.cpp:234
CMatd GetTransposed()
Definition: Matd.cpp:367
Data structure and operations for calculating with vectors of arbitrary dimension.
Definition: Vecd.h:54
CMatd operator+(const CMatd &m)
Definition: Matd.cpp:161