Orfeo Toolbox  3.16
itkFEMItpackSparseMatrix.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFEMItpackSparseMatrix.cxx,v $
5  Language: C++
6  Date: $Date: 2009-01-29 21:28:16 $
7  Version: $Revision: 1.15 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
18 #include "itpack.h"
19 
20 namespace itk {
21 namespace fem {
22 
23 
25 {
28  m_NZ = 0;
29  m_N = 0;
30  /* m_IER = 0; */ /* initialize */
31  m_MODE = 1; /* add to existing entries when building matrix */
32  m_LEVEL = -1; /* no error messages */
33  m_NOUT = 0; /* output unit number */
34 
35  m_IA = 0;
36  m_JA = 0;
37  m_IWORK = 0;
38  m_A = 0;
39 }
40 
42 {
45  m_NZ = 0;
46  m_N = order;
47  /* m_IER = 0; */ /* initialize */
48  m_MODE = 1; /* add to existing entries when building matrix */
49  m_LEVEL = -1; /* no error messages */
50  m_NOUT = 0; /* output unit number */
51 
52  m_IA = 0;
53  m_JA = 0;
54  m_IWORK = 0;
55  m_A = 0;
56 }
57 
58 
60 {
63  m_N = order;
64  m_NZ = maxNonZeroValues;
65  /* m_IER = 0; */ /* initialize */
66  m_MODE = 1; /* add to existing entries when building matrix */
67  m_LEVEL = -1; /* no error messages */
68  m_NOUT = 0; /* output unit number */
69 
70  m_IA = 0;
71  m_JA = 0;
72  m_IWORK = 0;
73  m_A = 0;
74 
75 }
76 
77 
79 {
80 
81  /* is matrix ready for initialization */
82  if ( (m_N <= 0) || (m_NZ <= 0) )
83  {
84  /* FIX ME: error handling */
85  throw FEMException(__FILE__, __LINE__, "ItpackSparseMatrix::Initialize");
86  }
87 
88  /* initialize itpack variables */
89  if (m_IA != 0)
90  {
91  delete [] m_IA;
92  }
93  if (m_JA != 0)
94  {
95  delete [] m_JA;
96  }
97  if (m_IWORK != 0)
98  {
99  delete [] m_IWORK;
100  }
101  if (m_A != 0)
102  {
103  delete [] m_A;
104  }
105  m_IA = new integer [ m_N + 1 ];
106  m_JA = new integer [ m_NZ ];
107  m_IWORK = new integer [ m_NZ ];
108  m_A = new doublereal [ m_NZ ];
109 
110  int i;
111  for (i=0; i<m_NZ; i++)
112  {
113  m_JA[i] = 0;
114  m_IWORK[i] = 0;
115  m_A[i] = 0.0;
116  }
117  for (i=0; i<=m_N; i++)
118  {
119  m_IA[i] = 0;
120  }
121 
122  /* initialize sparse matrix storage via itpack routine */
123  sbini_( &m_N, &m_NZ, m_IA, m_JA, m_A, m_IWORK );
124 
125  /* set info flags */
127  m_MatrixFinalized = 0;
128 
129  /* Do this to avoid itpack ignorance (unless it's somehow my ignorance) */
130  for (i=0; i<m_N; i++)
131  {
132  this->Set(i,i,0.0);
133  }
134 
135  return;
136 }
137 
139 {
140 
141  /* free variables */
142  if (m_IA != 0)
143  {
144  delete [] m_IA;
145  }
146  if (m_JA != 0)
147  {
148  delete [] m_JA;
149  }
150  if (m_IWORK != 0)
151  {
152  delete [] m_IWORK;
153  }
154  if (m_A != 0)
155  {
156  delete [] m_A;
157  }
158 
159  m_MatrixFinalized = 0;
161  m_N = 0;
162  m_NZ = 0;
163  /* m_IER = 0; */
164  m_MODE = 1;
165  m_LEVEL = -1;
166  m_NOUT = 0;
167 
168  m_IA = 0;
169  m_JA = 0;
170  m_IWORK = 0;
171  m_A = 0;
172 }
173 
175 {
176 
177  /* check */
178  if ( (m_MatrixFinalized != 0) || (m_MatrixInitialized == 0) )
179  {
180  throw FEMException(__FILE__, __LINE__, "ItpackSparseMatrix::Finalize");
181  }
182 
183  //std::cout << "sbend_ ... " << std::endl;
184  //this->PrintCompressedRow();
185 
186  /* finalize */
187  sbend_( &m_N, &m_NZ, m_IA, m_JA, m_A, m_IWORK );
188 
189  //this->PrintCompressedRow();
190  //std::cout << "sbend_ " << m_IER << std::endl;
191 
192  /* set info flag */
193  m_MatrixFinalized = 1;
194 
195  return;
196 }
197 
198 
200 {
201 
202  /* check if this op makes sense*/
203  if ( (m_MatrixFinalized == 0) || (m_MatrixInitialized == 0) )
204  {
205  throw FEMException(__FILE__, __LINE__, "ItpackSparseMatrix::UnFinalize");
206  }
207 
208  integer IER = 0;
209 
210  sbagn_(&m_N, &m_NZ, m_IA, m_JA, m_A, m_IWORK, &m_LEVEL, &m_NOUT, &IER);
211 
212  if (IER > 0)
213  {
214  throw FEMExceptionItpackSparseMatrixSbagn(__FILE__, __LINE__, "ItpackSparseMatrix::UnFinalize", IER);
215  }
216 
217  /* set info flag */
218  m_MatrixFinalized = 0;
219 
220  return;
221 }
222 
223 
225 {
226 
227  /* check for dynamic form */
228  if (m_MatrixInitialized == 0)
229  {
230 
231  /* initialize if prepared */
232  if ( (m_N <= 0) || (m_NZ <= 0) )
233  {
234  throw FEMException(__FILE__, __LINE__, "ItpackSparseMatrix::Set");
235  }
236  else
237  {
238  this->Initialize();
239  }
240  }
241 
242  if (m_MatrixFinalized == 1)
243  {
244  this->UnFinalize();
245  }
246 
247  /* replace an existing value */
248  m_MODE = 0;
249 
250  /* add entry (itpack expects 1-based indices */
251  integer IER;
252  integer fortranI = i+1;
253  integer fortranJ = j+1;
254  sbsij_(&m_N, &m_NZ, m_IA, m_JA, m_A, m_IWORK, &fortranI, &fortranJ, &value, &m_MODE, &m_LEVEL, &m_NOUT, &IER);
255 
256  if (IER > 700)
257  {
258  throw FEMExceptionItpackSparseMatrixSbsij(__FILE__, __LINE__, "ItpackSparseMatrix::Set", IER);
259  }
260 
261 
262  return;
263 }
264 
265 
267 {
268 
269  /* ignore add zero */
270  if (value == 0.0)
271  {
272  return;
273  }
274 
275  /* check for dynamic form */
276  if (m_MatrixInitialized == 0)
277  {
278 
279  /* initialize if prepared */
280  if ( (m_N <= 0) || (m_NZ <= 0) )
281  {
282  throw FEMException(__FILE__, __LINE__, "ItpackSparseMatrix::Add");
283  }
284  else
285  {
286  this->Initialize();
287  }
288  }
289  if (m_MatrixFinalized != 0)
290  {
291  this->UnFinalize();
292  }
293 
294  /* add to an existing value */
295  m_MODE = 1;
296 
297  /* add entry (itpack expects 1-based indices */
298  integer IER;
299  integer fortranI = i+1;
300  integer fortranJ = j+1;
301  sbsij_(&m_N, &m_NZ, m_IA, m_JA, m_A, m_IWORK, &fortranI, &fortranJ, &value, &m_MODE, &m_LEVEL, &m_NOUT, &IER);
302 
303  if (IER > 700)
304  {
305  throw FEMExceptionItpackSparseMatrixSbsij(__FILE__, __LINE__, "ItpackSparseMatrix::Set", IER);
306  }
307 
308  return;
309 }
310 
312 {
313 
314  doublereal returnValue = 0.0; /* set to default return value */
315  integer fortranJ = j+1;
316  integer lower;
317  integer upper;
318 
319  /* check for readiness */
320  if (m_MatrixInitialized != 0)
321  {
322 
323  /* ensure matrix is in readable form */
324  if (m_MatrixFinalized == 0)
325  {
326  this->Finalize();
327  }
328 
329  /* get search bounds in appropriate row */
330  lower = m_IA[i]-1;
331  upper = m_IA[i+1]-1;
332 
333  /* Find value if it exists */
334  for (int k=lower; k<upper; k++)
335  {
336  if (m_JA[k] == fortranJ)
337  {
338  returnValue = m_A[k];
339  }
340  }
341  }
342 
343  return returnValue;
344 }
345 
346 
348 {
349  if (m_MatrixInitialized == 0) return 0;
350  if (m_MatrixFinalized == 0) Finalize();
351 
352  return m_A;
353 }
354 
355 
357 {
358  if (m_MatrixInitialized == 0) return 0;
359  if (m_MatrixFinalized == 0) Finalize();
360 
361  return m_IA;
362 }
363 
364 
366 {
367  if (m_MatrixInitialized == 0) return 0;
368  if (m_MatrixFinalized == 0) Finalize();
369 
370  return m_JA;
371 }
372 
373 
375 {
376 
377  /* finalize matrix */
378  if (m_MatrixFinalized == 0)
379  {
380  this->Finalize();
381  }
382 
383  /* loop and temp variables */
384  int lower;
385  int upper;
386  int i;
387  int j;
388 
389  /* prepare result vector */
390  //delete [] result;
391  //result = new doublereal [ m_N ];
392  for (i=0; i<m_N; i++)
393  {
394  result[i] = 0.0;
395  }
396 
397  /* perform the mult operation */
398  for (i=0; i<m_N; i++)
399  {
400 
401  lower = m_IA[i]-1;
402  upper = m_IA[i+1]-1;
403 
404  for (j=lower; j<upper; j++)
405  {
406  result[i] += m_A[j] * vector[ m_JA[j] - 1 ];
407  }
408  }
409 
410  return;
411 }
412 
413 
415 {
416 
417  /* ensure appropriate matrix sizes */
418  if (m_N != rightMatrix->GetOrder())
419  {
420  return;
421  }
422 
423  /* finalize matrix */
424  if (m_MatrixFinalized == 0)
425  {
426  this->Finalize();
427  }
428 
429 
430  /* loop and temp variables */
431  int lower; /* lower bounds for column indices vector */
432  int upper; /* upper bounds for column indices vector */
433  int i; /* loop over rows */
434  int j; /* loop over columns */
435  int k; /* iterate through row */
436  doublereal summed; /* temp holder for row.column */
437 
438  /* perform the mult operation */
439  for (i=0; i<m_N; i++)
440  {
441  for (j=0; j<m_N; j++)
442  {
443 
444  /* bounds of values located in current row */
445  lower = m_IA[i]-1;
446  upper = m_IA[i+1]-1;
447 
448  // sum up row*column elements
449  summed = 0.0;
450  for (k=lower; k<upper; k++)
451  {
452  summed += m_A[k] * rightMatrix->Get( m_JA[k]-1, j );
453  }
454 
455  // insert sum to result matrix
456  if (summed != 0.0)
457  {
458  resultMatrix->Set(i,j,summed);
459  }
460 
461  }
462  }
463 
464 }
465 
466 
468 {
469  m_IA = ia;
470  m_JA = ja;
471  m_A = a;
472  m_MatrixFinalized = 1;
474 }
475 
476 
478 {
479  delete [] m_IA;
480  delete [] m_JA;
481  delete [] m_A;
482  delete [] m_IWORK;
483 }
484 
485 
486 FEMExceptionItpackSparseMatrixSbagn::FEMExceptionItpackSparseMatrixSbagn(const char *file, unsigned int lineNumber, std::string location, integer errorCode) :
487  FEMException(file,lineNumber)
488 {
489  std::string solverError;
490 
491  if (errorCode == 703)
492  {
493  solverError = "maximumNumberOfNonZeroValuesInMatrix is too small";
494  }
495  else
496  {
497  solverError = "Unknown error code returned";
498  }
499 
500  OStringStream buf;
501  buf << "Error: " << solverError;
502 
503  SetDescription(buf.str().c_str());
504 
505  SetLocation(location);
506 }
507 
508 FEMExceptionItpackSparseMatrixSbsij::FEMExceptionItpackSparseMatrixSbsij(const char *file, unsigned int lineNumber, std::string location, integer errorCode) :
509  FEMException(file,lineNumber)
510 {
511  std::string solverError;
512 
513  switch (errorCode)
514  {
515  case 701 :
516  solverError = "Improper index of matrix";
517  break;
518  case 702 :
519  solverError = "maximumNumberOfNonZeroValuesInMatrix is too small";
520  break;
521  default :
522  solverError = "Unknown error code returned";
523  }
524 
525  OStringStream buf;
526  buf << "Error: " << solverError;
527 
528  SetDescription(buf.str().c_str());
529 
530  SetLocation(location);
531 }
532 
533 
534 }} // end namespace itk::fem

Generated at Sat Feb 2 2013 23:36:46 for Orfeo Toolbox with doxygen 1.8.1.1