当前位置: 首页 > news >正文

matlab使用教程(13)—稀疏矩阵创建和使用

        使用稀疏矩阵存储包含众多零值元素的数据,可以节省大量内存并加快该数据的处理速度。sparse 是一种属性,可以将该属性分配给由 double logical 元素组成的任何二维 MATLAB 矩阵。通过 sparse 属性,MATLAB 可以:
        • 仅存储矩阵中的非零元素及其索引。
        • 不必对零元素执行运算,从而减少计算时间。
        对于满矩阵,MATLAB 将在内部存储每个矩阵元素。零值元素与任何其他矩阵元素需要的存储空间量相同。但是,对于稀疏矩阵,MATLAB 只会存储非零元素及其索引。对于零值元素百分比很高的大型矩阵,此方案可以极大地减少存储数据所需的内存量。whos 命令提供有关矩阵存储的高级信息,包括大小和存储类。例如,以下的 whos 列表显示了有关同一矩阵的稀疏版本和完全版本的信息。
M_full = magic(1100); % Create 1100-by-1100 matrix.
M_full(M_full > 50) = 0; % Set elements >50 to zero.
M_sparse = sparse(M_full); % Create sparse matrix of same.
whos
Name Size Bytes Class Attributes
M_full 1100x1100 9680000 double
M_sparse 1100x1100 9608 double sparse
        请注意,稀疏矩阵中使用的字节数较少,因为零值元素未被存储。
        在计算效率方面,稀疏矩阵也具有显著的优点。与满矩阵的运算不同,稀疏矩阵的运算不会执行不必要的低级算术操作,例如加零( x+0 始终为 x )。这样便可大大缩短处理大量稀疏数据的程序的执行时间。

1.创建稀疏矩阵

        MATLAB 从不会自动创建稀疏矩阵。相反,还必须确定矩阵中是否包含足够高百分比的零元素,以便利用稀疏方法。
        矩阵的密度是指非零元素数目除以矩阵元素总数。对于矩阵 M ,这将为
nnz(M) / prod(size(M));
        或
nnz(M) / numel(M);
        密度非常低的矩阵通常很适合使用稀疏格式。

1.1将满矩阵转换为稀疏矩阵

        可以使用带有单个参数的 sparse 函数将满矩阵转换为稀疏存储。例如:
A = [ 0 0 0 5
0 2 0 0
1 3 0 0
0 0 4 0];
S = sparse(A)
S =
(3,1) 1
(2,2) 2
(3,2) 3
(4,3) 4
(1,4) 5
        列显输出中列出了 S 的非零元素及其行索引和列索引。这些元素按列排序,反映了内部数据结构体。如果矩阵阶数不太高,可以使用 full 函数将稀疏矩阵转换为满存储。例如, A = full(S) 可反向转换该示例。
        将满矩阵转换为稀疏存储并非生成稀疏矩阵的最常用方法。如果矩阵的阶数足够低可以进行满存储,则转换为稀疏存储很难显著节省内存。

1.2直接创建稀疏矩阵

        可以使用带有五个参数的 sparse 函数,基于一列非零元素来创建稀疏矩阵。
S = sparse(i,j,s,m,n)
        i j 分别是矩阵中非零元素的行索引和列索引的向量。 s 是由对应的 (i,j) 对指定索引的非零值的向量。 m 是生成的矩阵的行维度, n 是其列维度。前一示例中的矩阵 S 可以直接通过以下表达式生成
S = sparse([3 2 3 4 1],[1 2 2 3 4],[1 2 3 4 5],4,4)
S =
(3,1) 1
(2,2) 2
(3,2) 3
(4,3) 4
(1,4) 5
        sparse 命令具有许多备用形式。上面示例使用的形式将矩阵中的最大非零元素数设置为 length(s)。如果需要,可以追加第六个参数用来指定更大的最大数,这样能在以后添加非零元素,而不必重新分配稀疏矩阵。
        二阶微分算子的矩阵表示形式就是一个很好的稀疏矩阵示例。它是一个三对角矩阵,其中 -2s 在对角线上,1s 在上对角线和下对角线上。有多种方式生成此类炬阵,这里只是一种可能性。
