gpt4 book ai didi

c++ - 来自函数的高效特征矩阵

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:41 26 4
gpt4 key购买 nike

我正在尝试从内核构建一个矩阵,使得 A(i,j) = f(i,j) 其中 i,j 都是 vector (因此我从两个矩阵 x,y 构建 A,每个矩阵行对应于一个点/vector )。我当前的功能看起来与此类似:

Eigen::MatrixXd get_kernel_matrix(const Eigen::MatrixXd& x, const Eigen::MatrixXd& y, double(&kernel)(const Eigen::VectorXd&)) {
Eigen::MatrixXd res (x.rows(), y.rows());
for(int i = 0; i < res.rows() ; i++) {
for(int j = 0; j < res.cols(); j++) {
res(i, j) = kernel(x.row(i), y.row(j));
}
}
}
return res;
}

连同对角线的一些逻辑(在我的情况下可能会导致被零除)。

有没有更有效/惯用的方法来做到这一点?在我的一些测试中,Matlab 代码似乎超过了我的 C++/Eigen 实现的速度(我猜是由于矢量化)。

我查看了大量文档(例如 unaryExpr 函数),但似乎无法找到我要查找的内容。

感谢您的帮助。

最佳答案

您可以使用带有适当 lambda 的 NullaryExpr 来删除您的 for 循环:

MatrixXd res = MatrixXd::NullaryExpr(x.rows(), y.rows(),
[&x,&y,&kernel](int i,int j) { return kernel(x.row(i), y.row(j)); });

这是一个重现矩阵乘积的独立工作示例:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;

double my_kernel(const MatrixXd::ConstRowXpr &x, const MatrixXd::ConstRowXpr &y) {
return x.dot(y);
}

template<typename Kernel>
MatrixXd apply_kernel(const MatrixXd& x, const MatrixXd& y, Kernel kernel) {
return MatrixXd::NullaryExpr(x.rows(), y.rows(),
[&x,&y,&kernel](int i,int j) { return kernel(x.row(i), y.row(j)); });
}

int main()
{
int n = 10;
MatrixXd X = MatrixXd::Random(n,n);
MatrixXd Y = MatrixXd::Random(n,n);
MatrixXd R = apply_kernel(X,Y,std::ptr_fun(my_kernel));
std::cout << R << "\n\n";
std::cout << X*Y.transpose() << "\n\n";
}

如果你不想让apply_kernel成为模板函数,你可以使用std::function传递内核。

关于c++ - 来自函数的高效特征矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47114736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com