pybind11(二):使用矩阵类演示 C++ 类的 Python 绑定方法

news/2025/12/8 14:39:58/文章来源:https://www.cnblogs.com/GrootStudy/p/19321703

前面的文章主要介绍了如何在 Python 中调用简单的 C++ 函数,而本篇文章将进一步探讨如何在 Python 中使用 C++ 定义的类及其成员函数。本文将分别在 C++ 和 Python 中实现一个矩阵类,并为其编写矩阵乘法的成员函数。最后,我们将把两种实现与 NumPy 的矩阵乘法进行性能对比,以观察各自的效率差异。

矩阵类实现思路

定义一个矩阵需要三个基本要素:行数、列数以及存储矩阵元素的数据。对于矩阵操作,还需要一些基础方法,例如获取行数或列数,以及设置或读取指定位置的元素。因此,一个矩阵类可以定义如下:

# 矩阵类的伪代码
class Matrix:int rowsint colsvector<float> dataint get_row_num()int get_col_num()void set(int row, int col, float value)float get(int row, int col)

在这个矩阵实现中,我们使用一维数组来存储矩阵的数据,并通过行列索引计算对应的一维下标,从而定位到具体的元素。

矩阵乘法实现思路

这里不使用任何矩阵乘法优化算法,就使用矩阵乘法定义的算法:
设矩阵 \(A\)\(m \times n\),矩阵 \(B\)\(n \times p\),则矩阵 \(C = A B\)\(m \times p\),其中元素 \(c_{ij}\) 的计算方式为:

\[c_{ij} = \sum_{k=1}^{n} a_{ik} b_{kj} \]

# 计算 C = A × B 的伪代码
# A: m × n
# B: n × p
# C: m × pfor i = 0 to m-1:for j = 0 to p-1:C[i][j] = 0for k = 0 to n-1:C[i][j] += A[i][k] * B[k][j]

C++ 矩阵类具体实现

在明确了矩阵类的设计思路后,我们首先给出矩阵类在 C++ 中的完整实现。该实现包含数据存储、元素读写、随机填充、矩阵乘法等核心功能。

#include <cstddef>
#include <cstdlib>
#include <ctime>#include <pybind11/pybind11.h>class Matrix {private:int rows, cols;std::vector<float> data;public:Matrix(int rows, int cols): rows(rows), cols(cols), data(rows * cols, 0.0f) {srand((unsigned)time(NULL));};void set(int row, int col, float value);float get(int row, int col) const;int rows_num() const;int cols_num() const;// 使用随机数填充矩阵void fill_random();Matrix dot(const Matrix &other) const;void print() const;
};
#include "matrix.h"
#include <cstdio>
#include <iostream>
#include <stdexcept>void Matrix::set(int row, int col, float value) {if ((row >= 0 && row < rows) && (col >= 0 && col < cols)) {data[row * cols + col] = value;}return;
}float Matrix::get(int row, int col) const {float value;if ((row >= 0 && row < rows) && (col >= 0 && col < cols)) {value = data[row * cols + col];}return value;
}int Matrix::rows_num() const { return rows; }int Matrix::cols_num() const { return cols; }void Matrix::fill_random() {for (float &i : data) {i = rand() / float(RAND_MAX);}
}Matrix Matrix::dot(const Matrix &other) const {if (other.rows != cols) {std::invalid_argument("Matrix dimisions not match for dot product!");}Matrix result(rows, other.cols);float sum = 0;for (int i = 0; i < rows; i++) {for (int j = 0; j < other.cols; j++) {sum = 0;for (int k = 0; k < cols; k++) {sum += this->get(i, k) * other.get(k, j);}result.set(i, j, sum);}}return result;
}void Matrix::print() const{std::cout << '[' << ' ';for (int i = 0; i < rows_num(); i++) {for (int j = 0; j < cols_num(); j++) {std::cout << get(i, j) << " ";}if (i < rows_num() - 1)std::cout << '\n' << "  ";}std::cout << "]" << '\n';return;
}

使用 pybind11 将 C++ 类导出

为了使 Python 能直接调用 C++ 实现的矩阵类,我们使用 pybind11 将其封装为 Python 扩展模块。通过绑定类的方法、构造函数以及成员函数,Python 端便可像使用普通对象一样创建和操作 C++ 的 Matrix 类实例。以下代码展示如何通过 pybind11 暴露该类。

