MeVisLab Toolbox Reference
mlLinearAlgebraTools.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2007, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_LINEAR_ALGEBRA_TOOLS_H
14 #define ML_LINEAR_ALGEBRA_TOOLS_H
15 
17 
18 // Include system independent file and project settings.
19 #include "mlLinearAlgebraSystem.h"
20 #include "mlLinearAlgebraDefs.h"
21 
22 #include <mlPrintTemplateErrors.h>
23 #include <sstream>
24 
25 // All declarations of this header will be in the ML_LA_NAMESPACE namespace.
26 ML_LA_START_NAMESPACE
27 
28  //-------------------------------------------------------------------
31  //-------------------------------------------------------------------
32  template <class OBJ_TYPE>
33  void MLSwap(OBJ_TYPE &obj1, OBJ_TYPE &obj2)
34  {
35  OBJ_TYPE buf = obj1;
36  obj1 = obj2;
37  obj2 = buf;
38  }
39 
40  //-------------------------------------------------------------------
58  //-------------------------------------------------------------------
59  template <class BASE_TYPE>
60  BASE_TYPE MLInverseMatHelper(const BASE_TYPE &origMat,
61  bool *isInvertible,
62  const typename BASE_TYPE::ComponentType /*ZeroEpsilon*/,
63  const char * const ZeroDetErrString,
64  const BASE_TYPE &Identity,
65  const size_t Dim
66  )
67  {
68  BASE_TYPE a(origMat); // As a evolves from original mat into identity
69  BASE_TYPE b(Identity); // b evolves from identity into inverse(a)
70  size_t i=0, j=0, i1=0; // Index counters.
71 
72  // Loop over columns of a from left to right, eliminating above and below diagonal
73  for (j=0; j<Dim; j++){
74  // Find largest pivot in column j among rows j..DIM-1
75  i1 = j; // Row with largest pivot candidate
76  for (i=j+1; i<Dim; i++){
77  if (MLAbs(a[i][j]) > MLAbs(a[i1][j])){
78  i1 = i;
79  }
80  }
81  // Swap rows i1 and j in a and b to put pivot on diagonal
82  MLSwap(a[i1], a[j]);
83  MLSwap(b[i1], b[j]);
84 
85  // Scale row j to have a identity diagonal
86  const typename BASE_TYPE::ComponentType avjj = a[j][j];
87  if (MLValueIs0WOM(avjj)){
88  if (isInvertible == nullptr)
89  {
90  std::stringstream sstream;
91  sstream.precision(4);
92  sstream << "Returning identity, matrix was:" << std::endl;
93  for (size_t y = 0; y < Dim; ++y)
94  {
95  for (size_t x = 0; x < Dim; ++x)
96  {
97  sstream << std::fixed << origMat[x][y] << "\t";
98  }
99  sstream << std::endl;
100  }
101  printTemplateError(ZeroDetErrString, ML_BAD_PARAMETER, sstream.str().c_str());
102  }
103  else
104  {
105  *isInvertible = false;
106  }
107  return Identity;
108  }
109  b[j] /= avjj;
110  a[j] /= avjj;
111 
112  // Eliminate off-diagonal elements in col j of a,
113  // applying identical operations to b
114  for (i=0; i<Dim; i++){
115  if (i!=j){
116  b[i] -= a[i][j]*b[j];
117  a[i] -= a[i][j]*a[j];
118  }
119  }
120  }
121 
122  // Set state and return inverse.
123  if (isInvertible != nullptr){ *isInvertible = true; }
124  return b;
125  }
126 
127 ML_LA_END_NAMESPACE
128 
129 #endif // __mlLinearAlgebraTools_H
bool MLValueIs0WOM(MLint8 a)
Returns true if value is 0, otherwise false.
DT MLAbs(const DT val)
Defines templated MLAbs version to circumvent fabs ambiguities on different platforms.
#define ML_BAD_PARAMETER
A bad/invalid parameter (or even an inappropriate image) has been passed to a module or an algorithm;...
Definition: mlTypeDefs.h:925
void ML_UTILS_EXPORT printTemplateError(const char *location, MLErrorCode reason, const std::string_view &handling)
void MLSwap(OBJ_TYPE &obj1, OBJ_TYPE &obj2)
Swaps two objects obj1 and obj2.
BASE_TYPE MLInverseMatHelper(const BASE_TYPE &origMat, bool *isInvertible, const typename BASE_TYPE::ComponentType, const char *const ZeroDetErrString, const BASE_TYPE &Identity, const size_t Dim)
Computes an N dimensional inverse from given default parameters.