n = 5;
D = sparse(1:n,1:n,-2*ones(1,n),n,n);
E = sparse(2:n,1:n-1,ones(1,n-1),n,n);
S = E+D+E'
S =
(1,1) -2
(2,1) 1
(1,2) 1
(2,2) -2
(3,2) 1
(2,3) 1
(3,3) -2
(4,3) 1
(3,4) 1
(4,4) -2
(5,4) 1
(4,5) 1
(5,5) -2
        现在,F = full(S) 显示相应的满矩阵。
F = full(S)
F =
-2 1 0 0 0
1 -2 1 0 0
0 1 -2 1 0
0 0 1 -2 1
0 0 0 1 -2

1.3基于稀疏矩阵的对角线元素创建稀疏矩阵

        基于稀疏矩阵的对角线元素创建稀疏矩阵是一种常用操作,因此函数 spdiags 可以处理此任务。其语法是
S = spdiags(B,d,m,n)
        要创建大小为 m×n 且元素在 p 对角线上的输出矩阵 S
        • B 是大小为 min(m,n) ×p 的矩阵。 B 的列是用于填充 S 对角线的值。
        • d 是长度 p 的向量,其整数元素可以指定要填充的 S 对角线。
        即,B 的列 j 中的元素填充 d 的元素 j 指定的对角线。
        注意 如果 B 的列长度超过所替换的对角线,则上对角线从 B 列的下部获取,下对角线从 B 列的上部获取。例如,考虑使用矩阵 B 和向量 d
B = [ 41 11 0
52 22 0
63 33 13
74 44 24 ];
d = [-3
0
2];
        使用这些矩阵创建 7×4 稀疏矩阵 A
A = spdiags(B,d,7,4)
A =
(1,1) 11
(4,1) 41
(2,2) 22
(5,2) 52
(1,3) 13
(3,3) 33
(6,3) 63
(2,4) 24
(4,4) 44
(7,4) 74
        在其满矩阵形式中,A 类似于:
full(A)
ans =
11 0 13 0
0 22 0 24
0 0 33 0
41 0 0 44
0 52 0 0
0 0 63 0
0 0 0 74
        spdiags 还可以从稀疏矩阵中提取对角线元素,或将矩阵对角线元素替换为新值。键入 help spdiags 以了解详细信息。

1.4导入稀疏矩阵

        可以在 MATLAB 环境外部通过计算导入稀疏矩阵。结合使用 spconvert 函数与 load 命令导入包含索引和非零元素列表的文本文件。例如,考虑使用三列文本文件 T.dat,它的第一列是行索引列表,第二列是列索引列表,第三列是非零值列表。这些语句将 T.dat 加载到 MATLAB 中并将其转换为稀疏矩阵 S
load T.dat
S = spconvert(T)
        save load 命令还可以处理作为 MAT 文件中的二进制数据存储的稀疏矩阵。

2.访问稀疏矩阵

2.1非零元素

        以下多条命令可以提供有关稀疏矩阵的非零元素的概要信息:
        • nnz 返回稀疏矩阵中的非零元素数。
        • nonzeros 返回包含稀疏矩阵的所有非零元素的列向量。
        • nzmax 返回为稀疏矩阵的非零项分配的存储空间量。
        要尝试上述中的一些命令,请加载提供的稀疏矩阵 west0479 ,该矩阵是 Harwell-Boeing 集合之一。
load west0479
whos
Name Size Bytes Class Attributes
west0479 479x479 34032 double sparse
        该矩阵为八个阶段的化工精馏塔建模。尝试以下命令。
