Marine systems simulation
AzimuthCurve.h
1#ifndef AzimuthCurve_h__
2#define AzimuthCurve_h__
3
4#include <vector>
5#include <cstddef>
6#include <Eigen/Eigen>
7
8template <class T>
10public:
11 AzimuthCurve( std::vector<T> coeff, std::vector<double> aziAngle ){
12 MakeCofficients(coeff, aziAngle);
13 }
14
15 AzimuthCurve( std::vector<T> coeff ){
16 size_t size = coeff.size();
17 m_coeff_size = size;
18 m_coeff = new T[size];
19 for (size_t i =0; i < size; i++){
20 m_coeff[i] = coeff[i];
21 }
22 }
23
24 T eval( double angle ){
25 T retval = m_coeff[0];
26 for( size_t j=1; j < ((m_coeff_size - 1) / 2 + 1); j++)
27 retval += m_coeff[j]*cos( j * angle);
28 for( size_t j=((m_coeff_size - 1) / 2 + 1); j < m_coeff_size; j++)
29 retval += m_coeff[j]*sin( (j-(m_coeff_size - 1) / 2) * angle);
30 return retval;
31 }
32
34 delete m_coeff;
35 }
36
37 std::vector<T> eval( std::vector<T> angle ){
38 std::vector<T> retval; retval.resize(angle.size());
39 for( size_t i=0; i < angle.size(); i++)
40 retval[i] = eval( angle[i] );
41 return retval;
42 }
43
44private:
45 T * m_coeff;
46 size_t m_coeff_size;
47
48 void MakeCofficients(std::vector<T> values, std::vector<double> aziAngle){
49
50 size_t size = values.size();
51
52 // Solve 2*N + 1 unknown (A0 + A1..AN + B1..BN
53 size_t N = static_cast<size_t>(std::floor((size - 1) / 2));
54 m_coeff_size = 2*N+1;
55 m_coeff = new T[m_coeff_size];
56
57 Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> A = Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>::Zero(m_coeff_size, m_coeff_size);
58 Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> B = Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>::Zero(m_coeff_size, 1);
59 Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> x = Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>::Zero(m_coeff_size, 1);
60
61 // right hand side of equation system
62 for(size_t k=0; k < m_coeff_size; k++)
63 B(k) = values[k];
64
65 // build system matrix, left hand side. A0, A1..AN and B1..BN
66 // build for each B value.
67 for(size_t k=0; k < m_coeff_size; k++){
68 A(k, 0) = 1;
69 for (size_t j = 1; j < N + 1; j++) {
70 A(k, j + 0) = cos(j * aziAngle[k]);
71 A(k, j + N) = sin(j * aziAngle[k]);
72 }
73 }
74
75 for(size_t k=0; k < size; k++)
76 for(size_t j=0; j < size; j++){
77 if( (std::abs(A(k,j)) < 1e-6) )
78 A(k,j) = 0;
79 }
80
81 x = A.colPivHouseholderQr().solve(B);
82 for(size_t k=0; k < size; k++)
83 m_coeff[k] = x(k);
84 }
85};
86
87#endif // AzimuthCurve_h__
Definition: AzimuthCurve.h:9