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 = 40y[1]变为2 * 20 + 3 * 5.0 = 40 + 15 = 55y[2]变为2 * 26 + 3 * 6.0 = 52 + 18 = 70y[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 = 14x.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控…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