nnz(west0479)
ans =
1887
format short e
west0479
west0479 =
(25,1) 1.0000e+00
(31,1) -3.7648e-02
(87,1) -3.4424e-01
(26,2) 1.0000e+00
(31,2) -2.4523e-02
(88,2) -3.7371e-01
(27,3) 1.0000e+00
(31,3) -3.6613e-02
(89,3) -8.3694e-01
(28,4) 1.3000e+02
nonzeros(west0479)
ans =
1.0000e+00
-3.7648e-02
-3.4424e-01
1.0000e+00
-2.4523e-02
-3.7371e-01
1.0000e+00
-3.6613e-02
-8.3694e-01
1.3000e+02
.
        注意 使用 Ctrl+C 随时停止列出 nonzeros
        请注意,最初在默认情况下,nnz nzmax 的值相同。即,非零元素数等于为非零元素分配的存储位置数。但是,如果将其他的数组元素置零,MATLAB 不会动态释放内存。将某些矩阵元素的值更改为零时会更改 nnz 的值,但不会更改 nzmax 的值。但是,可以根据需要将尽可能多的非零元素添加到矩阵中。不受 nzmax 原始值的限制。

2.2索引和值

        对于任何矩阵,无论是满矩阵还是稀疏矩阵,find 函数都会返回非零元素的索引和值。其语法是
[i,j,s] = find(S);
        find 返回向量 i 中的非零值的行索引、向量 j 中的列索引以及向量 s 中的自身非零值。下面的示例使用find 查找稀疏矩阵中的非零索引和值。 sparse 函数同时使用 find 输出和矩阵大小重新创建矩阵。
S1 = west0479;
[i,j,s] = find(S1);
[m,n] = size(S1);
S2 = sparse(i,j,s,m,n);

2.3稀疏矩阵运算中的索引

        由于稀疏矩阵是以压缩稀疏列格式存储的,因此为稀疏矩阵进行索引的相关成本与为满矩阵进行索引的相关成本不同。在只需更改稀疏矩阵中的若干元素时,这类成本可忽略不计,因此,在这类情况下,通常使用常规数组索引来重新分配值:
B = speye(4);
[i,j,s] = find(B);
[i,j,s]
ans =
1 1 1
2 2 1
3 3 1
4 4 1
B(3,1) = 42;
[i,j,s] = find(B);
[i,j,s]
ans =
1 1 1
3 1 42
2 2 1
3 3 1
4 4 1
        在存储新矩阵时,为使 42 位于 (3,1) 位置,MATLAB 会在非零值向量和下标向量中插入额外的一行,然后移动 (3,1) 后面的所有矩阵值。如果线性索引超过 2^48-1(即当前矩阵中允许的元素数上限),使用线性索引在大型稀疏矩阵中访问或指定元素将失败。
S = spalloc(2^30,2^30,2);
S(end) = 1
Maximum variable size allowed by the program is exceeded.
        要访问其线性索引大于 intmax 的元素,请使用数组索引:
S(2^30,2^30) = 1
S =
(1073741824,1073741824) 1
        尽管在稀疏矩阵中进行索引以更改单个元素的成本可忽略不计,但该成本在循环环境下会增加,而且在大型矩阵中该操作可能会使执行速度变得很慢。因此,在需要更改大量稀疏矩阵元素的情况下,最好使用向量化方法而不要使用循环方法来执行该操作。例如,考虑稀疏单位矩阵:
n = 10000;
A = 4*speye(n);
        以循环方式更改 A 的元素慢于类似的向量化运算:
tic
A(1:n-1,n) = -1;
A(n,1:n-1) = -1;
toc
Elapsed time is 0.003344 seconds.
tic
for k = 1:n-1
C(k,n) = -1;
C(n,k) = -1;
end
toc
Elapsed time is 0.448069 seconds.
        由于 MATLAB 以压缩稀疏列格式存储稀疏矩阵,因此,在循环的每个遍历期间,它都需要移动 A 中的多个条目。如果为稀疏矩阵预分配内存,然后以类似的逐个元素的方式填充,会使对稀疏数组进行索引产生大量开销:
S1 = spalloc(1000,1000,100000);
tic;
for n = 1:100000
i = ceil(1000*rand(1,1));
j = ceil(1000*rand(1,1));
S1(i,j) = rand(1,1);
end
toc
Elapsed time is 2.577527 seconds.
        构建索引和值向量则无需为稀疏数组进行索引,因此这种方法的速度快得多:
