Tomato
OxModelT1Shmolli.hxx
Go to the documentation of this file.
1 
7 #ifndef Tomato_OXModelT1Shmolli_HXX
8 #define Tomato_OXModelT1Shmolli_HXX
9 
10 namespace Ox {
11 
12 
13  template< typename MeasureType >
14  MeasureType
16  ::calcModelValue(const MeasureType* parameters, MeasureType time){
17  MeasureType A = parameters[0];
18  MeasureType B = parameters[1];
19  MeasureType T1star = parameters[2];
20 
21  MeasureType calculated = 0;
22 
23  if (_preventUnderOverFlow){
24  if (fabs(T1star) <= (time*0.005 ))
25  calculated = A; //prevent underflow when (-mTI/A[2]) < (-500) -- div/0, e^-500 is 0.0000
26  else if (fabs(T1star) >= (time*500 ))
27  calculated = (A - B*exp((MeasureType)-500)); //prevent overflow
28  }
29 
30  // if the previous block has calculated someting
31  if (calculated != 0){
32  return calculated;
33  }
34 
35  // if the numbers are unreasonable
36  if (fabs(T1star) < std::numeric_limits<MeasureType>::min()){
37  return calculated;
38  }
39 
40  if (_expAbsCost) {
41  calculated = A - B * exp((MeasureType) -fabs( time / T1star ) );
42  } else {
43  calculated = A - B * exp((MeasureType) -time / T1star );
44  }
45 
46  return calculated;
47  }
48 
49  template< typename MeasureType >
50  void
52  ::calcLSResiduals(const MeasureType* parameters, MeasureType* residuals){
53 
54  //std::cout << "calcLSResiduals" << std::endl;
55  unsigned int nSamples = this->_nSamples;
56 
57  MeasureType A = parameters[0];
58  MeasureType B = parameters[1];
59  MeasureType T1star = parameters[2];
60 
61  for (unsigned int i = 0; i < nSamples; i++) {
62  MeasureType invTime = this->_InvTimes[i];
63  MeasureType measured = this->_Signal[i];
64  MeasureType calculated = 0;
65 
66  calculated = calcModelValue(parameters, invTime);
67 
68  residuals[i] = calculated - measured;
69  }
70  }
71 
72  template< typename MeasureType >
73  void
75  ::calcLSJacobian(const MeasureType* parameters, MeasureType* jacobian){
76  int nSamples = this->_nSamples;
77 
78  //MeasureType A = parameters[0];
79  MeasureType B = parameters[1];
80  MeasureType T1star = parameters[2];
81  MeasureType invTime, myexp;
82 
83  for (int i = 0; i < nSamples; i++) {
84  invTime = this->_InvTimes[i];
85  myexp = exp(-invTime/T1star);
86 
87  // calculated in matlab (syms A B T1 t), f=A-B*exp(-t./T1); diff(f,A), diff(f,B), diff(calcCostValue,T1)
88  jacobian[i*3+0] = 1.0;
89  jacobian[i*3+1] = -myexp;
90  jacobian[i*3+2] = -B*invTime*myexp/(T1star*T1star);
91  }
92  }
93 
94  template< typename MeasureType >
95  MeasureType
97  ::calcCostValue(const MeasureType* parameters){
98 
99  //std::cout << "calcCostValue" << std::endl;
100  int nSamples = this->_nSamples;
101 
102  calcLSResiduals(parameters, this->_Residuals);
103  MeasureType result = 0;
104 
105  if (_rootMedianSquareCost){
106  // residuals are nor residuals squared!!!
107  for (int i = 0; i < nSamples; ++i) {
108  this->_Residuals[i] = this->_Residuals[i] * this->_Residuals[i];
109  }
110  // residuals are nor residuals squared!!!
111  result = KWUtil::calcMedianArray(nSamples, this->_Residuals);
112  // residuals are nor residuals squared!!!
113 
114  } else {
115 
116  for (int i = 0; i < nSamples; ++i) {
117  result = result + this->_Residuals[i] * this->_Residuals[i];
118  }
119 
120  }
121 
123  if (_costHeuristic){
124  if(parameters[0] < 0. )
125  result -= parameters[0]; // A<0 negative Mz0 estimate
126  if(parameters[0] > parameters[1])
127  result += (parameters[0] - parameters[1]); // less than saturation: B<A, should be B=2*A ideally
128  if(parameters[1] > (4. * parameters[0]))
129  result += (parameters[1]-4. * parameters[0]); // inversion ratio very high, likely error or SFFP
130  if(parameters[2] < 0.)
131  result -= parameters[2]; // negative time constant
132  }
133 
134  return result;
135 
136 
137  }
138 
139  template< typename MeasureType >
140  void
142  ::calcCostDerivative(const MeasureType* parameters, MeasureType* derivative){
143  //std::cout << "calcCostDerivative" << std::endl;
144 
145  int nSamples = this->_nSamples;
146 
147  derivative[0] = 0;
148  derivative[1] = 0;
149  derivative[2] = 0;
150 
151  MeasureType measured, invTime, myexp;
152 
153  MeasureType A = parameters[0];
154  MeasureType B = parameters[1];
155  MeasureType T1star = parameters[2];
156 
157  // calculated in matlab (syms A B T1 t y), f=(A-B*exp(-t./T1)-y).^2; diff(f,A), diff(f,B), diff(calcCostValue,T1)
158  for (int i = 0; i < nSamples; ++i){
159  measured = this->getSignal()[i];
160  invTime = this->getInvTimes()[i];
161  myexp = exp(-invTime/T1star);
162 
163  derivative[0] = derivative[0] + A*2 - measured*2 - myexp*B*2;;
164  derivative[1] = derivative[1] + myexp*2*(measured - A + myexp*B);
165  derivative[2] = derivative[2] + (invTime*myexp*B*2*(measured - A + myexp*B))/(T1star*T1star);
166  }
167  }
168 
169 } //namespace Ox
170 
171 
172 #endif //Tomato_OXModelT1Shmolli_HXX
virtual MeasureType calcModelValue(const MeasureType *parameters, MeasureType time)
Definition: OxModelT1Shmolli.hxx:16
virtual void calcLSResiduals(const MeasureType *parameters, MeasureType *residuals)
Definition: OxModelT1Shmolli.hxx:52
virtual MeasureType calcCostValue(const MeasureType *parameters)
Definition: OxModelT1Shmolli.hxx:97
virtual void calcLSJacobian(const MeasureType *parameters, MeasureType *jacobian)
Definition: OxModelT1Shmolli.hxx:75
Definition: OxCalculator.h:19
virtual void calcCostDerivative(const MeasureType *parameters, MeasureType *derivative)
Definition: OxModelT1Shmolli.hxx:142