summaryrefslogtreecommitdiff
path: root/video_input/consistencyChecker/NMath.h
blob: 5f31c3a14e780f13024a4b7760e90c98a207c2e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// NMath
// A collection of mathematical functions and numerical algorithms
//
// Author: Thomas Brox

#ifndef NMathH
#define NMathH

#include <math.h>
#include <stdlib.h>
#include <CVector.h>
#include <CMatrix.h>

namespace NMath {
  // Returns the faculty of a number
  int faculty(int n);
  // Computes the binomial coefficient of two numbers
  int binCoeff(const int n, const int k);
  // Returns the angle of the line connecting (x1,y1) with (y1,y2)
  float tangent(const float x1, const float y1, const float x2, const float y2);
  // Absolute for floating points
  inline float abs(const float aValue);
  // Computes min or max value of two numbers
  inline float min(float aVal1, float aVal2);
  inline float max(float aVal1, float aVal2);
  inline int min(int aVal1, int aVal2);
  inline int max(int aVal1, int aVal2);
  // Computes the sign of a value
  inline float sign(float aVal);
  // minmod function (see description in implementation)
  inline float minmod(float a, float b, float c);
  // Computes the difference between two angles respecting the cyclic property of an angle
  // The result is always between 0 and Pi
  float absAngleDifference(const float aFirstAngle, const float aSecondAngle);
  // Computes the difference between two angles aFirstAngle - aSecondAngle
  // respecting the cyclic property of an angle
  // The result ist between -Pi and Pi
  float angleDifference(const float aFirstAngle, const float aSecondAngle);
  // Computes the sum of two angles respecting the cyclic property of an angle
  // The result is between -Pi and Pi
  float angleSum(const float aFirstAngle, const float aSecondAngle);
  // Rounds to the nearest integer
  int round(const float aValue);
  // Computes the arctan with results between 0 and 2*Pi
  inline float arctan(float x, float y);

  // Computes [0,1] uniformly distributed random number
  inline float random();
  // Computes N(0,1) distributed random number
  inline float randomGauss();

  extern const float Pi;

  // Computes a principal axis transformation
  // Eigenvectors are in the rows of aEigenvectors
  void PATransformation(const CMatrix<float>& aMatrix, CVector<float>& aEigenvalues, CMatrix<float>& aEigenvectors, bool aOrdering = true);
  // Computes the principal axis backtransformation
  void PABacktransformation(const CMatrix<float>& aEigenVectors, const CVector<float>& aEigenValues, CMatrix<float>& aMatrix);
  // Computes a singular value decomposition A=USV^T
  // Input: U MxN matrix
  // Output: U MxN matrix, S NxN diagonal matrix, V NxN diagonal matrix
  void svd(CMatrix<float>& U, CMatrix<float>& S, CMatrix<float>& V, bool aOrdering = true, int aIterations = 20);
  // Reassembles A = USV^T, Result in U
  void svdBack(CMatrix<float>& U, const CMatrix<float>& S, const CMatrix<float>& V);
  // Applies the Householder method to A and b, i.e., A is transformed into an upper triangular matrix
  void householder(CMatrix<float>& A, CVector<float>& b);
  // Computes least squares solution of an overdetermined linear system Ax=b using the Householder method
  CVector<float> leastSquares(CMatrix<float>& A, CVector<float>& b);
  // Inverts a square matrix by eigenvalue decomposition,
  // eigenvalues smaller than aReg are replaced by aReg
  void invRegularized(CMatrix<float>& A, int aReg);
  // Given a positive-definite symmetric matrix A, this routine constructs A = LL^T.
  // Only the upper triangle of A need be given. L is returned in the lower triangle.
  void cholesky(CMatrix<float>& A);
  // Solves L*aOut = aIn when L is a lower triangular matrix (e.g. result from cholesky)
  void triangularSolve(CMatrix<float>& L, CVector<float>& aIn, CVector<float>& aOut);
  void triangularSolve(CMatrix<float>& L, CMatrix<float>& aIn, CMatrix<float>& aOut);
  // Solves L^T*aOut = aIn when L is a lower triangular matrix (e.g. result from cholesky)
  void triangularSolveTransposed(CMatrix<float>& L, CVector<float>& aIn, CVector<float>& aOut);
  void triangularSolveTransposed(CMatrix<float>& L, CMatrix<float>& aIn, CMatrix<float>& aOut);
  // Computes the inverse of a matrix, given its cholesky decomposition L (lower triangle)
  void choleskyInv(const CMatrix<float>& L, CMatrix<float>& aInv);
  // Creates the rotation matrix RzRyRx and extends it to a 4x4 RBM matrix with translation 0
  void eulerAngles(float rx, float ry, float rz, CMatrix<float>& A);
  // Transforms a rigid body motion in matrix representation to a twist representation
  void RBM2Twist(CVector<float> &T, CMatrix<float>& RBM); 
}

// I M P L E M E N T A T I O N -------------------------------------------------
// Inline functions have to be implemented directly in the header file

namespace NMath {

  // abs
  inline float abs(const float aValue) {
    if (aValue >= 0) return aValue;
    else return -aValue;
  }

  // min
  inline float min(float aVal1, float aVal2) {
    if (aVal1 < aVal2) return aVal1;
    else return aVal2;
  }

  // max
  inline float max(float aVal1, float aVal2) {
    if (aVal1 > aVal2) return aVal1;
    else return aVal2;
  }

  // min
  inline int min(int aVal1, int aVal2) {
    if (aVal1 < aVal2) return aVal1;
    else return aVal2;
  }

  // max
  inline int max(int aVal1, int aVal2) {
    if (aVal1 > aVal2) return aVal1;
    else return aVal2;
  }

  // sign
  inline float sign(float aVal) {
    if (aVal > 0) return 1.0;
    else return -1.0;
  }

  // minmod function:
  //     0,                       if any of the a, b, c are 0 or of opposite sign
  //     sign(a) min(|a|,|b|,|c|) else
  inline float minmod(float a, float b, float c) {
    if ((sign(a) == sign(b)) && (sign(b) == sign(c)) && (a != 0.0)) {
      float aMin = fabs(a);
      if (fabs(b) < aMin) aMin = fabs(b);
      if (fabs(c) < aMin) aMin = fabs(c);
      return sign(a)*aMin;
    }
    else return 0.0;
  }

  // arctan
  inline float arctan(float x, float y) {
    if (x == 0.0)
      if (y >= 0.0) return 0.5 * 3.1415926536;
      else return 1.5 * 3.1415926536;
    else if (x > 0.0)
      if (y >= 0.0) return atan (y/x);
      else return 2.0 * 3.1415926536 + atan (y/x);
    else return 3.1415926536 + atan (y/x);
  }

  // random
  inline float random() {
    return (float)rand()/RAND_MAX;
  }

  // randomGauss
  inline float randomGauss() {
    // Draw two [0,1]-uniformly distributed numbers a and b
    float a = random();
    float b = random();
    // assemble a N(0,1) number c according to Box-Muller */
    if (a > 0.0) return sqrt(-2.0*log(a)) * cos(2.0*3.1415926536*b);
    else return 0;
  }

}
#endif