i = ceil(1000*rand(100000,1));
j = ceil(1000*rand(100000,1));
v = zeros(size(i));
for n = 1:100000
v(n) = rand(1,1);
end
tic;
S2 = sparse(i,j,v,1000,1000);
toc
Elapsed time is 0.017676 seconds.
        因此,最好使用构造函数(例如 sparse spdiags 函数)一次构造所有稀疏矩阵。例如,假定需要稀疏形式的坐标矩阵 C
4 0 0 0 −1
0 4 0 0 −1
C = 0 0 4 0 −1
0 0 0 4 −1
1 1 1 1 4
        使用 sparse 函数,以及行下标、列下标和值组成的三联对组,直接构造该五列矩阵:
i = [1 5 2 5 3 5 4 5 1 2 3 4 5]';
j = [1 1 2 2 3 3 4 4 5 5 5 5 5]';
s = [4 1 4 1 4 1 4 1 -1 -1 -1 -1 4]';
C = sparse(i,j,s)
C =
(1,1) 4
(5,1) 1
(2,2) 4
(5,2) 1
(3,3) 4
(5,3) 1
(4,4) 4
(5,4) 1
(1,5) -1
(2,5) -1
(3,5) -1
(4,5) -1
(5,5) 4
        输出中值的顺序反映了底层的按列存储。

2.4可视化稀疏矩阵

        以图的形式查看非零元素在稀疏矩阵内的分布通常很有用。MATLAB spy 函数生成稀疏结构的模板视图,其中图表中的每点代表一个非零数组元素的位置。例如:加载提供的稀疏矩阵 west0479 ,该矩阵是 Harwell-Boeing 集合之一。
load west0479
        查看稀疏结构体。
spy(west0479)

 

相关文章:

matlab使用教程(13)—稀疏矩阵创建和使用

使用稀疏矩阵存储包含众多零值元素的数据,可以节省大量内存并加快该数据的处理速度。sparse 是一种属性,可以将该属性分配给由 double 或 logical 元素组成的任何二维 MATLAB 矩阵。通过 sparse 属性,MATLAB 可以: • 仅存储矩…...

UI美工设计的主要职责(合集)

UI美工设计的主要职责1 职责: 1、执行公司的规章制度及专业管理办法; 2、 负责重点项目的原型设计和产品流程设计、视觉设计,优化网站和移动端的设计流程和规范,制定产品 UI/UE规范及文档编写; 3、负责使用PS、AI、illustrator、MarkMan、…...

【前端二次开发框架关于关闭eslint】

前端二次开发框架关于关闭eslint 方法一方法二方法三方法四:以下是若想要关闭项目中的部分代码时: 方法一 在vue.config.js里面进行配置: module.exports {lintOnSave:false,//是否开启eslint保存检测 ,它的有效值为 true || false || err…...

Scractch3.0_Arduino_ESP32_学习随记_蓝牙键盘(三)

C02蓝牙键盘 目的器材程序联系我们 目的 通过C02实现蓝牙键盘 器材 硬件: 齐护机器人C02 购买地址 软件: scratch3.0 下载地址:官网下载 程序 在P5口连接按钮模块。 蓝牙键盘组合按键动作的实现。 当对应按键按下时模拟键盘动作,先按下ctrl然后按下对应组合键…...

Spark2.2出现异常:ERROR SparkUI: Failed to bind SparkUI

详细错误信息如下: 复制代码 19/03/19 11:04:18 INFO util.log: Logging initialized 5402ms 19/03/19 11:04:18 INFO server.Server: jetty-9.3.z-SNAPSHOT 19/03/19 11:04:18 INFO server.Server: Started 5604ms 19/03/19 11:04:18 WARN util.Utils: Service ‘S…...

LeetCode 2811. Check if it is Possible to Split Array【脑筋急转弯;前缀和+动态规划或记忆化DFS】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...

【学习日记】【FreeRTOS】链表结构体及函数详解

写在前面 本文主要是对于 FreeRTOS 中链表相关内容的详细解释,代码大部分参考了野火FreeRTOS教程配套源码,作了一小部分修改。 一、结构体定义 主要包含三种结构体: 普通节点结构体结尾节点(mini节点)结构体链表结…...

【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA)

