我正在使用pybind11为python编写C ++ Eigen扩展。
我希望其中一个扩展类采用一个参数,该参数指定要使用属性的几个函数中的哪个。我的部分问题是,由于我有限的C ++经验,因此我很难阐明这个问题,因此,我希望您能对术语提出任何建议。
在Python中,我想做的简化版本如下所示:
class My_class:
def __init__(self, arg1, option):
self.arg1 = arg1
if option == 'option1'
self.operation = operation1
else:
self.operation = operation2
def my_method(self, arg):
return self.operation(arg, self.arg1)
Run Code Online (Sandbox Code Playgroud)
我尝试遵循此问题的可接受答案,并且具有一个具有函数作为属性的类,尽管它不能按预期工作(如下所述)。
我已尽力构建了一个最小的示例:
#define _USE_MATH_DEFINES
#include "kernels.h"
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
#include <pybind11/stl.h>
#include <Eigen/LU>
#include <Eigen/Dense>
#include <math.h>
#include <unsupported/Eigen/SpecialFunctions>
// ================ Functions
Eigen::MatrixXd operation1(Eigen::Ref<const Eigen::MatrixXd> A, Eigen::Ref<const Eigen::MatrixXd> B){
return A.array() + B.array();
}
Eigen::MatrixXd operation2(Eigen::Ref<const Eigen::MatrixXd> A, Eigen::Ref<const Eigen::MatrixXd> B){
return A.array() * B.array();
}
// ================ Class
class Test
{
private:
Eigen::MatrixXd A;
std::function<Eigen::MatrixXd(Eigen::Ref<const Eigen::MatrixXd>,Eigen::Ref<const Eigen::MatrixXd>)> op;
public:
Test(const Eigen::MatrixXd &xdata, int k);
Eigen::MatrixXd operation(Eigen::Ref<const Eigen::MatrixXd>);
};
// class-constructor
Test::Test(const Eigen::MatrixXd &xdata, int k):A(xdata)
{
switch(k){
case 1:
op = operation1;
case 2:
op = operation2;
}
}
Eigen::MatrixXd Test::operation(Eigen::Ref<const Eigen::MatrixXd> B){
return Test::op(Test::A, B);
}
// ================ pybind11
namespace py = pybind11;
PYBIND11_MODULE(test5,m)
{
m.doc() = "pybind11 example plugin";
py::class_<Test>(m, "Test")
.def(py::init<Eigen::MatrixXd, int>())
.def("operation", &Test::operation)
.def("__repr__",[](const Test &a){return "<example.Test>";}
);
}
Run Code Online (Sandbox Code Playgroud)
不良行为是Test :: op仅绑定到operation2,即operation,无论是否使用k=1或初始化类,都仅在python中调用方法时才乘以数组k=2。
编译扩展后,我在python中进行如下测试:
from test5 import Test
import numpy as np
A = np.random.random((5,5))
B = np.random.random((5,5))
T = Test(A, 1)
np.allclose(T.operation(B), A + B) # Returns False
T = Test(A, 1)
np.allclose(T.operation(B), A * B) # Returns True
T = Test(A, 2)
np.allclose(T.operation(B), A * B) # Returns True
Run Code Online (Sandbox Code Playgroud)
问题:
此switch语句有什么问题?
使用switch语句完成此操作是否明智?结果,我是否放弃了Test :: op内部的任何编译器优化?