在Eigen中使用unaryExpr的元素操作

时间:2015-12-17 13:40:34

标签: c++ eigen eigen3

我正在尝试编写一个函数,该函数采用复数值向量并以double形式计算元素的角度。我的代码如下:

#include <iostream>
#include <functional>
#include <Eigen/Core>
#include <complex>

class Arg {
public:
    double operator()(std::complex<double> a) const
    {
        return std::arg(a);
    }
};

template <typename DerivedA, typename DerivedB>
void ArgumentComputer(const Eigen::MatrixBase<DerivedA> &mat, const Eigen::MatrixBase<DerivedB> &_arg)
{

    Eigen::MatrixBase<DerivedB>& arg = const_cast<decltype(arg)>(_arg);

    // 1st try:
    //arg = mat.unaryExpr(std::ptr_fun(std::arg<double>));

    //error: no matching function for call to ‘ptr_fun(<unresolved overloaded function type>)’

    // 2nd try:
    // arg = mat.unaryExpr(Arg{});

    // error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY

    // 3rd try:
    arg = mat.unaryExpr(Arg{}).template cast<double>();

    // error: invalid static_cast from type ‘const std::complex<double>’ to type ‘double’
    // return static_cast<NewType>(x);


}

int main()
{

    Eigen::MatrixXcd myMat = Eigen::MatrixXcd::Random(3, 3);
    Eigen::MatrixXd Arg_myMat(3, 3);

    ArgumentComputer(myMat, Arg_myMat);

    std::cout << myMat << std::endl;
    std::cout << Arg_myMat << std::endl;

    return 0;
}

我首先尝试使用ptr_fun,但我想解决类型时存在问题。然后我试着写一个表现为仿函数的类。在这种情况下,我得到错误说我需要做铸造。当我进行投射时,我得到了static_cast错误。所有这三种情况都在代码中给出,编译器消息也作为注释添加。我的错误是什么,我该怎么写呢?

1 个答案:

答案 0 :(得分:1)

您的问题是您在不知不觉中尝试将复数转换为实数。您会看到std::arg的返回类型为double,并假设您拥有的内容,但实际上由于std::complex<double>类型(mat)而属于MatrixXcd 。你的代码看起来像是:

// 1st try:
//arg = mat.unaryExpr(std::ptr_fun(std::arg<double>)).real(); // Should work but doesn't resolve the template for some reason

// 2nd try:
arg = mat.unaryExpr(Arg{}).real(); // works

我不是百分百肯定为什么你的第一次尝试不起作用。您也可以使用函数代替函子:

double myArg(std::complex<double> a)
{
    return std::arg(a);
}
//...
arg = mat.unaryExpr(std::ptr_fun(myArg)).real();