Orfeo Toolbox  3.16
itkFEMLinearSystemWrapper.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFEMLinearSystemWrapper.cxx,v $
5  Language: C++
6  Date: $Date: 2009-01-29 21:55:14 $
7  Version: $Revision: 1.19 $
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 =========================================================================*/
17 
18 // disable debug warnings in MS compiler
19 #ifdef _MSC_VER
20 #pragma warning(disable: 4786)
21 #endif
22 
24 #include <vector>
25 
26 
27 namespace itk {
28 namespace fem {
29 
30 
32 {
33  unsigned int i;
34 
35  // FIXME: Does not work properly for all derived classes
36 
37  // clear all data
38  for(i=0;i<m_NumberOfMatrices;i++)
39  {
40  this->DestroyMatrix(i);
41  }
42  for(i=0;i<m_NumberOfVectors;i++)
43  {
44  this->DestroyVector(i);
45  }
46  for(i=0;i<m_NumberOfSolutions;i++)
47  {
48  this->DestroySolution(i);
49  }
50 
51  this->SetSystemOrder(0);
52 
53 }
54 
55 
56 void LinearSystemWrapper::ScaleMatrix(Float scale, unsigned int matrixIndex)
57 {
58  /* FIX ME: error checking */
59 
60  /* check for no scaling */
61  if (scale == 1.0)
62  {
63  return;
64  }
65 
66  unsigned int i;
67  unsigned int j;
68  for (i=0; i<m_Order; i++)
69  {
70  for (j=0; j<m_Order; j++)
71  {
72  this->SetMatrixValue(i, j, scale*GetMatrixValue(i,j,matrixIndex), matrixIndex);
73  }
74  }
75 
76  return;
77 }
78 
79 void LinearSystemWrapper::ScaleVector(Float scale, unsigned int vectorIndex)
80 {
81  /* FIX ME: error checking */
82 
83  /* check for no scaling */
84  if (scale == 1.0)
85  {
86  return;
87  }
88 
89  unsigned int i;
90  for (i=0; i<m_Order; i++)
91  {
92  this->SetVectorValue(i, scale * GetVectorValue(i, vectorIndex), vectorIndex);
93  }
94 
95  return;
96 }
97 
98 void LinearSystemWrapper::ScaleSolution(Float scale, unsigned int solutionIndex)
99 {
100  /* FIX ME: error checking */
101 
102  /* check for no scaling */
103  if (scale == 1.0)
104  {
105 
106  return;
107  }
108 
109  unsigned int i;
110  for (i=0; i<m_Order; i++)
111  {
112  this->SetSolutionValue(i, scale * GetSolutionValue(i, solutionIndex), solutionIndex);
113  }
114 
115  return;
116 }
117 
118 void LinearSystemWrapper::AddVectorValue(unsigned int i, Float value, unsigned int vectorIndex)
119 {
120  this->SetVectorValue(i, value+this->GetVectorValue(i, vectorIndex), vectorIndex);
121 }
122 
123 void LinearSystemWrapper::AddMatrixValue(unsigned int i, unsigned int j, Float value, unsigned int matrixIndex)
124 {
125  this->SetMatrixValue(i, j, value+this->GetMatrixValue(i, j, matrixIndex), matrixIndex);
126 }
127 
128 void LinearSystemWrapper::AddSolutionValue(unsigned int i, Float value, unsigned int solutionIndex)
129 {
130  this->SetSolutionValue(i, value+this->GetSolutionValue(i, solutionIndex), solutionIndex);
131 }
132 
133 
134 void LinearSystemWrapper::MultiplyMatrixVector(unsigned int resultVector, unsigned int matrixIndex, unsigned int vectorIndex)
135 {
136  /* FIX ME: error checking */
137 
138  unsigned int i;
139  unsigned int j;
140 
141  this->InitializeVector(resultVector);
142 
143  /* perform multiply */
144  for (i=0; i<m_Order; i++)
145  {
146  for (j=0; j<m_Order; j++)
147  {
148  this->AddVectorValue(i, this->GetMatrixValue(i,j,matrixIndex) * this->GetVectorValue(j, vectorIndex), resultVector);
149  }
150  }
151 
152 }
153 
154 
156 {
157  // By default we assume full matrices and return indices of all columns
158  cols=ColumnArray(m_Order);
159  for(unsigned int i=0;i<m_Order;i++)
160  {
161  cols[i]=i;
162  }
163 }
164 
165 
166 void LinearSystemWrapper::OptimizeMatrixStorage(unsigned int matrixIndex, unsigned int tempMatrixIndex)
167 {
168 
169  /* put original matrix in temp space */
170  this->SwapMatrices(matrixIndex, tempMatrixIndex);
171 
172  /* re-initialze storage */
173  this->InitializeMatrix(matrixIndex);
174 
175  /* loop through old matrix and pull out non-zero values */
176  ColumnArray currentRow;
177  unsigned int i;
178  unsigned int j;
179  for (i=0; i<this->m_Order; i++)
180  {
181  this->GetColumnsOfNonZeroMatrixElementsInRow(i, currentRow, tempMatrixIndex);
182  for (j=0; j<currentRow.size(); j++)
183  {
184  this->SetMatrixValue(i,currentRow[j],this->GetMatrixValue(i, currentRow[j], tempMatrixIndex), matrixIndex);
185  }
186  }
187 
188  /* destroy temp matrix space */
189  this->DestroyMatrix(tempMatrixIndex);
190 
191 }
192 
193 void
195 ::CopyMatrix(unsigned int matrixIndex1, unsigned int matrixIndex2)
196 {
197  ColumnArray cols;
198  unsigned int r;
199 
200  this->InitializeMatrix(matrixIndex2);
201 
202  for (r=0; r<this->m_Order; r++)
203  {
204  this->GetColumnsOfNonZeroMatrixElementsInRow(r, cols, matrixIndex1);
205  for(LinearSystemWrapper::ColumnArray::iterator c=cols.begin(); c != cols.end(); c++)
206  {
207  this->SetMatrixValue(r,*c,this->GetMatrixValue(r, *c, matrixIndex1), matrixIndex2);
208  }
209  }
210 }
211 
212 void
214 ::AddMatrixMatrix(unsigned int matrixIndex1, unsigned int matrixIndex2)
215 {
216  ColumnArray cols;
217  unsigned int r;
218 
219  for (r=0; r<this->m_Order; r++)
220  {
221  this->GetColumnsOfNonZeroMatrixElementsInRow(r, cols, matrixIndex2);
222  for(LinearSystemWrapper::ColumnArray::iterator c=cols.begin(); c != cols.end(); c++)
223  {
224  this->AddMatrixValue(r,*c,this->GetMatrixValue(r, *c, matrixIndex2), matrixIndex1);
225  }
226  }
227 }
228 
229 void
231 ::CopyVector(unsigned int vectorSource, unsigned int vectorDestination)
232 {
233  unsigned int r;
234  for (r=0; r<this->m_Order; r++)
235  {
236  this->SetVectorValue(r,this->GetVectorValue(r, vectorSource), vectorDestination);
237  }
238 }
239 
240 void
242 ::AddVectorVector(unsigned int vectorIndex1, unsigned int vectorIndex2)
243 {
244  unsigned int r;
245  for (r=0; r<this->m_Order; r++)
246  {
247  this->AddVectorValue(r,this->GetVectorValue(r, vectorIndex2), vectorIndex1);
248  }
249 }
250 
251 /* FIXME - untested...do not use yet */
252 void LinearSystemWrapper::ReverseCuthillMckeeOrdering(ColumnArray& newNumbering, unsigned int matrixIndex)
253 {
254 
255  /* find cuthill-mckee ordering */
256  this->CuthillMckeeOrdering(newNumbering, -1, matrixIndex);
257 
258 }
259 
260 
261 void LinearSystemWrapper::CuthillMckeeOrdering(ColumnArray& newNumbering, int startingRow, unsigned int matrixIndex)
262 {
263 
264 
265  ColumnArray reverseMapping; /* temp storage for re-mapping of rows */
266  newNumbering = ColumnArray(this->m_Order); /* new row numbering */
267  reverseMapping = ColumnArray (this->m_Order); /* allocate temp storage */
268  unsigned int i; /* loop counter */
269 
270  /* find degrees of each row in matrix & initialize newNumbering vector */
271  ColumnArray currentRow; /* column indices of nonzero in current row */
272  ColumnArray rowDegree(this->m_Order); /* degrees in each row */
273 
274  /* initialize variables */
275  for (i=0; i<this->m_Order; i++)
276  {
277  this->GetColumnsOfNonZeroMatrixElementsInRow(i, currentRow, matrixIndex);
278  rowDegree[i] = static_cast<unsigned int>( currentRow.size() - 1 ); /* assuming non-zero diagonal */
279  reverseMapping[i] = this->m_Order; /* set to impossible value */
280  }
281 
282  /* choose starting row if not given - chooses row of lowest degree */
283  if (startingRow < 0)
284  {
285  unsigned int lowestDegree = rowDegree[0];
286  startingRow = 0;
287  for (i=1; i<this->m_Order; i++)
288  {
289  if (rowDegree[i] < lowestDegree)
290  {
291  startingRow = i;
292  lowestDegree = rowDegree[i];
293  }
294  }
295  }
296 
297  /* set first row */
298  unsigned int nextRowNumber = 0;
299  reverseMapping[startingRow] = nextRowNumber++;
300 
301  /* follow connections and assign new row numbering */
302  this->FollowConnectionsCuthillMckeeOrdering(startingRow, rowDegree, reverseMapping, nextRowNumber, matrixIndex);
303 
304  for (i=0; i<this->m_Order; i++)
305  {
306  newNumbering[ reverseMapping[i] ] = i;
307  }
308 
309 }
310 
311 
312 void LinearSystemWrapper::FollowConnectionsCuthillMckeeOrdering(unsigned int rowNumber, ColumnArray& rowDegree, ColumnArray& reverseMapping, unsigned int nextRowNumber, unsigned int matrixIndex)
313 {
314 
315  int i; // these must be signed ints since they are compared to size()-1
316  int j;
317  int k;
318  unsigned int temp;
319  ColumnArray::iterator rowBufferIt;
320  ColumnArray::iterator nextRowsIt;
321  ColumnArray bufferArray;
322  ColumnArray rowBuffer;
323 
324  if (reverseMapping[rowNumber] > (this->m_Order-1) )
325  {
326  return;
327  }
328 
329  /* temp vector of next rows to examine */
330  ColumnArray nextRows;
331  this->GetColumnsOfNonZeroMatrixElementsInRow(rowNumber, nextRows, matrixIndex);
332 
333  /* remove diagonal element */
334  for (nextRowsIt = nextRows.begin(); nextRowsIt != nextRows.end(); ++nextRowsIt)
335  {
336  if ( *nextRowsIt == rowNumber )
337  {
338  nextRows.erase(nextRowsIt);
339  --nextRowsIt;
340  }
341  }
342 
343  /* order by degree */
344  if (nextRows.size() > 1)
345  {
346  for( i=0; i < (int)(nextRows.size()) - 1; i++ )
347  {
348  for( j=0; j < (int)(nextRows.size()) - 1 - i; j++ )
349  {
350  if ( rowDegree[nextRows[j+1]] < rowDegree[nextRows[j]] )
351  {
352  temp = nextRows[j+1];
353  nextRows[j+1] = nextRows[j];
354  nextRows[j] = temp;
355  }
356  }
357  }
358  }
359 
360  /* while there are more rows to examine */
361  while ( (nextRows.size() != 0 ) && (nextRowNumber < this->m_Order) )
362  {
363 
364 
365  bufferArray.clear();
366 
367  for (i=0; i<(int)(nextRows.size()); i++)
368  {
369  reverseMapping[ nextRows[i] ] = nextRowNumber++;
370  }
371 
372 
373  /* renumber rows in nextRows */
374  for (i=0; i<(int)(nextRows.size()); i++)
375  {
376 
377  /* connections of current row */
378  this->GetColumnsOfNonZeroMatrixElementsInRow( nextRows[i], rowBuffer, matrixIndex );
379 
380  /* remove previously renumbered rows */
381  for (rowBufferIt = rowBuffer.begin(); rowBufferIt != rowBuffer.end(); ++rowBufferIt)
382  {
383  if (reverseMapping[*rowBufferIt] < this->m_Order )
384  {
385  rowBuffer.erase(rowBufferIt);
386  --rowBufferIt;
387  }
388  }
389 
390  /* order by degree */
391  if (rowBuffer.size() > 1)
392  {
393  for( k=0; k < (int)(rowBuffer.size()) - 1; k++)
394  {
395  for( j=0; j < (int)(rowBuffer.size()) - 1-k; j++)
396  {
397  if ( rowDegree[rowBuffer[j+1]] < rowDegree[rowBuffer[j]] )
398  {
399  temp = rowBuffer[j+1];
400  rowBuffer[j+1] = rowBuffer[j];
401  rowBuffer[j] = temp;
402  }
403  }
404  }
405  }
406 
407  /* add rows in rowBuffer to bufferArray (don't add repeats) */
408  unsigned int repeatFlag;
409  for( k=0; k < (int)(rowBuffer.size()); k++)
410  {
411  repeatFlag = 0;
412  for( j=0; j < (int)(bufferArray.size()); j++)
413  {
414  if (bufferArray[j] == rowBuffer[k])
415  {
416  repeatFlag = 1;
417  }
418  }
419 
420  if (!repeatFlag)
421  {
422  bufferArray.push_back(rowBuffer[k]);
423  }
424  }
425 
426  }
427 
428  nextRows.clear();
429  nextRows = bufferArray;
430 
431 
432  }
433 
434  return;
435 
436 
437 }
438 
439 
440 FEMExceptionLinearSystem::FEMExceptionLinearSystem(const char *file, unsigned int lineNumber, std::string location, std::string moreDescription) :
441  FEMException(file,lineNumber)
442 {
443  SetDescription("Error in linear system: "+moreDescription);
444  SetLocation(location);
445 }
446 
447 
448 FEMExceptionLinearSystemBounds::FEMExceptionLinearSystemBounds(const char *file, unsigned int lineNumber, std::string, std::string moreDescription, unsigned int index1) :
449  FEMException(file,lineNumber)
450 {
451  OStringStream buf;
452  buf << "Index of " << moreDescription << " out of bounds (" << index1 << ")";
453  SetDescription(buf.str().c_str());
454 
455 }
456 
457 
458 FEMExceptionLinearSystemBounds::FEMExceptionLinearSystemBounds(const char *file, unsigned int lineNumber, std::string, std::string, unsigned int index1, unsigned int index2) :
459  FEMException(file,lineNumber)
460 {
461  OStringStream buf;
462  buf << "Index out of bounds (" << index1 << "," << index2 << ")";
463  SetDescription(buf.str().c_str());
464 
465 }
466 
467 }}

Generated at Sat Jun 15 2013 23:37:52 for Orfeo Toolbox with doxygen 1.8.3.1