Для 2D-тензоров лучше использовать Matrix
или Array
, это приведет к более простому коду:
ArrayXXd a = ArrayXXd::Random(2*10000,5);
ArrayXXd b = ArrayXXd::Random(2*10000,5);
auto means = (a-b).colwise().mean().eval();
auto stds = (((a-b).rowwise()-means).square().colwise().sum() / (a.rows()-1)).sqrt().eval();
ArrayXXd diffs = abs((a-b).rowwise() - means).rowwise()/stds;
Обратите внимание на .eval()
для строк, использующих auto
, см. почему .
Этот код занимает 0.000324919s
при компиляции с gcc и -O3
на среднем ноутбуке (без учета генерации случайных чисел, которая, вероятно, намного дороже, но не репрезентативна).
Вот версия Tensor, с которой я столкнулся, снова обратите внимание на вызовы eval()
:
int n = a.dimension(0);
Eigen::array<int, 1> dims({0 /* dimension to reduce */});
Eigen::array<int, 2> good_dims{{1,(int)a.dimension(1)}};
Eigen::array<int,2> bc({n,1});
auto means = (a - b).mean(dims).eval();
auto submean = (a - b) - means.reshape(good_dims).broadcast(bc);
auto stds = (submean.square().eval().sum(dims) * 1.f/(float(n-1))).sqrt().eval();
diffs = submean.abs() / stds.reshape(good_dims).broadcast(bc);
, но, похоже, она медленнее, около 0,007 с здесь.Чтобы просмотреть Tensor
как Array
, вы можете использовать Map
:
Map<const ArrayXXf> a(tensor_a.data(), tensor_a.dimension(0), tensor_a.dimension(1));