Внешнее дополнение с Eigen - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь перевести следующую функцию 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), а именно «внешнего» сложения, посредством которого получается матрица путем добавления (широковещательных) строк одного вектора к(широковещательные) колонки другого?то есть если

vec1 = [1,2,3]
vec2 = [3,4,5]

, то

outer_add(vec1, vec2) = 
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]

1 Ответ

1 голос
/ 26 мая 2019

Вы можете использовать для этого копию, например:

Vector3f v1(1,2,3), v2(3,4,5);
MatrixXf r = v1.rowwise().replicate(v2.size())
           + v2.transpose().colwise().replicate(v1.size());
...