11 template <
class TScalarType>
13 LogEuclideanTensorCalculator <TScalarType>
14 ::GetTensorLogarithm(
const vnl_matrix <TScalarType> &tensor, vnl_matrix <TScalarType> &log_tensor)
16 unsigned int tensDim = tensor.rows();
18 m_EigenAnalyzer.SetDimension(tensDim);
19 m_EigenAnalyzer.SetOrder(tensDim);
20 m_EigVals.set_size(tensDim);
21 m_EigVecs.set_size(tensDim,tensDim);
23 m_EigenAnalyzer.ComputeEigenValuesAndVectors(tensor,m_EigVals,m_EigVecs);
25 for (
unsigned int i = 0;i < tensDim;++i)
27 if (m_EigVals[i] <= 1.0e-16)
28 m_EigVals[i] = 1.0e-16;
30 m_EigVals[i] = std::log(m_EigVals[i]);
36 template <
class TScalarType>
39 ::GetTensorPower(
const vnl_matrix <TScalarType> &tensor, vnl_matrix <TScalarType> &outputTensor,
double powerValue)
41 unsigned int tensDim = tensor.rows();
43 m_EigenAnalyzer.SetDimension(tensDim);
44 m_EigenAnalyzer.SetOrder(tensDim);
45 m_EigVals.set_size(tensDim);
46 m_EigVecs.set_size(tensDim,tensDim);
48 m_EigenAnalyzer.ComputeEigenValuesAndVectors(tensor,m_EigVals,m_EigVecs);
50 for (
unsigned int i = 0;i < tensDim;++i)
52 if (m_EigVals[i] <= 1.0e-16)
53 m_EigVals[i] = 1.0e-16;
55 m_EigVals[i] = std::pow(m_EigVals[i],powerValue);
61 template <
class TScalarType>
64 ::GetTensorExponential(
const vnl_matrix <TScalarType> &log_tensor, vnl_matrix <TScalarType> &tensor)
66 unsigned int tensDim = log_tensor.rows();
68 m_EigenAnalyzer.SetDimension(tensDim);
69 m_EigenAnalyzer.SetOrder(tensDim);
70 m_EigVals.set_size(tensDim);
71 m_EigVecs.set_size(tensDim,tensDim);
73 m_EigenAnalyzer.ComputeEigenValuesAndVectors(tensor,m_EigVals,m_EigVecs);
75 for (
unsigned int i = 0;i < tensDim;++i)
76 m_EigVals[i] = std::exp(m_EigVals[i]);
81 template <
class T1,
class T2>
84 unsigned int vecDim,
bool scale)
86 unsigned int dim = tensor.rows();
88 vecDim = dim * (dim + 1) / 2;
90 double sqrt2 = sqrt(2.0);
91 if (vector.GetSize() != vecDim)
92 vector.SetSize(vecDim);
95 for (
unsigned int i = 0;i < dim;++i)
96 for (
unsigned int j = 0;j <= i;++j)
98 vector[pos] = tensor(i,j);
100 vector[pos] *= sqrt2;
105 template <
class T1,
class T2>
108 vnl_matrix <T2> &tensor,
unsigned int tensDim,
bool scale)
110 unsigned int vecDim = vector.GetSize();
113 tensDim = std::floor((std::sqrt((
double)(8 * vecDim + 1)) - 1) / 2.0);
115 double sqrt2 = std::sqrt(2.0);
116 tensor.set_size(tensDim,tensDim);
118 unsigned int pos = 0;
119 for (
unsigned int i = 0;i < tensDim;++i)
120 for (
unsigned int j = 0;j <= i;++j)
122 tensor(i,j) = vector[pos];
126 tensor(i,j) /= sqrt2;
128 tensor(j,i) = tensor(i,j);
137 typedef itk::SymmetricEigenAnalysis < vnl_matrix <T>, vnl_diag_matrix<T>, vnl_matrix <T> > EigenAnalysisType;
138 unsigned int tensDim = matrix.rows();
140 EigenAnalysisType eigen(tensDim);
141 vnl_matrix <T> eigVecs(tensDim,tensDim);
142 vnl_diag_matrix <T> eigVals(tensDim);
144 eigen.ComputeEigenValuesAndVectors(matrix,eigVals,eigVecs);
146 for (
unsigned int i = 0;i < tensDim;++i)
148 if (eigVals[i] <= 1.0e-16)
149 eigVals[i] = 1.0e-16;
155 template <
typename RealType>
158 vnl_matrix <RealType> &tmpMat)
160 unsigned int tensorDimension = 3;
161 tmpMat.set_size(tensorDimension, tensorDimension);
163 for (
unsigned int l = 0;l < tensorDimension;++l)
164 for (
unsigned int m = l;m < tensorDimension;++m)
167 for (
unsigned int n = 0;n < tensorDimension;++n)
168 tmpVal += jacobianMatrix(l,n)*jacobianMatrix(m,n);
170 tmpMat.put(l,m,tmpVal);
173 tmpMat.put(m,l,tmpVal);
176 itk::SymmetricEigenAnalysis < vnl_matrix <RealType>, vnl_diag_matrix<RealType>, vnl_matrix <RealType> > eigenComputer(tensorDimension);
177 vnl_matrix <RealType> eVec(tensorDimension,tensorDimension);
178 vnl_diag_matrix <RealType> eVals(tensorDimension);
180 eigenComputer.ComputeEigenValuesAndVectors(tmpMat, eVals, eVec);
182 for (
unsigned int i = 0;i < tensorDimension;++i)
183 eVals[i] = std::pow(eVals[i], -0.5);
187 rotationMatrix *= jacobianMatrix;
190 template <
typename RealType,
typename MatrixType>
193 MatrixType &eigenVectors)
195 const unsigned int tensorDimension = 3;
197 typedef vnl_vector_fixed <RealType,tensorDimension> VectorType;
198 VectorType transformedPrincipal;
199 VectorType transformedSecondary;
200 for (
unsigned int i = 0;i < tensorDimension;++i)
202 transformedPrincipal[i] = 0;
203 transformedSecondary[i] = 0;
204 for (
unsigned int j = 0;j < tensorDimension;++j)
206 double jacVal = jacobianMatrix.get(i,j);
207 transformedPrincipal[i] += jacVal * eigenVectors(2,j);
208 transformedSecondary[i] += jacVal * eigenVectors(1,j);
215 VectorType principalEigenVector;
216 for (
unsigned int i = 0;i < tensorDimension;++i)
217 principalEigenVector[i] = eigenVectors(2,i);
220 VectorType rotatedSecondary;
221 double dotProductTransformed = 0;
222 for (
unsigned int i = 0;i < tensorDimension;++i)
224 dotProductTransformed += transformedPrincipal[i] * transformedSecondary[i];
225 rotatedSecondary[i] = 0;
226 for (
unsigned int j = 0;j < tensorDimension;++j)
227 rotatedSecondary[i] += firstRotation(i,j) * eigenVectors(1,j);
230 VectorType projectedSecondary;
231 for (
unsigned int i = 0;i < tensorDimension;++i)
232 projectedSecondary[i] = transformedSecondary[i] - dotProductTransformed * transformedPrincipal[i];
237 rotationMatrix.set_size(tensorDimension,tensorDimension);
238 rotationMatrix.fill(0.0);
239 for (
unsigned int i = 0;i < tensorDimension;++i)
241 for (
unsigned int j = 0;j < tensorDimension;++j)
244 for (
unsigned int k = 0;k < tensorDimension;++k)
245 rotVal += secondRotation(i,k) * firstRotation(k,j);
247 rotationMatrix.put(i,j,rotVal);
252 template <
class T1,
class T2>
254 RecomposeTensor(vnl_diag_matrix <T1> &eigs, vnl_matrix <T1> &eigVecs, vnl_matrix <T2> &resMatrix)
256 unsigned int tensorDimension = eigs.size();
257 resMatrix.set_size(tensorDimension,tensorDimension);
259 for (
unsigned int i = 0;i < tensorDimension;++i)
261 for (
unsigned int j = i;j < tensorDimension;++j)
264 for (
unsigned int k = 0;k < tensorDimension;++k)
265 resVal += eigs[k] * eigVecs.get(k,i) * eigVecs.get(k,j);
267 resMatrix.put(i,j,resVal);
270 resMatrix.put(j,i,resVal);
275 template <
class T1,
class T2,
class T3>
278 for (
unsigned int i = 0;i < tensorDim;++i)
279 for (
unsigned int j = i;j < tensorDim;++j)
281 double rotatedValue = 0.0;
282 for (
unsigned int a = 0;a < tensorDim;++a)
283 for (
unsigned int b = a;b < tensorDim;++b)
285 double factor = rotationMatrix.get(b,i) * rotationMatrix.get(a,j);
287 factor += rotationMatrix.get(a,i) * rotationMatrix.get(b,j);
289 rotatedValue += tensor.get(a,b) * factor;
292 rotated_tensor.put(i,j,rotatedValue);
295 rotated_tensor.put(j,i,rotatedValue);
299 template <
class T1,
class T2>
300 void RotateSymmetricMatrix(vnl_matrix <T1> &tensor, vnl_matrix <T2> &rotationMatrix, vnl_matrix <T2> &rotated_tensor)
302 unsigned int tensorDim = tensor.rows();
303 rotated_tensor.set_size(tensorDim,tensorDim);
308 template <
class T1,
class T2,
unsigned int NDim>
310 itk::Matrix <T2,NDim,NDim> &rotated_tensor)
317 ovlScore(vnl_diag_matrix <T1> &eigsX, vnl_matrix <T1> &eigVecsX,
318 vnl_diag_matrix <T1> &eigsY, vnl_matrix <T1> &eigVecsY)
320 unsigned int sizeData = eigsX.size();
322 long double resVal = 0;
323 long double denomVal = 0;
325 for (
unsigned int i = 0;i < sizeData;++i)
327 long double dotProd = 0;
328 for (
unsigned int j = 0;j < sizeData;++j)
329 dotProd += eigVecsX.get(i,j)*eigVecsY.get(i,j);
331 resVal += dotProd * dotProd * eigsX[i] * eigsY[i];
332 denomVal += eigsX[i] * eigsY[i];
335 return resVal/denomVal;
double ovlScore(vnl_diag_matrix< T1 > &eigsX, vnl_matrix< T1 > &eigVecsX, vnl_diag_matrix< T1 > &eigsY, vnl_matrix< T1 > &eigVecsY)
itk::Matrix< double, 3, 3 > GetRotationMatrixFromVectors(const VectorType &first_direction, const VectorType &second_direction, const unsigned int dimension)
void ExtractRotationFromJacobianMatrix(vnl_matrix< RealType > &jacobianMatrix, vnl_matrix< RealType > &rotationMatrix, vnl_matrix< RealType > &tmpMat)
void GetVectorRepresentation(const vnl_matrix< T1 > &tensor, itk::VariableLengthVector< T2 > &vector, unsigned int vecDim=0, bool scale=false)
void RotateSymmetricMatrix(T1 &tensor, T2 &rotationMatrix, T3 &rotated_tensor, unsigned int tensorDim)
Rotates a symmetric matrix by performing R^T D R where R is a rotation matrix and D the symmetric mat...
void GetTensorFromVectorRepresentation(const itk::VariableLengthVector< T1 > &vector, vnl_matrix< T2 > &tensor, unsigned int tensDim=0, bool scale=false)
void RecomposeTensor(vnl_diag_matrix< T1 > &eigs, vnl_matrix< T1 > &eigVecs, vnl_matrix< T2 > &resMatrix)
Recompose tensor from values extracted using SymmetricEigenAnalysis (vnl_symmetric_eigensystem transp...
void Normalize(const VectorType &v, const unsigned int NDimension, VectorType &resVec)
void ProjectOnTensorSpace(const vnl_matrix< T > &matrix, vnl_matrix< T > &tensor)
void ExtractPPDRotationFromJacobianMatrix(vnl_matrix< RealType > &jacobianMatrix, vnl_matrix< RealType > &rotationMatrix, MatrixType &eigenVectors)