【云原生•监控】基于Prometheus实现自定义指标弹性伸缩(HPA) 什么是弹性伸缩 「Autoscaling即弹性伸缩,是Kubernetes中的一种非常核心的功能,它可以根据给定的指标(例如 CPU 或内存)自动缩放Pod副本,从而可以更好地管…...

Windows、 Linux 等操作系统的基本概念及其常见操作

Windows 和 Linux 是两种常见的操作系统,它们在计算机领域中广泛使用。下面我将为您介绍它们的基本概念以及一些常见的操作。 **Windows 操作系统:** 1. **基本概念:** Windows 是由微软公司开发的操作系统系列,旨在为个人计算机…...

【RabbitMQ】golang客户端教程5——使用topic交换器

topic交换器(主题交换器) 发送到topic交换器的消息不能具有随意的routing_key——它必须是单词列表,以点分隔。这些词可以是任何东西,但通常它们指定与消息相关的某些功能。一些有效的routing_key示例:“stock.usd.ny…...

SpringBoot对接OpenAI

SpringBoot对接OpenAI 随着人工智能技术的飞速发展,越来越多的开发者希望将智能功能集成到自己的应用中,以提升用户体验和应用的功能。OpenAI作为一家领先的人工智能公司,提供了许多先进的自然语言处理和语言生成模型,其中包括深…...

(C++)继承

目录 1.继承的概念及定义 1.1继承的概念 1.2继承定义 1.2.1定义格式 1.2.2继承方式和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6.继承与静态成员 7.复杂的菱形继承及菱形虚拟…...

图像处理技巧形态学滤波之膨胀操作

1. 引言 欢迎回来,我的图像处理爱好者们!今天,让我们继续研究图像处理领域中的形态学计算。在本篇中,我们将重点介绍腐蚀操作的反向效果膨胀操作。 闲话少说,我们直接开始吧! 2. 膨胀操作原理 膨胀操作…...

机器学习基础之《特征工程(4)—特征降维》

一、什么是特征降维 降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程 1、降维 降低维度 ndarry 维数:嵌套的层数 0维:标量,具体的数0 1 2 3... …...

学生管理系统(Python版本)

class Student:def __init__(self, id, name, age):self.id idself.name nameself.age ageclass StudentManagementSystem:def __init__(self):self.students []def add_student(self, student):self.students.append(student)print("学生信息添加成功!&qu…...

Linux下快速创建大文件的4种方法总结

1、使用 dd 命令创建大文件 dd 命令用于复制和转换文件,它最常见的用途是创建实时 Linux USB。dd 命令是实际写入硬盘,文件产生的速度取决于硬盘的读写速度,根据文件的大小,该命令将需要一些时间才能完成。 假设我们要创建一个名…...

用 Rufus 制作 Ubuntu 系统启动盘时,选择分区类型为MBR还是GPT?

当使用 Rufus 制作 Ubuntu 系统启动盘时,您可以根据您的需求选择分区类型,MBR(Master Boot Record)还是 GPT(GUID Partition Table)。 MBR 是传统的分区表格式,适用于大多数旧版本的操作系统和旧…...

Nodejs+vue+elementui汽车租赁管理系统_1ma2x

语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 前端nodejsvueelementui, 课题主要分为三大模块:即管理员模块、用户模块和普通管理员模块,主要功能包括&#…...

Prometheus入门

Prometheus(普罗米修斯) 是一种 新型监控告警工具,Kubernetes 的流行带动了 Prometheus 的应用。 全文参考自 prometheus 学习笔记(1)-mac 单机版环境搭建[1] Mac 上安装 Prometheus brew install prometheus 安装路径在 /usr/local/Cellar/prometheus/2.20.1, 配置文件在 /usr…...

RISC-V云测平台:Compiling The Fedora Linux Kernel Natively on RISC-V

注释:编译Fedora,HS-2 64核RISC-V服务器比Ryzen5700x快两倍! --- 以下是blog 正文 --- # Compiling The Fedora Linux Kernel Natively on RISC-V ## Fedora RISC-V Support There is ongoing work to Fedora to support RISC-V hardwar…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

JVM垃圾回收机制全解析

Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

网络编程(UDP编程)

思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

管理学院权限管理系统开发总结

文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...