ANIMA  4.0
animaLogExpMapsUnitSphere.hxx
Go to the documentation of this file.
1 #pragma once
3 #include <cmath>
4 
5 namespace anima
6 {
7 
8 template <class ScalarType> void sphere_log_map(const std::vector <ScalarType> &p, const std::vector <ScalarType> &x,
9  std::vector <ScalarType> &logValue)
10 {
11  unsigned int sizeVec = p.size();
12  if (logValue.size() != sizeVec)
13  logValue.resize(sizeVec);
14 
15  for (unsigned int i = 0;i < sizeVec;++i)
16  logValue[i] = 0;
17 
18  double dotProd = 0;
19  for (unsigned int i = 0;i < sizeVec;++i)
20  dotProd += p[i]*x[i];
21 
22  if (dotProd >= 1)
23  return;
24 
25  if (dotProd <= -1 + 1.0e-8)
26  dotProd = -1 + 1.0e-8;
27 
28  for (unsigned int i = 0;i < sizeVec;++i)
29  logValue[i] = (p[i] - x[i]*dotProd)*std::acos(dotProd)/std::sqrt(1.0 - dotProd*dotProd);
30 }
31 
32 template <class ScalarType> void sphere_exp_map(const std::vector <ScalarType> &p, const std::vector <ScalarType> &x,
33  std::vector <ScalarType> &expValue)
34 {
35  unsigned int sizeVec = p.size();
36  if (expValue.size() != sizeVec)
37  expValue.resize(sizeVec);
38 
39  double normP = 0;
40  for (unsigned int i = 0;i < sizeVec;++i)
41  normP += p[i]*p[i];
42 
43  normP = std::sqrt(normP);
44 
45  if (normP == 0)
46  {
47  expValue = x;
48  return;
49  }
50 
51  for (unsigned int i = 0;i < sizeVec;++i)
52  expValue[i] = std::cos(normP)*x[i] + p[i]*std::sin(normP)/normP;
53 }
54 
55 template <class ScalarType> void ComputeSphericalCentroid(const std::vector < std::vector <ScalarType> > &dataPoints,
56  std::vector <ScalarType> &centroidValue, const std::vector <ScalarType> &initPoint,
57  const std::vector <ScalarType> &weights, std::vector <ScalarType> *workLogVector,
58  std::vector <ScalarType> *workVector, double tol)
59 {
60  unsigned int sizeData = dataPoints.size();
61  unsigned int sizeVec = initPoint.size();
62  centroidValue = initPoint;
63 
64  bool internalLogVector = false;
65  bool internalVector = false;
66  if (!workLogVector)
67  {
68  workLogVector = new std::vector <ScalarType> (sizeVec);
69  internalLogVector = true;
70  }
71 
72  if (workLogVector->size() != sizeVec)
73  workLogVector->resize(sizeVec);
74 
75  if (!workVector)
76  {
77  workVector = new std::vector <ScalarType> (sizeVec);
78  internalVector = true;
79  }
80 
81  if (workVector->size() != sizeVec)
82  workVector->resize(sizeVec);
83 
84  double sumWeights = 0;
85  for (unsigned int i = 0;i < sizeData;++i)
86  sumWeights += weights[i];
87 
88  double diffNewOld = tol + 1;
89 
90  while (diffNewOld > tol)
91  {
92  for (unsigned int j = 0;j < sizeVec;++j)
93  (*workLogVector)[j] = 0;
94 
95  for (unsigned int i = 0;i < sizeData;++i)
96  {
97  sphere_log_map(dataPoints[i],centroidValue,(*workVector));
98 
99  for (unsigned int j = 0;j < sizeVec;++j)
100  (*workLogVector)[j] += weights[i]*(*workVector)[j];
101  }
102 
103  for (unsigned int j = 0;j < sizeVec;++j)
104  (*workLogVector)[j] /= sumWeights;
105 
106  sphere_exp_map((*workLogVector),centroidValue,(*workVector));
107 
108  diffNewOld = 0;
109 
110  for (unsigned int j = 0;j < sizeVec;++j)
111  diffNewOld += (centroidValue[j]-(*workVector)[j])*(centroidValue[j]-(*workVector)[j]);
112 
113  diffNewOld = std::sqrt(diffNewOld);
114 
115  centroidValue = (*workVector);
116  }
117 
118  if (internalLogVector)
119  delete workLogVector;
120 
121  if (internalVector)
122  delete workVector;
123 }
124 
125 } //end namespace anima
void sphere_exp_map(const std::vector< ScalarType > &p, const std::vector< ScalarType > &x, std::vector< ScalarType > &expValue)
void sphere_log_map(const std::vector< ScalarType > &p, const std::vector< ScalarType > &x, std::vector< ScalarType > &logValue)
void ComputeSphericalCentroid(const std::vector< std::vector< ScalarType > > &dataPoints, std::vector< ScalarType > &centroidValue, const std::vector< ScalarType > &initPoint, const std::vector< ScalarType > &weights, std::vector< ScalarType > *workLogVector=0, std::vector< ScalarType > *workVector=0, double tol=1.0e-4)