IGraph使用实例——线性代数计算(blas)
1 概述
在图论中,BLAS(Basic Linear Algebra Subprograms)并不直接应用于图论的计算,而是作为一套线性代数计算中通用的基本运算操作函数集合,用于进行向量和矩阵的基本运算。然而,这些基本运算在图论的相关计算中可能会被用到,尤其是涉及到矩阵运算的时候。
BLAS主要包含以下三个级别的函数:
- Level 1 BLAS函数:
- 处理单一向量的线性运算,如向量的加、减、数乘等。
- 处理两个向量的二元运算,如点积、向量外积等。
- Level 2 BLAS函数:
- 处理矩阵与向量的运算,如矩阵与向量的乘积、矩阵的秩1更新等。
- 包含线性方程求解计算,如使用高斯消元法解线性方程组。
- Level 3 BLAS函数:
- 包含矩阵与矩阵的运算,如矩阵乘法、矩阵的三角分解等。
在图论中,如果涉及到矩阵表示的图(如邻接矩阵)、线性方程组的求解(如网络流问题中的势能法)或者特征值问题(如图的谱分析)等,就可能会使用到BLAS库中的函数。
2 运行环境
操作系统:win10 64位
编程语言:C/C++
编译平台:vs2019 x64 debug | release
igraph版本: 0.10.12
3 示例代码
在IGraph中的blas.c文件中提供了丰富的功能来处理图和网络数据结构。这个特定的文件包含了一些使用BLAS(Basic Linear Algebra Subprograms)库的函数,用于执行线性代数操作,如矩阵-向量乘法、矩阵-矩阵乘法、向量的欧几里得范数计算和向量的点积。
文件中定义了几个函数,每个函数都与特定的线性代数操作相关:
-
igraph_blas_dgemv
:执行矩阵-向量乘法,使用BLAS库中的dgemv
函数。它支持矩阵的转置操作,并允许用户指定alpha和beta系数。 -
igraph_blas_dgemm
:执行矩阵-矩阵乘法,使用BLAS库中的dgemm
函数。它同样支持矩阵的转置操作,并允许用户指定alpha和beta系数。 -
igraph_blas_dgemv_array
:与igraph_blas_dgemv
类似,但是它接受C语言数组作为输入,而不是IGraph库中的向量对象。 -
igraph_blas_dnrm2
:计算向量的欧几里得范数,使用BLAS库中的dnrm2
函数。 -
igraph_blas_ddot
:计算两个向量的点积,使用BLAS库中的ddot
函数。
3.1 示例1
在下列代码中使用了igraph
库,特别是它的线性代数部分(通过igraph_blas
函数集)来进行一些基本的矩阵和向量运算。
#include <igraph.h> // 引入igraph库的头文件 int main(void) { // 定义igraph的矩阵和向量对象 igraph_matrix_t m; igraph_vector_t x, y, z; igraph_real_t xz, xx; // 用于存储计算结果的两个实数变量 // 初始化向量x,包含3个元素,分别为1.0, 2.0, 3.0 igraph_vector_init_real(&x, 3, 1.0, 2.0, 3.0); // 初始化向量y,包含4个元素,分别为4.0, 5.0, 6.0, 7.0 // 注意:虽然y之后会被用于计算,但这里先初始化为一些值 igraph_vector_init_real(&y, 4, 4.0, 5.0, 6.0, 7.0); // 初始化向量z,包含3个元素,分别为-1.0, 0.0, 0.5 igraph_vector_init_real(&z, 3, -1.0, 0.0, 0.5); // 初始化一个4x3的矩阵m,并为其赋值 igraph_matrix_init(&m, 4, 3); // 填充矩阵m的元素 MATRIX(m, 0, 0) = 1;MATRIX(m, 0, 1) = 2;MATRIX(m, 0, 2) = 3;MATRIX(m, 1, 0) = 2;MATRIX(m, 1, 1) = 3;MATRIX(m, 1, 2) = 4;MATRIX(m, 2, 0) = 3;MATRIX(m, 2, 1) = 4;MATRIX(m, 2, 2) = 5;MATRIX(m, 3, 0) = 4;MATRIX(m, 3, 1) = 5;MATRIX(m, 3, 2) = 6;// 计算 2 * m.x + 3 * y,并将结果存储在y中 // 注意:这里的操作会改变y的内容 igraph_blas_dgemv(/* transpose= */ 0, /* alpha= */ 2, &m, &x, /* beta= */ 3, &y); // 打印向量y的新内容 igraph_vector_print(&y); // 计算向量x的模的平方(即x与自身的点积),存储在xx中 igraph_blas_ddot(&x, &x, &xx); // 计算向量x和z的点积,存储在xz中 igraph_blas_ddot(&x, &z, &xz); // 打印结果 printf("x.x = %g, x.z = %g\n", xx, xz); // 销毁之前创建的矩阵和向量对象,释放内存 igraph_matrix_destroy(&m); igraph_vector_destroy(&z); igraph_vector_destroy(&y); igraph_vector_destroy(&x); return 0;
}
3.2 示例2
以下代码使用BLAS(Basic Linear Algebra Subprograms)库中的dgemm
(Double-precision General Matrix Multiply)函数来执行两个矩阵的乘法,并将结果存储在第三个矩阵中。
// 引入igraph库的头文件
#include <igraph.h> int main(void) { // 声明三个igraph_matrix_t类型的变量a, b, c,用于存储矩阵 igraph_matrix_t a, b, c; // 初始化一个2x2的矩阵a,并为其分配内存 igraph_matrix_init(&a, 2, 2); // 设置矩阵a的元素 MATRIX(a, 0, 0) = 1; // a[0][0] = 1 MATRIX(a, 0, 1) = 2; // a[0][1] = 2 MATRIX(a, 1, 0) = 3; // a[1][0] = 3 MATRIX(a, 1, 1) = 4; // a[1][1] = 4 // 初始化一个2x2的矩阵b,并为其分配内存 igraph_matrix_init(&b, 2, 2); // 设置矩阵b的元素 MATRIX(b, 0, 0) = 5; // b[0][0] = 5 MATRIX(b, 0, 1) = 6; // b[0][1] = 6 MATRIX(b, 1, 0) = 7; // b[1][0] = 7 MATRIX(b, 1, 1) = 8; // b[1][1] = 8 // 初始化一个2x2的矩阵c,用于存储a和b的乘法结果 igraph_matrix_init(&c, 2, 2); // 使用igraph_blas_dgemm函数计算a和b的乘积,并将结果乘以0.5后存储在c中 // 第一个和第二个参数分别是矩阵a和b的alpha(这里是1,即不缩放) // 第三个参数是缩放因子(这里是0.5) // 第四和第五个参数是矩阵a和b的指针 // 第六个参数是矩阵c的beta(这里是0,即不使用c的原始值) // 第七个参数是结果矩阵c的指针 igraph_blas_dgemm(1, 1, 0.5, &a, &b, 0, &c); // 打印矩阵c的内容 igraph_matrix_printf(&c, "%g"); // 释放矩阵a, b, c所占用的内存 igraph_matrix_destroy(&a); igraph_matrix_destroy(&b); igraph_matrix_destroy(&c); // 程序正常退出 return 0;
}
4 运行结果
4.1 结果1
首先,我们初始化了几个向量x
, y
, z
和一个矩阵m
。然后为矩阵m
赋值了一个4x3的矩阵。
在第一个igraph_blas_dgemv
函数调用中,我们试图计算2 * m * x + 3 * y
并将结果存储在y
中。但是,请注意,由于igraph_blas_dgemv
的默认操作是y = alpha * A * x + beta * y
(其中A
是矩阵,x
和y
是向量,alpha
和beta
是标量),因此,实际上是在更新y
的值,而不是简单地计算结果。由于y
的初始值不为零,这会影响最终结果。
y
向量初始化为[4.0, 5.0, 6.0, 7.0]
。在调用igraph_blas_dgemv
后,y
将被更新为2 * m * x + 3 * y
。
矩阵m
与向量x
的乘法结果是一个4x1的向量,其值为[1*1 + 2*2 + 3*3, 2*1 + 3*2 + 4*3, 3*1 + 4*2 + 5*3, 4*1 + 5*2 + 6*3]
,即[14, 20, 26, 32]
。
然后,我们将这个结果与y
的初始值相加,并乘以相应的系数:
y[0]
变为2 * 14 + 3 * 4.0 = 28 + 12 = 40
y[1]
变为2 * 20 + 3 * 5.0 = 40 + 15 = 55
y[2]
变为2 * 26 + 3 * 6.0 = 52 + 18 = 70
y[3]
变为2 * 32 + 3 * 7.0 = 64 + 21 = 85
因此,y
向量的最终值是[40, 55, 70, 85]
。
接下来,我们使用igraph_blas_ddot
来计算x
与x
的点积(即x.x
),以及x
与z
的点积(即x.z
)。这些计算的结果是:
x.x
是[1.0, 2.0, 3.0]
与[1.0, 2.0, 3.0]
的点积,即1*1 + 2*2 + 3*3 = 14
x.z
是[1.0, 2.0, 3.0]
与[-1.0, 0.0, 0.5]
的点积,即1*(-1) + 2*0 + 3*0.5 = -1 + 1.5 = 0.5
因此输出x.x = 14, x.z = 0.5
。
4.2 结果2 
根据矩阵乘法的定义和给定的代码,矩阵a
和b
的乘积再乘以0.5会得到矩阵c
,其元素计算如下:
a = [1 2; 3 4]
b = [5 6; 7 8]
c = 0.5 * (a * b)
矩阵乘法a * b
的结果为:
[1*5 + 2*7 1*6 + 2*8; 3*5 + 4*7 3*6 + 4*8] = [1 + 14 6 + 16; 15 + 28 18 + 32] = [15 22; 43 50]
然后,我们将这个结果乘以0.5得到矩阵c
:
c = [15*0.5 22*0.5; 43*0.5 50*0.5] = [7.5 11; 21.5 25]
最后程序执行结果如下:
11.5 15.5
17 23
相关文章:

IGraph使用实例——线性代数计算(blas)
1 概述 在图论中,BLAS(Basic Linear Algebra Subprograms)并不直接应用于图论的计算,而是作为一套线性代数计算中通用的基本运算操作函数集合,用于进行向量和矩阵的基本运算。然而,这些基本运算在图论的相…...

【MySQL】(基础篇五) —— 排序检索数据
排序检索数据 本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检索出的数据。 排序数据 还是使用上一节中的例子,查询employees表中的last_name字段 SELECT last_name FROM employees;输出结果: 发现其输出并没有特定的顺序。其实…...
C++ C_style string overview and basic Input funcitons
write in advance 最近在做题,遇到一个简单的将console的输入输出到文件中的简单题目,没有写出来。悔恨当初没有踏实地总结string 相关的 I/O 以及与文件的操作。这篇文章旨在记录基础的字符I/O, 简单常用的文件I/O操作函数。 当然,你会说C…...

VS2022+Qt雕刻机单片机马达串口上位机控制系统
程序示例精选 VS2022Qt雕刻机单片机马达串口上位机控制系统 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《VS2022Qt雕刻机单片机马达串口上位机控制系统》编写代码,代码整洁&a…...

Android Ble低功耗蓝牙开发
一、新建项目 在Android Studio中新建一个项目,如下图所示: 选择No Activity,然后点击Next 点击Finish,完成项目创建。 1、配置build.gradle 在android{}闭包中添加viewBinding,用于获取控件 buildFeatures {viewB…...
Visual Studio的快捷按键
Visual Studio的快捷按键对于提高编程效率至关重要。以下是一些常用的Visual Studio快捷按键,并按照功能进行分类和归纳: 1. 文件操作 Ctrl O:打开文件Ctrl S:保存文件Ctrl Shift S:全部保存Ctrl N:…...

【WEB系列】过滤器Filter
Filter,过滤器,属于Servlet规范,并不是Spring独有的。其作用从命名上也可以看出一二,拦截一个请求,做一些业务逻辑操作,然后可以决定请求是否可以继续往下分发,落到其他的Filter或者对应的Servl…...

[书生·浦语大模型实战营]——LMDeploy 量化部署 LLM 实践
1.基础作业 1.1配置 LMDeploy 运行环境 创建开发机 创建新的开发机,选择镜像Cuda12.2-conda;选择10% A100*1GPU;点击“立即创建”。注意请不要选择Cuda11.7-conda的镜像,新版本的lmdeploy会出现兼容性问题。其他和之前一样&…...

TiDB-从0到1-配置篇
TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇 一、系统配置 TiDB的配置分为系统配置和集群配置两种。 其中系统配置对应TiDB Server(不包含TiKV和PD的参数࿰…...
微信小程序按钮设计与交互:打造极致用户体验
微信小程序作为一种流行的应用形式,其界面设计和交互体验对于用户吸引力和留存率至关重要。其中,按钮作为用户与小程序进行交互的主要方式之一,其设计和实现直接影响到用户体验的质量。在本文中,我们将探讨微信小程序按钮的设计与…...
ES6中如何使用class和extends关键字实现继承?
在ES6中,可以使用class关键字来定义类,使用extends关键字来实现继承。下面是一个示例: // 父类 class Parent {constructor(name) {this.name name;}sayHello() {console.log(Hello, my name is ${this.name});} }// 子类 class Child ex…...

Linux:基本指令
文章目录 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令 && rm指令cp指令man指令echo指令输出重定向追加重定向 cat指令输入重定向 mv指令which指令alias指令more && less指令head && tail指令事件相关的指令date显示时间戳 cal指令find指令grep指令…...
商业C++静态代码检测工具PC-lint Plus 、 polysace和sonarqube对比
商业C静态代码检测工具PC-lint Plus 、 polysace和sonarqube对比 特性/工具PC-lint PlusPolyspaceSonarQube主要功能高精度静态代码分析、编码标准检查高级静态分析和形式验证、优化嵌入式系统综合性代码质量管理、静态分析、技术债务管理集成方式可集成到IDE和构建系统与开发…...
邬家桥公园
文|随意的风 原文地址 我游览过现存规模最大、保存最完整的皇家园林颐和园,瞻仰过拥有世界上最大祭天建筑群的天坛公园,那都是多年前的事情了。 邬家桥公园相比颐和园、天坛公园,气势雄伟倒谈不上。它没有西湖的水平如镜ÿ…...
Flutter 中的 RenderObjectToWidgetAdapter 小部件:全面指南
Flutter 中的 RenderObjectToWidgetAdapter 小部件:全面指南 Flutter 是一个功能强大的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的渲染体系中,RenderObjectToWidgetAdap…...

SNAT与DNAT
一、SNAT策略概述 1、SNAT 策略的典型应用环境 局域网主机共享单个公网IP地址接入Internet(私有IP不能在Internet中正常路由) 局域共享上网 2、 SNAT 策略的原理 修改数据包的源地址 把从内网 --> 外网的数据的源内网地址转换成公网源地址 3、SN…...
MySql八股文知识点总结,一篇文章让mysql成为面试加分项
MySql八股文知识点总结(自检) 1.前言 参与了几次中大厂的面试,你会发现一面时对于八股文的考察也具有侧重点(MySQLRedis > 网络 > 系统 >设计模式 > java集合 >spring) 本文的目标就是通过这一篇文章让你能在面…...

Python 很好用的爬虫框架:Scrapy:
了解Scrapy 爬虫框架的工作流程: 在scrapy中, 具体工作流程是这样的: 首先第一步 当爬虫引擎<engine>启动后, 引擎会到 spider 中获取 start_url<起始url> 然后将其封装为一个request对象, 交给调度器<…...
C/C++|关于 namespace 在C++中的代码组织
命名空间(namespace)在C中用于组织代码,避免命名冲突,并提供更好的代码结构和可读性。下面详细解释命名空间在C多文件编写中的各种作用和表达。 基本概念 命名空间是一个声明区域,用于组织代码,防止不同部…...

selenium自动化测试入门 —— 上传文件
selenium无法识别非web的控件,上传文件窗口为系统自带,无法识别窗口元素。 上传文件有两种场景:input控制上传和非input控件上传。 大多数情况都是input控件上传文件,只有非常少数的使用自定义的非input上传文件。 一、input控…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
python读取SQLite表个并生成pdf文件
代码用于创建含50列的SQLite数据库并插入500行随机浮点数据,随后读取数据,通过ReportLab生成横向PDF表格,包含格式化(两位小数)及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...
P10909 [蓝桥杯 2024 国 B] 立定跳远
# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上,小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时࿰…...