ANIMA  4.0
animaMatrixOperations.hxx
Go to the documentation of this file.
1 #pragma once
3 
6 #include <itkSymmetricEigenAnalysis.h>
7 
8 namespace anima
9 {
10 
11 template <class VectorType>
12 itk::Matrix <double,3,3>
13 GetRotationMatrixFromVectors(const VectorType &first_direction, const VectorType &second_direction, const unsigned int dimension)
14 {
15  vnl_matrix<double> tmpMatrix(dimension+1,dimension+1,0);
16  anima::pairingToQuaternion(first_direction,second_direction,tmpMatrix);
17  vnl_matrix<double> AMatrix = tmpMatrix.transpose()*tmpMatrix;
18 
19  // Needs two points, providing one on normal vector (cross product)
20  VectorType tmpVec;
21  tmpVec[0] = first_direction[1] * second_direction[2] - first_direction[2] * second_direction[1];
22  tmpVec[1] = first_direction[2] * second_direction[0] - first_direction[0] * second_direction[2];
23  tmpVec[2] = first_direction[0] * second_direction[1] - first_direction[1] * second_direction[0];
24 
25  double normTmpVec = 0;
26  for (unsigned int i = 0;i < dimension;++i)
27  normTmpVec += tmpVec[i] * tmpVec[i];
28 
29  normTmpVec = std::sqrt(normTmpVec);
30  if (normTmpVec < 1.0e-8)
31  {
32  tmpVec[0] = 0;
33  tmpVec[1] = 0;
34  tmpVec[2] = 1;
35  }
36 
37  anima::pairingToQuaternion(tmpVec,tmpVec,tmpMatrix);
38  AMatrix += tmpMatrix.transpose()*tmpMatrix;
39 
40  itk::SymmetricEigenAnalysis < vnl_matrix <double>, vnl_diag_matrix<double>, vnl_matrix <double> > eigenSystem(dimension+1);
41  vnl_matrix <double> eVec(dimension+1,dimension+1);
42  vnl_diag_matrix <double> eVals(dimension+1);
43 
44  eigenSystem.SetOrderEigenValues(true);
45  eigenSystem.ComputeEigenValuesAndVectors(AMatrix, eVals, eVec);
46 
47  vnl_matrix <double> rotationMatrix = anima::computeRotationFromQuaternion<double,double>(eVec.get_row(0));
48 
49  return rotationMatrix;
50 }
51 
52 template <class ScalarType>
53 itk::Matrix <double,3,3>
54 GetRotationMatrixFromVectors(const itk::Point<ScalarType> &first_direction, const itk::Point<ScalarType> &second_direction)
55 {
56  unsigned int dimension = first_direction.GetPointDimension();
57  return GetRotationMatrixFromVectors(first_direction, second_direction, dimension);
58 }
59 
60 template <class ScalarType, unsigned int NDimension>
61 itk::Matrix <double,3,3>
62 GetRotationMatrixFromVectors(const itk::Vector<ScalarType,NDimension> &first_direction, const itk::Vector<ScalarType,NDimension> &second_direction)
63 {
64  return GetRotationMatrixFromVectors(first_direction, second_direction, NDimension);
65 }
66 
67 template <class ScalarType, unsigned int NDimension>
68 itk::Matrix <double,3,3>
69 GetRotationMatrixFromVectors(const vnl_vector_fixed<ScalarType,NDimension> &first_direction, const vnl_vector_fixed<ScalarType,NDimension> &second_direction)
70 {
71  return GetRotationMatrixFromVectors(first_direction, second_direction, NDimension);
72 }
73 
74 template <class ScalarType, class VectorType>
75 void
76 LowerTriangularSolver(vnl_matrix <ScalarType> &matrix, VectorType &rhs, VectorType &result, unsigned int rank)
77 {
78  unsigned int n = matrix.rows();
79  if (rank != 0)
80  n = rank;
81 
82  for (unsigned int i = 0;i < n;++i)
83  {
84  double resValue = rhs[i];
85  for (unsigned int j = 0;j < i;++j)
86  resValue -= matrix.get(i,j) * result[j];
87 
88  result[i] = resValue / matrix(i,i);
89  }
90 }
91 
92 template <class ScalarType, class VectorType>
93 void
94 UpperTriangularSolver(const vnl_matrix <ScalarType> &matrix, const VectorType &rhs, VectorType &result, unsigned int rank)
95 {
96  unsigned int n = matrix.cols();
97  if (rank != 0)
98  n = rank;
99 
100  for (int i = n - 1;i >= 0;--i)
101  {
102  double resValue = rhs[i];
103  for (unsigned int j = i + 1;j < n;++j)
104  resValue -= matrix.get(i,j) * result[j];
105 
106  result[i] = resValue / matrix.get(i,i);
107  }
108 }
109 
110 } // end of namespace anima
void LowerTriangularSolver(vnl_matrix< ScalarType > &matrix, VectorType &rhs, VectorType &result, unsigned int rank=0)
void pairingToQuaternion(const vnl_vector_fixed< TInput, NDimensions > &inputPoint, const vnl_vector_fixed< TInput, NDimensions > &inputTransformedPoint, vnl_matrix< TOutput > &outputMatrix)
itk::Matrix< double, 3, 3 > GetRotationMatrixFromVectors(const VectorType &first_direction, const VectorType &second_direction, const unsigned int dimension)
void UpperTriangularSolver(const vnl_matrix< ScalarType > &matrix, const VectorType &rhs, VectorType &result, unsigned int rank=0)