Ищете лучший способ инициализации матрицы EIGEN3

StackOverflow https://stackoverflow.com//questions/20004252

  •  20-12-2019
  •  | 
  •  

Вопрос

У меня есть ситуация, когда я получаю матрицу собственной 3 с комплексными элементами из одного с двойными элементами.На данный момент я просто петлю по рядам и колонкам и заполните записями один за другим.Мне было интересно, если кто-нибудь знал о каком-либо подходе по линиям:

 complexMatrix = doubleMatrix.unaryExpr(transform)
.

Это было полезно?

Решение

Есть оператор в Eigen для этого называется CAST . Декларация выглядит страшно из-за вещей шаблона, но использование довольно прост.

Я думаю, что это должно работать

complexMatrix = doubleMatrix.cast< std::complex<double> >();
.

Редактировать, ммм ж ... есть способ сделать это. В документации есть пример: http://eigen.tuxfamily.org/dox/classeigen_1_1matrixbase .html # a23fc4bf97168dee2516f85edcfd4cfe7

Однако я считаю, что для того, чтобы получить правильный тип, вам нужно объединить cast и функтор.

complexMatrix = doubleMatrix.cast< std::complex<double> >().unaryExpr( FUNCTOR );
. Ожидается, что функтор

, конечно, будет предназначен для работы с комплексным типом Scalar. Вы также можете использовать обертку fnc_ptr с простой функцией, как показано в примере.

Примечание. Может быть, можно пропустить cast при использовании класса функтора, который принимает двойной и возвратный комплекс, но мне не удалось сделать это с летучей мыши. Было бы сложно. Я также не думаю, что нужно, потому что cast, вероятно, не вводит никаких реальных накладных расходов.

<Сильные> Редактировать: Рабочий пример.

Он вводится немного накладных расходов от преобразования генеракодицетагкода из x для генеракодицетагкода обратно взад и вперед 2 раза, но я ожидаю, что он будет незначительным по сравнению с фактическим телом функтора.

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

std::complex<double> functor(double x){
  //complicated stuff
  return std::complex<double> (x, -2*x) ;
}

std::complex<double> wrapper(std::complex<double> x)
{
    //nothing is lost here, as we expect x to have only real part 
    //from being upcasted from the original matrix
    double xReal = x.real();
    return functor(xReal);
}

int main(int, char**)
{
  Matrix4d m1 = Matrix4d::Random();
  cout << m1 << endl << "becomes: " << endl 
       << m1.cast< std::complex<double> >().unaryExpr(ptr_fun(wrapper)) << endl;
  return 0;
}
.

Другие советы

unaryexpr может вывести тип возврата из функтора, поэтому можно сделать:

#include <Eigen/Core>
std::complex<double> functor(double x){
  return std::complex<double> (-x, x) ;
}
int main(int, char**)
{
  Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
  Eigen::Matrix3cd m2 = m1.unaryExpr(std::ptr_fun(functor));
}
.

и с классом функтора:

#include <Eigen/Core>
struct Functor {
  typedef std::complex<double> result_type;
  std::complex<double> operator()(double x) const {
    return std::complex<double> (-x, x) ;
  }
};
int main(int, char**)
{
  Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
  Eigen::Matrix3cd m2 = m1.unaryExpr(Functor());
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top