ML 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.
20#include "mlLinearAlgebraDefs.h"
21
23#include <sstream>
24
25// All declarations of this header will be in the ML_LA_NAMESPACE namespace.
26ML_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
127ML_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:823
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.