You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cython中如何将Numpy矩阵列表映射为Eigen矩阵std::vector

解决方案

第一步:修复C++头文件的类型声明错误

你的第一个编译错误是C侧找不到FlattenedMapWithOrder,本质是Cython层面的FlattenedMapWithOrder是eigency提供的语法糖,C原生侧没有这个类型名,我们直接在C++侧用原生Eigen类型声明函数即可,避免和eigency的内部类型耦合。
修改后的cpp_source_cpp.h对应部分如下:

// 保留原有头文件引入,仅修改函数声明
float MyCppFunction(
    const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>& inputMatrix
    );

// 直接用Eigen::Map的vector作为参数类型
float MyCppFunctionVector(
    const std::vector<Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>>& inputMatrixList
    );

第二步:修改Cython侧的函数声明和实现

C不允许不同模板参数的std::vector直接隐式转换(哪怕元素类型可转换也不行),所以我们直接把Cython侧vector的元素类型声明为和C侧对齐的Eigen Map类型,单个FlattenedMapWithOrder实例可以隐式转换为Eigen Map,循环插入的时候完成转换即可。
修改cython_source.pyx的对应部分:

# 保留原有引入,修改外部函数声明
cdef extern from "source_cpp_cython/cpp_source_cpp.h":
    cdef float _MyCppFunction "MyCppFunction"(
                FlattenedMapWithOrder[Matrix, float, Dynamic, Dynamic, RowMajor] &
                )

    # 声明参数为Eigen Map类型的vector
    cdef float _MyCppFunctionVector "MyCppFunctionVector"(
                vector[Map[Matrix, float, Dynamic, Dynamic, RowMajor]] &
                )


# 单矩阵函数保持原有实现不变
def my_python_function(np.ndarray[ndim=2, dtype=np.float32_t] my_matrix):
    cdef FlattenedMapWithOrder[Matrix, float, Dynamic, Dynamic, RowMajor] my_matrix_cpp
    my_matrix_cpp = FlattenedMapWithOrder[Matrix, float, Dynamic, Dynamic, RowMajor](my_matrix)
    return _MyCppFunction(my_matrix_cpp)


# 修改列表处理函数的实现
def my_python_function_vector(list my_matrix_list):
    # vector元素类型和C++函数要求对齐
    cdef vector[Map[Matrix, float, Dynamic, Dynamic, RowMajor]] matrix_map_vec
    cdef FlattenedMapWithOrder[Matrix, float, Dynamic, Dynamic, RowMajor] my_matrix_cpp

    for my_matrix in my_matrix_list:
        my_matrix_cpp = FlattenedMapWithOrder[Matrix, float, Dynamic, Dynamic, RowMajor](my_matrix)
        # 单个实例隐式转换为Eigen Map后插入vector
        matrix_map_vec.push_back(my_matrix_cpp)

    return _MyCppFunctionVector(matrix_map_vec)

第三步:修改C++侧的函数实现

现在C++侧接收的参数已经是原生Eigen Map的vector,不需要额外转换,直接使用即可:
修改cpp_source_cpp.cpp的对应部分:

#include "cpp_source_cpp.h"

float MyCppFunction(
    const Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>& inputMatrix
    )
{
    return 5.0;
}

float MyCppFunctionVector(
    const std::vector<Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>>& inputMatrixList
    )
{
    // 直接使用inputMatrixList执行业务逻辑即可
    return 6.0;
}

原理说明

C中std::vector<T>和std::vector<U>是完全独立的两个类型,哪怕T可以隐式转换为U,两个vector类型之间也没有任何内置转换关系,这是你之前类型不匹配报错的核心原因。而单个eigency::FlattenedMap实例可以隐式转换为Eigen::Map,所以只需要在插入vector的时候完成单个元素的转换,让整个vector的元素类型和C函数要求的类型完全对齐即可。

内容的提问来源于stack exchange,提问作者Stefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:48:00