/*** 简要说明:*   该文件通过 pybind11 暴露了一个名为 "my_matrix" 的 Python 扩展模块。*   模块中注册了一个 Matrix 类(C++ 实现),用于在 Python 中创建和操作矩阵对象。** 导出的主要功能(Python 侧):*   - 类名: my_matrix.Matrix*   - 构造器:*       Matrix(rows: int, cols: int)*         创建一个指定行列数的矩阵(初始内容由底层实现决定)。*   - 实例方法(代表性说明):*       set(i: int, j: int, value)*         在位置 (i, j) 设置元素值(下标约定以实现为准,通常为 0 基或 1 基,参见实现文档)。*       get(i: int, j: int) -> value*         返回位置 (i, j) 的元素值。*       rows_num() -> int*         返回矩阵的行数。*       cols_num() -> int*         返回矩阵的列数。*       fill_random()*         用随机值填充矩阵(随机数分布与范围由实现决定)。*       dot(other)*         矩阵乘法(点乘/矩阵积)。若维度不匹配,应抛出异常或以实现约定处理。*       print()*         将矩阵内容以可读格式输出(用于调试/展示)。**/
#include <pybind11/detail/common.h>
#include <pybind11/pybind11.h>#include "matrix.h"namespace py = pybind11;PYBIND11_MODULE(my_matrix, m){py::class_<Matrix>(m, "Matrix").def(py::init<int, int>()).def("set", &Matrix::set).def("get", &Matrix::get).def("rows_num", &Matrix::rows_num).def("cols_num", &Matrix::cols_num).def("fill_random", &Matrix::fill_random).def("dot", &Matrix::dot).def("print", &Matrix::print);
}

编写 CMakeLists.txt

要成功构建 Python 扩展模块,需要使用 CMake 对项目进行配置。CMakeLists.txt 文件主要负责指定编译选项、寻找依赖库(如 Python、pybind11),并将 C++ 源文件编译为可供 Python 导入的模块。本节给出完整的 CMake 构建脚本,确保项目可以顺利编译运行。

# 最小 CMake 版本要求
cmake_minimum_required(VERSION 3.14)# 定义项目名称为 'matrix',并指定项目使用 C++ 语言。
project(matrix LANGUAGES CXX)# 查找 Python 3 环境。
# COMPONENTS Interpreter Development: 确保找到 Python 解释器和开发头文件/库。
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)# 查找 pybind11 库。
# REQUIRED: 如果找不到 pybind11,则停止配置并报错。
find_package(pybind11 REQUIRED)# 设置 C++ 语言标准为 C++11。pybind11 通常至少需要 C++11。
set(CMAKE_CXX_STANDARD 11)
# 强制要求编译器必须支持设置的 C++ 标准
set(CMAKE_CXX_STANDARD_REQUIRED True)
# 设置默认构建类型为 Release。这会启用优化选项。
set(CMAKE_BUILD_TYPE Release)
# 为 Release 构建类型设置高级优化标志 (-O3)
set(CMAKE_CXX_FLAGS_RELEASE "-O3")# 使用 pybind11 提供的便捷函数来创建 Python 扩展模块。
# 目标名: my_matrix (对应于 Python 中 import my_matrix)
# 源文件: matrix.cpp matrix_bind.cpp
# pybind11 会自动处理链接 Python 库和添加必要的包含目录。pybind11_add_module(my_matrix matrix.cpp matrix_bind.cpp)

编写 python 脚本

在 Python 脚本中,我们同样定义了一个 Matrix 类,其接口设计与 C++ 版本基本一致,用于保持对比的一致性。在主程序中,我们依次使用下列三种方式执行矩阵乘法:

  1. 使用 pybind11 导出的 C++ 版本 Matrix 类
  2. 使用 Python 纯接口实现的 Matrix 类
  3. 使用 NumPy 的矩阵乘法(高度优化)

通过测量三者的运行时间,便可以直观地比较不同语言、不同实现方式的执行效率。

