Eigen 外加法
Outer addition with Eigen
我正在尝试将以下 python 函数翻译成 C++:
import numpy as np
from scipy.linalg import blas
def scaled_dist(a, b, ls):
al = a/ls
bl = b/ls
tmp1 = np.sum(al**2, axis=1)
tmp2 = np.sum(bl**2, axis=1)
tmp3 = np.add.outer(tmp1, tmp2, order='F')
tau = blas.dgemm(a=al, b=bl, alpha=-2.0, c=tmp3, beta=1, trans_b=1)
np.clip(tau, 0, np.inf, out=tau)
return tau
但是我遇到了一个绊脚石:
tmp3 = np.add.outer(tmp1, tmp2)
我的 C++ 代码可以编译,但在执行时遇到运行时错误。代码(到那一行)是:
Eigen::MatrixXd test2(const Eigen::MatrixXd &x1, const Eigen::MatrixXd &x2,const Eigen::VectorXd &vec)
{
Eigen::MatrixXd r = Eigen::MatrixXd::Zero(x1.rows(), x2.rows());
Eigen::MatrixXd al = x1.array().rowwise() / vec.transpose().array();
Eigen::VectorXd tmp1 = al.array().square().rowwise().sum();
Eigen::MatrixXd bl = x2.array().rowwise() / vec.transpose().array();
Eigen::VectorXd tmp2 = bl.array().square().rowwise().sum();
r = tmp1.transpose().array() + tmp2.array();
return r;
}
我能够理解运行时错误,这是(我相信)断言错误,抱怨加法表达式左右两侧的大小不匹配。 tmp1.transpose() * tmp2
确实 似乎产生了预期的结果这一事实激发了我采用这种方法的动机。
我的问题如下:
给定两个向量,vec1
和 vec2
,使用 Eigen 实现与 numpy.add.outer(vec1, vec2)
相同功能的惯用方法是什么,即 "outer" 加法,其中矩阵是通过将一个向量的(广播)行添加到另一个向量的(广播)列获得的?即,如果
vec1 = [1,2,3]
vec2 = [3,4,5]
然后
outer_add(vec1, vec2) =
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
您可以为此使用复制,例如:
Vector3f v1(1,2,3), v2(3,4,5);
MatrixXf r = v1.rowwise().replicate(v2.size())
+ v2.transpose().colwise().replicate(v1.size());
我正在尝试将以下 python 函数翻译成 C++:
import numpy as np
from scipy.linalg import blas
def scaled_dist(a, b, ls):
al = a/ls
bl = b/ls
tmp1 = np.sum(al**2, axis=1)
tmp2 = np.sum(bl**2, axis=1)
tmp3 = np.add.outer(tmp1, tmp2, order='F')
tau = blas.dgemm(a=al, b=bl, alpha=-2.0, c=tmp3, beta=1, trans_b=1)
np.clip(tau, 0, np.inf, out=tau)
return tau
但是我遇到了一个绊脚石:
tmp3 = np.add.outer(tmp1, tmp2)
我的 C++ 代码可以编译,但在执行时遇到运行时错误。代码(到那一行)是:
Eigen::MatrixXd test2(const Eigen::MatrixXd &x1, const Eigen::MatrixXd &x2,const Eigen::VectorXd &vec)
{
Eigen::MatrixXd r = Eigen::MatrixXd::Zero(x1.rows(), x2.rows());
Eigen::MatrixXd al = x1.array().rowwise() / vec.transpose().array();
Eigen::VectorXd tmp1 = al.array().square().rowwise().sum();
Eigen::MatrixXd bl = x2.array().rowwise() / vec.transpose().array();
Eigen::VectorXd tmp2 = bl.array().square().rowwise().sum();
r = tmp1.transpose().array() + tmp2.array();
return r;
}
我能够理解运行时错误,这是(我相信)断言错误,抱怨加法表达式左右两侧的大小不匹配。 tmp1.transpose() * tmp2
确实 似乎产生了预期的结果这一事实激发了我采用这种方法的动机。
我的问题如下:
给定两个向量,vec1
和 vec2
,使用 Eigen 实现与 numpy.add.outer(vec1, vec2)
相同功能的惯用方法是什么,即 "outer" 加法,其中矩阵是通过将一个向量的(广播)行添加到另一个向量的(广播)列获得的?即,如果
vec1 = [1,2,3]
vec2 = [3,4,5]
然后
outer_add(vec1, vec2) =
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
您可以为此使用复制,例如:
Vector3f v1(1,2,3), v2(3,4,5);
MatrixXf r = v1.rowwise().replicate(v2.size())
+ v2.transpose().colwise().replicate(v1.size());