ANIMA  4.0
animaGaussianMCMCost.cxx
Go to the documentation of this file.
1 #include <animaGaussianMCMCost.h>
2 #include <cmath>
3 
4 #include <animaBaseTensorTools.h>
5 
6 namespace anima
7 {
8 
11 {
12  unsigned int numberOfParameters = parameters.GetSize();
13  unsigned int nbImages = m_Gradients.size();
14 
15  // Set MCM parameters
16  m_TestedParameters.resize(numberOfParameters);
17 
18  for (unsigned int i = 0;i < numberOfParameters;++i)
19  m_TestedParameters[i] = parameters[i];
20 
21  m_MCMStructure->SetParametersFromVector(m_TestedParameters);
22 
23  m_Residuals.SetSize(nbImages);
24  m_PredictedSignals.resize(nbImages);
25  m_SigmaSquare = 0.0;
26 
27  for (unsigned int i = 0;i < nbImages;++i)
28  {
31 
32  m_Residuals[i] = m_ObservedSignals[i] - m_PredictedSignals[i];
33  m_SigmaSquare += m_Residuals[i] * m_Residuals[i];
34  }
35 
36  m_SigmaSquare /= nbImages;
37 
38  if (m_SigmaSquare < 1.0e-4)
39  {
40  std::cerr << "Noise variance: " << m_SigmaSquare << std::endl;
41  itkExceptionMacro("Too low estimated noise variance.");
42  }
43 
44  return m_Residuals;
45 }
46 
48 {
49  // This is -2log(L) so that we only have to give one formula
50  double costValue = 0;
51  unsigned int nbImages = m_Residuals.size();
52 
53  if (m_MarginalEstimation)
54  costValue = -2.0 * std::log(std::tgamma(1.0 + nbImages / 2.0)) + nbImages * std::log(2.0 * M_PI) + (nbImages + 2.0) * (std::log(nbImages / 2.0) + std::log(m_SigmaSquare));
55  else
56  costValue = nbImages * (1.0 + std::log(2.0 * M_PI * m_SigmaSquare));
57 
58  return costValue;
59 }
60 
61 void
63 {
64  unsigned int nbParams = parameters.GetSize();
65  if (m_MarginalEstimation)
66  itkExceptionMacro("Marginal estimation does not boil down to a least square minimization problem.");
67 
68  if (nbParams == 0)
69  return;
70 
71  unsigned int nbValues = m_ObservedSignals.size();
72 
73  // Assume get derivative is called with the same parameters as GetValue just before
74  for (unsigned int i = 0;i < nbParams;++i)
75  {
76  if (m_TestedParameters[i] != parameters[i])
77  itkExceptionMacro("Get derivative not called with the same parameters as GetValue, suggestive of NaN...");
78  }
79 
80  derivative.SetSize(nbValues, nbParams);
81  derivative.Fill(0.0);
82 
83  std::vector<ListType> signalJacobians(nbValues);
84 
85  for (unsigned int i = 0;i < nbValues;++i)
86  {
87  signalJacobians[i] = m_MCMStructure->GetSignalJacobian(m_SmallDelta,m_BigDelta,
89 
90  for (unsigned int j = 0;j < nbParams;++j)
91  derivative.put(i,j,signalJacobians[i][j]);
92  }
93 }
94 
95 void
97 {
98  unsigned int nbParams = derivativeMatrix.columns();
99  unsigned int nbValues = derivativeMatrix.rows();
100 
101  derivative.set_size(nbParams);
102 
103  for (unsigned int j = 0;j < nbParams;++j)
104  {
105  double residualJacobianResidualProduct = 0;
106  for (unsigned int i = 0;i < nbValues;++i)
107  residualJacobianResidualProduct += derivativeMatrix(i,j) * m_Residuals[i];
108 
109  if (!m_MarginalEstimation)
110  derivative[j] = 2.0 * residualJacobianResidualProduct / m_SigmaSquare;
111  else
112  derivative[j] = 2.0 * (nbValues + 2.0) * residualJacobianResidualProduct / (nbValues * m_SigmaSquare);
113  }
114 }
115 
116 } // end namespace anima
itk::OptimizerParameters< double > ParametersType
std::vector< double > m_PredictedSignals
MCMPointer m_MCMStructure
double GetCurrentCostValue() ITK_OVERRIDE
For the current set of parameters, compute the cost function value, requires GetValues to be called f...
MeasureType GetValues(const ParametersType &parameters) ITK_OVERRIDE
Get residual values for a given set of parameters, returns a vector of residuals. ...
void GetCurrentDerivative(DerivativeMatrixType &derivativeMatrix, DerivativeType &derivative) ITK_OVERRIDE
Get cost function derivatives from a derivative matrix obtained from GetDerivativeMatrix.
void GetDerivativeMatrix(const ParametersType &parameters, DerivativeMatrixType &derivative) ITK_OVERRIDE
Get residual derivatives for a given set of parameters, returns a matrix of residuals derivatives...
ListType m_GradientStrengths
itk::Array2D< double > DerivativeMatrixType
itk::Array< double > MeasureType
std::vector< Vector3DType > m_Gradients
itk::Array< double > DerivativeType