import my_matrix
import numpy as np
import time
import randomclass Matrix:def __init__(self, rows, cols, data):self.rows = rowsself.cols = colsif data is None:self.data = [0.0] * (rows * cols)else:self.data = list(data)def index(self, row, col):return row * self.cols + coldef set(self, row, col, value):if ((row >=0 and row < self.rows) and (col >= 0 and col < self.cols)):self.data[self.index(row, col)] = valuedef get(self, row, col):if ((row >=0 and row < self.rows) and (col >= 0 and col < self.cols)):return self.data[self.index(row, col)]def fill_random(self):for i in range(self.rows * self.cols):self.data[i] = random.random()def dot(self, other):if self.cols != other.rows:raise ValueError("Matrix shapes do not match for multiplication")result = Matrix(self.rows, other.cols, None)for i in range(self.rows):for j in range(other.cols):sum = 0.0for k in range(self.cols):sum += self.get(i, k) * other.get(k, j)result.set(i, j, sum)return resultif __name__ == "__main__":a_rows = 100a_cols = b_rows = 100b_cols = 400a = my_matrix.Matrix(a_rows, a_cols)b = my_matrix.Matrix(b_rows, b_cols)a.fill_random()b.fill_random()start = time.perf_counter()c = a.dot(b)elapsed = time.perf_counter() - startprint(f"my matrix compute time: c computed in {elapsed:.6f} s")a = np.random.rand(a_rows, a_cols).astype(np.float32)b = np.random.rand(b_rows, b_cols).astype(np.float32)start = time.perf_counter()c = np.dot(a, b)elapsed = time.perf_counter() - startprint(f"numpy compute time: c computed in {elapsed:.6f} s")a = Matrix(a_rows, a_cols, None)b = Matrix(b_rows, b_cols, None)a.fill_random()b.fill_random()start = time.perf_counter()c = a.dot(b)elapsed = time.perf_counter() - startprint(f"python matrix compute time: c computed in {elapsed:.6f} s")

实验结果


在小规模矩阵乘法中,C++ 实现表现最为出色,NumPy 次之,而纯 Python 的性能最弱。随着矩阵规模增大,NumPy 的优势逐渐显现,在大规模矩阵乘法中性能最优;C++ 紧随其后;纯 Python 与二者相比则存在巨大差距。

文件结构如下:

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── Makefile
│   ├── matrix.py
│   └── my_matrix.cpython-313-aarch64-linux-gnu.so
├── CMakeLists.txt
├── extern
│   └── pybind11
├── matrix_bind.cpp
├── matrix.cpp
├── matrix.h
├── matrix.py
└── __pycache__

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/992878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年会议室音响设备实力厂家权威推荐:灯光音响设备/专业音响设备/ktv音响设备源头厂家精选

据统计,在超过50人的中大型会议中,超过70% 的与会者曾因音响问题错过关键信息,而一套专业的数字会议系统能将语音清晰度提升40%以上,彻底改变会议沟通的效率与体验。 现代会议室音响系统已从简单的“扩声”工具,演…

2025年GEO 公司哪家好?:权威TOP10榜单精选

2025年GEO 公司哪家好?:权威TOP10榜单精选在AI重塑信息检索方式的浪潮中,越来越多企业将目光投向GEO优化,期望在生成式AI的回答中赢得品牌先机。然而,当用户试图寻找“GEO 公司哪家好 ”时,往往陷入困惑与焦虑:…

2025年度中国设备上锁挂牌服务商家TOP5排行榜,看哪家品

