29 #include <eigen3/Eigen/SVD> 30 #include <eigen3/Eigen/LU> 32 using namespace Eigen;
37 namespace BasisFunction {
39 void Gaussian::activations(
40 const std::vector<Eigen::VectorXd>& mus,
41 const std::vector<Eigen::MatrixXd>& covars,
42 std::vector<double> priors,
43 const Eigen::Ref<const Eigen::MatrixXd>& inputs,
44 Eigen::MatrixXd& kernel_activations,
45 bool normalized_basis_functions)
48 unsigned int n_basis_functions = mus.size();
49 int n_samples = inputs.rows();
51 assert(n_basis_functions>0);
52 assert(n_basis_functions==covars.size());
53 #ifndef NDEBUG // Variables below are only required for asserts; check for NDEBUG to avoid warnings. 54 int n_dims = mus[0].size();
56 assert(n_dims==covars[0].cols());
57 assert(n_dims==covars[0].rows());
58 assert(n_dims==inputs.cols());
60 kernel_activations.resize(n_samples,n_basis_functions);
62 if (normalized_basis_functions && n_basis_functions==1)
70 kernel_activations.fill(1.0);
74 VectorXd mu,diff,exp_term;
78 for (
unsigned int bb=0; bb<n_basis_functions; bb++)
81 covar_inv = covars[bb].inverse();
83 for (
int tt=0; tt<n_samples; tt++)
87 diff = inputs.row(tt)-mu.transpose();
88 exp_term = -0.5*diff.transpose()*covar_inv*diff;
89 assert(exp_term.size()==1);
90 kernel_activations(tt,bb) = prior*exp(exp_term[0]);
94 if (normalized_basis_functions)
97 MatrixXd sum_kernel_activations = kernel_activations.rowwise().sum();
100 if ((sum_kernel_activations.array()==0).any())
101 sum_kernel_activations.array() += sum_kernel_activations.maxCoeff()/100000.0;
104 kernel_activations = kernel_activations.array()/sum_kernel_activations.replicate(1,n_basis_functions).array();
110 void Gaussian::activations(
const Eigen::MatrixXd& centers,
const Eigen::MatrixXd& widths,
const Eigen::Ref<const Eigen::MatrixXd>& inputs, Eigen::MatrixXd& kernel_activations,
bool normalized_basis_functions,
bool asymmetric_kernels)
112 ENTERING_REAL_TIME_CRITICAL_CODE
119 int n_basis_functions = centers.rows();
120 int n_samples = inputs.rows();
121 int n_dims = centers.cols();
122 assert( (n_basis_functions==widths.rows()) & (n_dims==widths.cols()) );
123 assert( (n_samples==inputs.rows() ) & (n_dims==inputs.cols()) );
127 kernel_activations.resize(n_samples,n_basis_functions);
129 if (normalized_basis_functions && n_basis_functions==1)
137 kernel_activations.fill(1.0);
138 EXITING_REAL_TIME_CRITICAL_CODE
144 for (
int bb=0; bb<n_basis_functions; bb++)
154 kernel_activations.col(bb).fill(1.0);
155 for (
int i_dim=0; i_dim<n_dims; i_dim++)
157 c = centers(bb,i_dim);
158 for (
int i_s=0; i_s<n_samples; i_s++)
160 x = inputs(i_s,i_dim);
161 w = widths(bb,i_dim);
163 if (asymmetric_kernels && x<c && bb>0)
166 w = widths(bb-1,i_dim);
168 kernel_activations(i_s,bb) *= exp(-0.5*pow(x-c,2)/(w*w));
174 if (normalized_basis_functions)
177 double sum_kernel_activations;
178 for (
int i_sample=0; i_sample<n_samples; i_sample++)
180 sum_kernel_activations = kernel_activations.row(i_sample).sum();
181 for (
int i_basis=0; i_basis<n_basis_functions; i_basis++)
183 if (sum_kernel_activations==0.0)
185 kernel_activations(i_sample,i_basis) = 1.0/n_basis_functions;
188 kernel_activations(i_sample,i_basis) /= sum_kernel_activations;
194 EXITING_REAL_TIME_CRITICAL_CODE
197 void Cosine::activations(
198 const std::vector<Eigen::MatrixXd>& angular_frequencies,
199 const std::vector<Eigen::VectorXd>& phases,
200 const Eigen::Ref<const Eigen::MatrixXd>& inputs,
201 Eigen::MatrixXd& activations)
203 unsigned int n_basis_functions = angular_frequencies.size();
204 int n_samples = inputs.rows();
206 assert(n_basis_functions>0);
207 assert(phases.size()==n_basis_functions);
208 assert(phases[0].size()==1);
210 assert(angular_frequencies[0].size()==inputs.cols());
213 activations.resize(n_samples,n_basis_functions);
215 for (
unsigned int bb=0; bb<n_basis_functions; bb++)
217 for (
int i_s=0; i_s<n_samples; i_s++)
219 activations(i_s,bb) = cos(angular_frequencies[bb].row(0).dot(inputs.row(i_s)) + phases[bb][0]);
225 void Cosine::activations(
226 const Eigen::MatrixXd& angular_frequencies,
227 const Eigen::VectorXd& phases,
228 const Eigen::Ref<const Eigen::MatrixXd>& inputs,
229 Eigen::MatrixXd& activations)
233 activations = inputs * angular_frequencies.transpose();
234 activations.rowwise() += phases.transpose();
235 activations = activations.array().cos();
BasisFunction header file.