来自 Eigen 的 unaryExpr 不适用于来自同一结构体的函数

unaryExpr from Eigen dosn't work with function from the same struct

提问人:Fisteshak 提问时间:10/30/2023 更新时间:10/30/2023 访问量:29

问:

我有使用 unaryExpr 将 sigmoid 函数应用于特征矩阵的代码

#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/Core>

#include <iostream>

using Eigen::MatrixXd, std::cout, std::cin;

double sigmoid(double x) {
    return 1.0 / (1.0 + exp(-x));
}

struct Network {
public:
    MatrixXd sigmoid_matrix(MatrixXd z) {
        return z.unaryExpr(&sigmoid);
    }
};

int main() {
    Network net;
    Eigen::MatrixXd m(1, 4);
    m << 1, 2, 3, 4;
    cout << net.sigmoid_matrix(m);
}

但是,如果我将函数放在结构中,它可以正常工作:double sigmoid(double x)Network

#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/Core>

#include <iostream>

using Eigen::MatrixXd, std::cout, std::cin;

struct Network {
public:
    double sigmoid(double x) {
        return 1.0 / (1.0 + exp(-x));
    }
    MatrixXd sigmoid_matrix(MatrixXd z) {
        return z.unaryExpr(&Network::sigmoid);
    }
};

int main() {
    Network net;
    Eigen::MatrixXd m(1, 4);
    m << 1, 2, 3, 4;
    cout << net.sigmoid_matrix(m);
}

它无法编译,并出现以下错误:

D:/Projects/c++/eigen/Eigen/src/Core/util/Meta.h:272:61: error: no type named 'type' in 'struct std::invoke_result<double (Network::*)(double), const double&>'
  272 |   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
      |                                                             ^~~~~
D:/Projects/c++/eigen/Eigen/src/Core/util/Meta.h:273:31: error: no type named 'type' in 'struct std::invoke_result<double (Network::*)(double), const double&>'
  273 |   typedef remove_all_t<type1> type;
      |                               ^~~~

是什么导致了这里的问题?

完整的错误消息在这里:

PS D:\Projects\c++\NeuralNetwrokNumbers> g++ -I D:/Projects/c++/eigen network.cpp -o network.exe
In file included from D:/Projects/c++/eigen/Eigen/Core:169,
                 from D:/Projects/c++/eigen/Eigen/Dense:1,
                 from network.cpp:1:
D:/Projects/c++/eigen/Eigen/src/Core/util/Meta.h: In instantiation of 'struct Eigen::internal::result_of<double (Network::*(const double&))(double)>':
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:26:28:   required from 'struct Eigen::internal::traits<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >'
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:97:7:   required from 'class Eigen::CwiseUnaryOpImpl<double (Network::*)(double), const Eigen::Matrix<double, -1, -1>, Eigen::Dense>'
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:58:7:   required from 'class Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> >'     
network.cpp:19:27:   required from here
D:/Projects/c++/eigen/Eigen/src/Core/util/Meta.h:272:61: error: no type named 'type' in 'struct std::invoke_result<double (Network::*)(double), const double&>'
  272 |   typedef typename std::invoke_result<F, ArgTypes...>::type type1;
      |                                                             ^~~~~
D:/Projects/c++/eigen/Eigen/src/Core/util/Meta.h:273:31: error: no type named 'type' in 'struct std::invoke_result<double (Network::*)(double), const double&>'
  273 |   typedef remove_all_t<type1> type;
      |                               ^~~~
In file included from D:/Projects/c++/eigen/Eigen/Core:292:
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h: In instantiation of 'class Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >':
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:51:34:   required from 'class Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >'
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:97:7:   required from 'class Eigen::CwiseUnaryOpImpl<double (Network::*)(double), const Eigen::Matrix<double, -1, -1>, Eigen::Dense>'
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:58:7:   required from 'class Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> >'     
network.cpp:19:27:   required from here
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:79:17: error: 'coeff' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   79 |     using Base::coeff;
      |                 ^~~~~
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:80:17: error: 'coeffByOuterInner' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   80 |     using Base::coeffByOuterInner;
      |                 ^~~~~~~~~~~~~~~~~
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:81:26: error: 'operator()' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   81 |     using Base::operator();
      |                          ^
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:82:26: error: 'operator[]' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   82 |     using Base::operator[];
      |                          ^
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:83:17: error: 'x' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   83 |     using Base::x;
      |                 ^
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:84:17: error: 'y' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   84 |     using Base::y;
      |                 ^
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:85:17: error: 'z' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   85 |     using Base::z;
      |                 ^
D:/Projects/c++/eigen/Eigen/src/Core/DenseBase.h:86:17: error: 'w' has not been declared in 'Eigen::DenseBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   86 |     using Base::w;
      |                 ^
In file included from D:/Projects/c++/eigen/Eigen/Core:293:
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h: In instantiation of 'class Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, 
-1, -1> > >':
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:97:7:   required from 'class Eigen::CwiseUnaryOpImpl<double (Network::*)(double), const Eigen::Matrix<double, -1, -1>, Eigen::Dense>'
D:/Projects/c++/eigen/Eigen/src/Core/CwiseUnaryOp.h:58:7:   required from 'class Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> >'     
network.cpp:19:27:   required from here
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:78:17: error: 'coeff' has not been declared in 'Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   78 |     using Base::coeff;
      |                 ^~~~~
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:81:17: error: 'eval' has not been declared in 'Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   81 |     using Base::eval;
      |                 ^~~~
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:82:25: error: 'operator-' has not been declared in 'Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   82 |     using Base::operator-;
      |                         ^
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:85:25: error: 'operator*=' has not been declared in 'Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   85 |     using Base::operator*=;
      |                         ^~
D:/Projects/c++/eigen/Eigen/src/Core/MatrixBase.h:86:25: error: 'operator/=' has not been declared in 'Eigen::MatrixBase<Eigen::CwiseUnaryOp<double (Network::*)(double), const Eigen::Matrix<double, -1, -1> > >::Base'
   86 |     using Base::operator/=;
      |                         ^~
C++ 结构 体特征

评论

2赞 chtz 10/30/2023
尝试。除非你真的需要访问 的(非静态)成员 -- 在这种情况下,你需要传递某种 lambda 函数或表达式。static double sigmoid(double x){...}Networkstd::bind
1赞 BoP 10/30/2023
若要调用成员函数,代码还需要一个具有此类成员的对象。基本上。可用作指针的东西。this
0赞 Fisteshak 10/31/2023
static double sigmoid(double x){...}工作!所以,据我了解,即使不存在,编译器也应该能够调用函数?double sigmoid(double x){...}Network
0赞 Homer512 11/1/2023
是的,静态成员函数与常规函数类似,但存在于类的命名空间中,可以访问私有成员等

答: 暂无答案