为帮助工业企业精准锁定适配的设备安全管控服务商,避免因选型不当导致安全事故风险,本文从技术合规性(如国际安全认证覆盖度)、方案落地能力(全场景流程适配性)、服务响应速度(724小时应急支持)、客户口碑(头…

2025年气相色谱仪定制十大优质供应商推荐,专业气相色谱仪厂

在分析测试领域,气相色谱仪作为物质分离与检测的核心设备,其性能、定制化能力及服务质量直接影响实验结果与生产效率。面对进口仪器的高成本、服务滞后等痛点,国产气相色谱仪厂商正凭借自主研发实力与高性价比优势崛…

2025年冲锋衣棉服优质供应商/加工厂/生产商十大排行榜,精

为助力企业高效锁定适配的冲锋衣棉服定制合作伙伴,避免选型走弯路,我们从生产工艺稳定性、面料品质把控、定制响应效率、交付保障能力及真实客户口碑五大维度,对多家服务商展开深度评估,终筛选出2025年的10大专业冲…

2025南通装修公司TOP5权威推荐:性价比高的装修公司有哪

随着南通楼市交付高峰的到来,2024年南通家装市场规模突破60亿元,年增速达18%。但市场调研显示,超35%的业主投诉集中在预算超支隐性增项低价陷阱三大问题——不少业主因轻信低价套餐,最终花费比预算高出40%;某小区…

2025年护士服批发厂家权威推荐榜单:洗手衣‌/洗手服‌/病人服‌‌源头厂家精选

在医疗健康产业持续升级的背景下,护士服已从基础工装演变为集专业防护、职业标识、舒适体验与院感控制于一体的功能性装备。市场对产品的需求正朝着 “功能专业化、面料科技化、设计人性化、采购集约化” 深度发展。据…

2025年洛阳老牌民办高中学校权威推荐:洛阳优质民办初中/洛阳老牌私立初中/洛阳初中艺考学校综合盘点

在洛阳市涧西区的一所民办学校里,超过90%的高三教师拥有至少10年以上的一线教学经验,学校历年复读生的成绩平均提升幅度超过80分。 洛阳作为历史文化名城,民办教育已成为其教育体系中不可或缺的重要力量。面对高考升…

Python多进程和多线程的区别:从原理到实战

Python多进程(multiprocessing)和多线程(threading)是实现并发编程的两大核心方式,但适用场景、底层原理、性能表现差异极大。很多新手容易混淆二者,本文从“原理-特性-场景-实战”四层拆解核心区别,结合真实案…

2025年12月旋转接头厂家选购指南:多通路旋转接头/水用旋转接头/回转旋转接头/H型旋转接头/液压旋转接头/高压旋转接头/中央回转接头/优先推荐滕州旭康密封机械,品质与服务双保障

随着工业自动化进程加速、机械设备精密化升级及各行业对传动密封稳定性要求的提升,旋转接头作为连接固定管道与旋转设备的关键部件,已广泛应用于工程机械、能源、化工、机械制造等多个领域,2025 年市场需求持续攀升…

深度剖析Answer与KoalaQA的差异化竞争:从基础问答社区到智能业务中台的全面进化路径解析

深度剖析Answer与KoalaQA的差异化竞争:从基础问答社区到智能业务中台的全面进化路径解析在开源问答社区赛道中,为什么越来越多的企业正在放弃Answer而选择KoalaQA:一场关于效率革命与技术架构的深度思考 当我们在20…

WQ25xx

https://www.cnblogs.com/weizhunie/p/17479759.html 64Mbit = 64 * 1024 *1024 bit = 8MByte = 8192 * 1024Byte = 8192KB 128 Block, 64KB/Block 1 Block = 16 Sector 4KB/Sector 扇区 1 Sector = 16 Page = 256 …

使用fastapi框架,修复访问avif格式的图片时浏览器会触发下载

使用fastapi框架,修复访问avif格式的图片时浏览器会触发下载import mimetypesmimetypes.add_type(image/avif, .avif)mimetypes.add_type(image/webp, .webp)

朴素贝叶斯算法预测中文钓鱼邮件

朴素贝叶斯算法预测中文钓鱼邮件目录大致步骤第一步:准备工具(训练模型)第二步:分析目标邮件(实际判断)1. 提取这封邮件的特征2. 计算两种可能性得分3. 做出判断第三步:现实中的优化朴素贝叶斯算法定义Referenc…

德阳商标购买平台哪家好?2025 最新榜单出炉!适配本地企业首选

在德阳实体经济蓬勃发展、品牌意识日益觉醒的当下,商标早已从单纯的商业标识,升级为企业抢占区域市场、积累用户信任的核心资产。无论是德阳本地初创企业急于落地品牌布局,进军电商、商超等渠道,还是成熟商家拓展产…

2025年车间照明供电规划设计企业权威榜单:车间照明规划/车间照明母线槽/车间照明供电企业精选

一套科学规划的车间照明系统,能让生产线上的产品缺陷检测准确率提升22% ,这是现代化工业制造对光环境提出的新要求。 在工业4.0和智能制造浪潮下,车间照明已远非简单的“点亮”需求。专业的供电规划设计,直接关系到…

2025年圆纸桶定做厂家权威推荐榜单:纸桶‌/焊丝桶‌/方形纸桶‌‌源头厂家精选

在化工、金属线材、医药及食品等行业的包装领域,圆纸桶以其坚固、轻便、环保和经济等综合优势,成为粉状、颗粒及固体物料不可或缺的包装容器。随着绿色包装理念的深入和行业安全标准的提升,市场对纸桶的防潮防腐性能…

2025年度优质石笼网厂商推荐,石笼网批发加工厂哪家技术强全

在水利工程与生态治理领域,石笼网是守护自然防线的隐形铠甲,其材料品质、技术方案与售后服务直接关乎工程安全与生态效益。面对市场上良莠不齐的供应商,如何找到技术强、售后好的优质厂商?以下依据材料品质、定制能…

2025年液体乳酸菌原料源头工厂推荐:菌种多的乳酸菌原料专业

TOP1 推荐:民生中科嘉亿(山东)生物工程有限公司 推荐指数:★★★★★ 口碑评分:国内首推乳酸菌原料源头工厂 专业能力:作为拥有20年益生菌研发生产经验的液体乳酸菌原料源头工厂,民生中科嘉亿(山东)生物工程有…

2025打包机生产厂商年度排名:看看哪家合作案例多?

在全球固废处理与资源回收产业加速升级的背景下,打包机作为减容增效的核心装备,其技术创新力、案例适配性与服务可靠性成为企业选型的关键指标。2024年数据显示,我国打包机市场规模突破120亿元,年增速达28%,但42%…