Given that Eigen allows parallelising the computations via either MKL, OpenMP, or AVX, it is often considered a best practice to avoid iterations when possible, as these cannot be fully optimized at the library level. I was wondering if it would be possible to further use .rowwise() in some way rather than iterating over the rows in the following snippet of code computing the decision function for a trained SVM with the RBF Kernel for is kernel trick:
Eigen::VectorXd decision_function(const Eigen::MatrixXd& Train,const Eigen::MatrixXd& Test, const Eigen::VectorXd& lambdas, double gamma, double b) {
Eigen::VectorXd result = Eigen::VectorXd::Zero(X_test.rows());
for (int i = 0; i < X_test.rows(); ++i) {
Eigen::VectorXd v = (-gamma * ((Train).rowwise() + (-Test).row(i)).rowwise().squaredNorm()).array().exp();
result(i) = v.transpose()*lambdas;
}
return result.array()+b;
}
By using the above function with the following data, the output statement returns a vector of ( 504, 504.1).
double data[nColumns * nRows] = {
0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1,
0.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2,
1.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3,
1.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f, 3.6f, 3.7f, 3.8f, 3.9f, 4,
0.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f, 4.7f, 4.8f, 4.9f, 5,
0.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f, 5.6f, 5.7f, 5.8f, 5.9f, 1,
0.0f, 6.1f, 6.2f, 6.3f, 6.4f, 6.5f, 6.6f, 6.7f, 6.8f, 6.9f, 2,
7.0f, 7.1f, 7.2f, 7.3f, 7.4f, 7.5f, 7.6f, 7.7f, 7.8f, 7.9f, 3,
8.0f, 8.1f, 8.2f, 8.3f, 8.4f, 8.5f, 8.6f, 8.7f, 8.8f, 8.9f, 4,
9.0f, 9.1f, 9.2f, 9.3f, 9.4f, 9.5f, 9.6f, 9.7f, 9.8f, 9.9f, 5
};
double data2[nColumns * 2] = {
0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1,
0.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2,
};
using RowMajorMapType2 = Eigen::Map> ;
RowMajorMapType2 Training{(double*)data, nRows, nColumns};
RowMajorMapType2 Testing{(double*)data2, 2, nColumns};
Eigen::VectorXd b(10);
b << 0.0 , 0.1 , 0.2 , 0.3 , 0.4, 0.5 , 0.6 , 0.7 , 0.8 , 0.9;
std::cout << decision_function(Training, Testing, b, 1.0, 504) << std::endl;