Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00042 #include "dmp/fourier_approx.h"
00043 #include<stdio.h>
00044 using namespace Eigen;
00045 using namespace std;
00046
00047 namespace dmp{
00048
00049 FourierApprox::FourierApprox(int order)
00050 {
00051 n_bases = order + 1;
00052 features = new double[n_bases];
00053 weights.resize(n_bases);
00054 for(int i=0; i<n_bases; i++){
00055 features[i] = 0;
00056 }
00057 }
00058
00059
00060 FourierApprox::FourierApprox(const vector<double> &w)
00061 {
00062 weights = w;
00063 n_bases = w.size();
00064 features = new double[n_bases];
00065 for(int i=0; i<n_bases; i++){
00066 features[i] = 0;
00067 }
00068 }
00069
00070
00071 FourierApprox::~FourierApprox()
00072 {
00073 delete[] features;
00074 }
00075
00076
00077 double FourierApprox::evalAt(double x)
00078 {
00079 calcFeatures(x);
00080
00081 double wsum = 0;
00082 for(int i=0; i<n_bases; i++){
00083 wsum += features[i] * weights[i];
00084 }
00085 return wsum;
00086 }
00087
00088
00089 void FourierApprox::leastSquaresWeights(double *X, double *Y, int n_pts)
00090 {
00091 MatrixXd D_mat = MatrixXd(n_pts,n_bases);
00092 MatrixXd Y_mat = MatrixXd(n_pts,1);
00093
00094
00095 for(int i=0; i<n_pts; i++){
00096 Y_mat(i,0) = Y[i];
00097 calcFeatures(X[i]);
00098 for(int j=0; j<n_bases; j++){
00099 D_mat(i,j) = features[j];
00100 }
00101 }
00102
00103
00104 MatrixXd w = pseudoinverse(D_mat.transpose() * D_mat) * D_mat.transpose() * Y_mat;
00105 for(int i=0; i<n_bases; i++){
00106 weights[i] = w(i,0);
00107 }
00108 }
00109
00110
00111 void FourierApprox::calcFeatures(double x)
00112 {
00113 for(int i=0; i<n_bases; i++){
00114 features[i] = cos(PI*i*x);
00115 }
00116 }
00117
00118
00119 MatrixXd FourierApprox::pseudoinverse(MatrixXd mat){
00120
00121 double precisionCutoff = 1e-10;
00122
00123
00124 JacobiSVD<MatrixXd> svd(mat, ComputeThinU | ComputeThinV);
00125 MatrixXd U = svd.matrixU();
00126 MatrixXd V = svd.matrixV();
00127 MatrixXd S = svd.singularValues();
00128
00129
00130 MatrixXd S_plus = MatrixXd::Zero(n_bases, n_bases);
00131 for(int i=0; i<n_bases; i++){
00132 if(S(i) > precisionCutoff){
00133 S_plus(i,i) = 1.0/S(i);
00134 }
00135 }
00136
00137
00138 return V * S_plus * U.transpose();
00139 }
00140
00141 }
00142
00143