CASToR  3.2
Tomographic Reconstruction (PET/SPECT/CT)
src/scanner/oMatrix.cc
Go to the documentation of this file.
1 
8 #include "oMatrix.hh"
9 
10 // =====================================================================
11 // ---------------------------------------------------------------------
12 // ---------------------------------------------------------------------
13 // =====================================================================
14 /*
15  \brief oMatrix constructor.
16  Initialize the member variables to their default values.
17 */
19 {
20  m_lin = 0;
21  m_col = 0;
22 
23  m2p_Mat = NULL;
24 }
25 
26 
27 
28 // =====================================================================
29 // ---------------------------------------------------------------------
30 // ---------------------------------------------------------------------
31 // =====================================================================
32 /*
33  \param nl : a number of lines
34  \param nc : a number of colons
35  \brief oMatrix constructor.
36  Instanciate a Matrix structure with the number of lines and colons provided in parameters
37 */
38 oMatrix::oMatrix(uint16_t nl, uint16_t nc)
39 {
40  m_lin = nl;
41  m_col = nc;
42  m2p_Mat = new HPFLTNB *[nl];
43 
44  for(uint16_t l=0 ; l<nl ; l++)
45  m2p_Mat[l] = new HPFLTNB[nc];
46 }
47 
48 
49 
50 // =====================================================================
51 // ---------------------------------------------------------------------
52 // ---------------------------------------------------------------------
53 // =====================================================================
54 /*
55  \brief oMatrix destructor.
56  Free memory of the oMatrix object.
57 */
59 {
60  for(uint16_t l=0 ; l<m_lin ; l++)
61  if(m2p_Mat[l]) delete[] m2p_Mat[l];
62 
63  if(m2p_Mat) delete[] m2p_Mat;
64 }
65 
66 
67 
68 // =====================================================================
69 // ---------------------------------------------------------------------
70 // ---------------------------------------------------------------------
71 // =====================================================================
72 /*
73  \fn Allocate
74  \param nl : a number of lines
75  \param nc : a number of colons
76  \brief Instanciate a Matrix structure with the number of lines and colons provided in parameters
77 */
78 void oMatrix::Allocate(uint16_t nl, uint16_t nc)
79 {
80  // No verbosity in oMatrix structure. Show this only if CASTOR_DEBUG is enabled (for bug tracking)
81  #ifdef CASTOR_DEBUG
82  Cout("oMatrix::Allocate() ...");
83  #endif
84 
85  // Free memory in case the matrix had already been allocated
86  if(m2p_Mat != NULL)
87  {
88  for(uint16_t l=0 ; l<m_lin ; l++)
89  if(m2p_Mat[l]) delete[] m2p_Mat[l];
90 
91  delete[] m2p_Mat;
92  }
93 
94  m_lin = nl;
95  m_col = nc;
96  m2p_Mat = new HPFLTNB *[nl];
97 
98  for(uint16_t l=0 ; l<nl ; l++)
99  m2p_Mat[l] = new HPFLTNB[nc];
100 }
101 
102 
103 
104 // =====================================================================
105 // ---------------------------------------------------------------------
106 // ---------------------------------------------------------------------
107 // =====================================================================
108 /*
109  \fn SetMatriceElt
110  \param l : a line index
111  \param c : a colon index
112  \param a_val : a value to initialize the matrix element with
113  \brief set the matrix element corresponding to the argument indices with the provided value.
114  \return 0 if success, positive value otherwise
115 */
116 int oMatrix::SetMatriceElt(uint16_t l, uint16_t c, HPFLTNB a_val)
117 {
118  if(l>=m_lin || c>=m_col)
119  {
120  Cerr("***** oMatrix::SetMatriceElt()-> Nb of (lin,col) ("<<l+1<<","<<c+1<<") in parameters ");
121  Cerr("> to the number of (lin,col) of this matrix ("<<m_lin<<","<<m_col<<") !" << endl);
122  return 1;
123  }
124 
125  m2p_Mat[l][c] = a_val;
126 
127  return 0;
128 }
129 
130 
131 
132 // =====================================================================
133 // ---------------------------------------------------------------------
134 // ---------------------------------------------------------------------
135 // =====================================================================
143 HPFLTNB oMatrix::GetMatriceElt(uint16_t l,uint16_t c)
144 {
145  return m2p_Mat[l][c];
146 }
147 
148 
149 
150 // =====================================================================
151 // ---------------------------------------------------------------------
152 // ---------------------------------------------------------------------
153 // =====================================================================
154 /*
155  \fn Multiplication
156  \param ap_Mtx : input matrix to multiply to the matrix from which the function is called
157  \param ap_MtxResult : output matrix containing the result of the multiplication
158  \brief Multiply the member matrix with the matrix provided in 1st parameter
159  Return the result in the matric provided in 2nd parameter
160  \return 0 if success, positive value otherwise
161 */
162 int oMatrix::Multiplication(oMatrix *ap_Mtx, oMatrix *ap_MtxResult)
163 {
164  HPFLTNB sum=0;
165 
166  if ( m_col != ap_Mtx->m_lin )
167  {
168  Cerr("***** oMatrix::Multiplication()-> Not matching number of colons and lines of the two matrices !");
169  return 1;
170  }
171  else if (ap_MtxResult == NULL)
172  {
173  Cerr("***** oMatrix::Multiplication()-> The resulting matrix has not been allocated !");
174  return 1;
175  }
176  else
177  {
178  for ( uint16_t tl = 0; tl < m_lin; tl++ )
179  for ( uint16_t c = 0; c < ap_Mtx->m_col; c++ )
180  {
181  for ( uint16_t l = 0; l < ap_Mtx->m_lin; l++ )
182  {
183  sum += GetMatriceElt(tl,l) * ap_Mtx->GetMatriceElt(l,c);
184  }
185  ap_MtxResult->SetMatriceElt(tl,c,sum);
186  sum = 0;
187  }
188  }
189 
190  return 0;
191 }
192 
193 
194 
195 
196 // =====================================================================
197 // ---------------------------------------------------------------------
198 // ---------------------------------------------------------------------
199 // =====================================================================
200 /*
201  \fn int oMatrix::Transpose()
202  \param ap_MtxResult : output matrix containing the result of the transposition
203  \brief Transpose the elements of the matrix
204  \return 0 if success, positive value otherwise
205 */
206 int oMatrix::Transpose(oMatrix *ap_Mtx)
207 {
208  if ( this->m_col != ap_Mtx->m_lin
209  || this->m_lin != ap_Mtx->m_col )
210  {
211  Cerr("***** oMatrix::Transpose()-> Not matching number of colons <-> lines between the input and transpose matrices !");
212  return 1;
213  }
214  if (ap_Mtx == NULL)
215  {
216  Cerr("***** oMatrix::Transpose()-> The resulting matrix has not been allocated !");
217  return 1;
218  }
219 
220  uint16_t lsize = m_lin>m_col ? m_lin : m_col;
221 
222  for ( uint16_t l = 0; l < lsize; l++ )
223  for ( uint16_t c = l; c < lsize; c++ )
224  {
225  HPFLTNB tmp = 0.;
226 
227  if( l < m_lin
228  && c < m_col )
229  tmp = m2p_Mat[l][c];
230 
231  if(l < ap_Mtx->m_lin
232  && c < ap_Mtx->m_col
233  && l < m_col
234  && c < m_lin )
235  ap_Mtx->SetMatriceElt( l , c , m2p_Mat[c][l] );
236 
237  if(l < ap_Mtx->m_col
238  && c < ap_Mtx->m_lin
239  && l < m_lin
240  && c < m_col )
241  ap_Mtx->SetMatriceElt( c , l , tmp );
242  }
243 
244  return 0;
245 }
246 
247 
248 
249 
250 // =====================================================================
251 // ---------------------------------------------------------------------
252 // ---------------------------------------------------------------------
253 // =====================================================================
254 /*
255  \fn int oMatrix::Inverse()
256  \param ap_MtxResult : output matrix containing the inverse matrix
257  \brief Inverse the matrix on which the function is called
258  An error is returned if the matrix is not square,
259  or if there is a nil component on the diagonal
260  The resulting matrix object must be different than the input matrix
261  \return 0 if success, positive value otherwise
262 */
263 int oMatrix::Inverse(oMatrix *ap_Mtx)
264 {
265  // Check matching nb colons/lines
266  if ( (this->m_col != this->m_lin)
267  || (ap_Mtx->m_col != ap_Mtx->m_lin) )
268  {
269  Cerr("***** oMatrix::Inverse()-> Not matching number of colons <-> lines between the input and transpose matrices !");
270  return 1;
271  }
272  // Check if resulting matrix has been allocated
273  if (ap_Mtx == NULL)
274  {
275  Cerr("***** oMatrix::Inverse()-> The resulting matrix has not been allocated !");
276  return 1;
277  }
278  // Check if resulting matrix is the same as this matrix
279  // Throw error as the resulting matrix will overwrite the components of the input matrix in the process
280  if (this == ap_Mtx)
281  {
282  Cerr("***** oMatrix::Inverse()-> The resulting matrix has not been allocated !");
283  return 1;
284  }
285 
286  for ( uint16_t l = 0; l < m_lin; l++ )
287  for ( uint16_t c = 0; c < m_col; c++ )
288  {
289  if (m2p_Mat[l][c] == 0)
290  {
291  //Cerr("***** oMatrix::Inverse()-> One element on the diagonal is nil !");
292  return 1;
293  }
294  }
295 
296  oMatrix* p_tMtx = new oMatrix(m_lin, m_col);
297 
298 
299  // Init
300  for( uint16_t l=0 ; l<m_lin ; l++ )
301  for ( uint16_t c = 0; c < m_col; c++ )
302  {
303  p_tMtx->SetMatriceElt( l, c, 0. );
304  ap_Mtx->SetMatriceElt( l, c, m2p_Mat[l][c] );
305  }
306 
307  HPFLTNB** pMtx = ap_Mtx->GetMtx();
308 
309  for( uint16_t l=0 ; l<m_lin ; l++ )
310  {
311  for ( uint16_t c = 0; c < m_col; c++ )
312  {
313  p_tMtx->SetMatriceElt(l, l, 1./pMtx[l][l]);
314 
315  if(c != l)
316  p_tMtx->SetMatriceElt(l, c, -pMtx[l][c] / pMtx[l][l]);
317 
318  for( uint16_t r=0 ; r<m_lin ; r++ )
319  {
320  if(r!=l)
321  p_tMtx->SetMatriceElt(r, l, pMtx[r][l]/pMtx[l][l]);
322  if(c!=l && r!=l)
323  p_tMtx->SetMatriceElt(r, c, pMtx[r][c] - pMtx[l][c]*pMtx[r][l]/pMtx[l][l]);
324  }
325 
326  }
327 
328  for(int ll=0 ; ll<m_lin ; ll++)
329  for(int cc=0 ; cc<m_col ; cc++)
330  pMtx[ll][cc] = p_tMtx->GetMatriceElt(ll,cc) ;
331 
332  }
333 
334  delete p_tMtx;
335 
336  return 0;
337 }
338 
339 
340 // =====================================================================
341 // ---------------------------------------------------------------------
342 // ---------------------------------------------------------------------
343 // =====================================================================
344 /*
345  \fn int oMatrix::SetXRotMtx()
346  \param ang : angle in degree
347  \brief Set a (3,3) X-axis rotation matrix using the provided angle
348  \return 0 if sucess, positive value otherwise
349 */
351 {
352  if(m_lin !=3 || m_col != 3)
353  {
354  Cerr("***** oMatrix::SetXRotMtx()-> The matrix must be (3,3) in order to use this function !");
355  return 1;
356  }
357 
358  SetMatriceElt(0,0, 1 );
359  SetMatriceElt(0,1, 0 );
360  SetMatriceElt(0,2, 0 );
361  SetMatriceElt(1,0, 0 );
362  SetMatriceElt(1,1, cos(ang));
363  SetMatriceElt(1,2, -sin(ang));
364  SetMatriceElt(2,0, 0 );
365  SetMatriceElt(2,1, sin(ang));
366  SetMatriceElt(2,2, cos(ang)) ;
367 
368  return 0;
369 }
370 
371 
372 
373 
374 // =====================================================================
375 // ---------------------------------------------------------------------
376 // ---------------------------------------------------------------------
377 // =====================================================================
378 /*
379  \fn int oMatrix::SetYRotMtx()
380  \param ang : angle in degree
381  \brief Set a (3,3) Y-axis rotation matrix using the provided angle
382  \return 0 if sucess, positive value otherwise
383 */
385 {
386  if(m_lin !=3 || m_col != 3)
387  {
388  Cerr("***** oMatrix::SetYRotMtx()-> The matrix must be (3,3) in order to use this function !");
389  return 1;
390  }
391 
392  SetMatriceElt(0,0, cos(ang));
393  SetMatriceElt(0,1, 0 );
394  SetMatriceElt(0,2, sin(ang));
395  SetMatriceElt(1,0, 0 );
396  SetMatriceElt(1,1, 1 );
397  SetMatriceElt(1,2, 0 );
398  SetMatriceElt(2,0, -sin(ang));
399  SetMatriceElt(2,1, 0 );
400  SetMatriceElt(2,2, cos(ang));
401 
402  return 0;
403 }
404 
405 
406 
407 
408 // =====================================================================
409 // ---------------------------------------------------------------------
410 // ---------------------------------------------------------------------
411 // =====================================================================
412 /*
413  \fn int oMatrix::SetZRotMtx()
414  \param ang : angle in degree
415  \brief Set a (3,3) Z-axis rotation matrix using the provided angle
416  \return 0 if sucess, positive value otherwise
417 */
419 {
420  if(m_lin !=3 || m_col != 3)
421  {
422  Cerr("***** oMatrix::SetZRotMtx()-> The matrix must be (3,3) in order to use this function !");
423  return 1;
424  }
425 
426  SetMatriceElt(0,0, cos(ang) );
427  SetMatriceElt(0,1, -sin(ang) );
428  SetMatriceElt(0,2, 0);
429  SetMatriceElt(1,0, sin(ang));
430  SetMatriceElt(1,1, cos(ang) );
431  SetMatriceElt(1,2, 0);
432  SetMatriceElt(2,0, 0);
433  SetMatriceElt(2,1, 0);
434  SetMatriceElt(2,2, 1);
435 
436  return 0;
437 }
438 
439 
440 
441 
442 // =====================================================================
443 // ---------------------------------------------------------------------
444 // ---------------------------------------------------------------------
445 // =====================================================================
446 /*
447  \fn int oMatrix::Describe()
448  \brief Display the element of the matrix
449 */
450 void oMatrix::Describe()
451 {
452  for ( uint16_t l = 0; l < m_lin; l++ )
453  {
454  for ( uint16_t c = 0; c < m_col; c++ )
455  cout << m2p_Mat[l][c] << " ; ";
456 
457  cout << endl;
458  }
459 }
int Inverse(oMatrix *ap_MtxResult)
#define Cerr(MESSAGE)
~oMatrix()
oMatrix destructor. Free memory of the oMatrix object.
oMatrix()
oMatrix constructor. Initialize the member variables to their default values.
HPFLTNB GetMatriceElt(uint16_t l, uint16_t c)
void Describe()
Display the element of the matrix.
Structure designed for basic matrices operations.
int SetXRotMtx(HPFLTNB ang)
int Multiplication(oMatrix *ap_Mtx, oMatrix *ap_MtxResult)
int SetMatriceElt(uint16_t l, uint16_t c, HPFLTNB a_val)
#define Cout(MESSAGE)
int SetZRotMtx(HPFLTNB ang)
int SetYRotMtx(HPFLTNB ang)
int Transpose(oMatrix *a_MtxResult)
void Allocate(uint16_t nl, uint16_t nc)