在Eigen中使用一元表达式的逐元素运算



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

#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错误。这三种情况都在代码中给出,编译器消息也作为注释添加。我的错误是什么?我应该如何正确地写?

您的问题是在不知不觉中试图将复数强制转换为实数。您看到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();

最新更新