Следует ли использовать оба Tigenor.contract Tensor.reduce от Eigen для достижения функциональности, аналогичной np.einsum? - PullRequest
0 голосов
/ 24 августа 2018

Скажем, я хочу умножить a=shape(3, 2, 2) with b=shape(3, 2, 2) матрицы вместе. С np.einsum это легко можно выразить как np.einsum("sij,sjk->sil", a, b).

Я пытаюсь сделать что-то похожее в Eigen, используя Tensor.contract, но в лучшем случае я смог создать (3,2,3,2) форму вывода (см. Вывод c ниже).

#include <iostream>

#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"


int main(void)
{
    // np.einsum("sij,sjk->sik")
    Eigen::DefaultDevice my_device;
    Eigen::Tensor<float, 3> a(3, 2, 2);
    Eigen::Tensor<float, 3> b(3, 2, 2);

    Eigen::array<Eigen::IndexPair<int>,1> dims = {Eigen::IndexPair<int>(2, 1)};

    a.setConstant(1);
    b.setConstant(2);

    Eigen::Tensor<float, 4> c(3, 2, 3, 2);
    Eigen::Tensor<float, 3> d(3, 2, 2);
    Eigen::array<int, 1> reduce_dims({2});

    c.device(my_device) = a.contract(b, dims);
    d.device(my_device) = a.contract(b, dims).sum(reduce_dims);
    std::cout << c << std::endl;
    std::cout << d << std::endl;
}

Вопросы

  1. Кажется, что contract и reduce должны быть объединены, чтобы произвести поведение einsum. Это правильно?

  2. Это простой случай, но я хочу в конечном итоге выполнить более сложное поведение, аналогичное суммированию по Эйнштейну. Что-то с эффектом np.einsum("stacij,tacjk, tckl->tacil"). Разумно ли использовать контракт Эйгена и сокращать его для достижения этого?

  3. Размеры ijkl будут максимум 4, тогда как остальные размеры будут намного больше. Будет Eigen хорошо работать с этими размерами размеров.

...