002_avoid_for_loop_in_Matlab避免使用for循环

避免使用for循环

在程序设计思想中,循环是一个很有力的工具。在循环中,计算机很轻松地重复执行相同的操作。循环是汇编之上的编程中最重要的概念之一。Matlab的循环有两个语言构造,一个是for循环,另一个是while循环。在Matlab中,for循环是最常用的循环结构。

然而,for循环在Matlab中是非常慢的。这是因为Matlab是一种解释性语言,而不是一种编译性语言。比如,立志于在科学计算领域开辟一“新”道路的Julia语言,其宣传的最重要特点之一就是for循环的速度非常快。

作为经常需要处理大量数据的科学计算工具,Matlab的for循环速度慢是一个很大的问题。因此,我们应该尽量避免使用for循环。

这里有一个说法可以特别地在这里提到,就是所谓的过早优化。过早优化是一种不好的编程习惯。在程序设计的初期,我们应该首先考虑代码的可读性和可维护性。然后,我们应该考虑代码的性能。然而在Matlab中,避免使用for循环并不意味着我们应该在一开始就考虑性能问题。通过采用下面我们提到的方式,编写的Matlab代码的可读性和可维护性也是非常强的。

1. For循环的基本知识

1.1 语法

在Matlab中,for循环的构造如下:

for i = 1:n% do something
end

这个构造同样也可以写成单行的形式:

for i = 1:n, statements, end

如果我们要对一个向量v进行操作,可以使用如下的for循环:

for i = 1:length(v)% do something
end

上面,1:n1:length(v)是for循环的索引。实际上,在Matlab中,:操作符会直接产生一个数组(Matlab最基本的数据结构),并且这个操作符还能够设定步长。比如,1:2:10会产生一个从1到10的数组,步长为2。

for语言构造采用 = 来迭代一个数组。所以,前一个例子里面,可以直接写成:

for vi = v% do something
end

1.2 break和continue

在For循环中,要避免改变索引变量的值来试图改变循环过程,for循环会直接覆盖对这个值的改变。这一点跟很多别的程序设计语言并不相同。

for i = 1:10i = 5; % 这个操作是无效的disp(i);
end

要中途退出一个循环,可以使用关键词break。要跳过当前循环的剩余部分,可以使用关键词continue。

运行一下上面的代码,会打印10个5。

1.3 循环二维数组

另外,我们都知道Matalb的2维数组(矩阵)是列先的,所以在for循环中,对矩阵的操作,应该是按列进行的。比如:

A = [1 2 3; 4 5 6; 7 8 9];
for Ai = Adisp(Ai);
end

上面的代码会打印出矩阵A的每一列。

在这里插入图片描述

Q: 如果上面的A是一个列向量,会怎么样?循环几次?

A: 循环一次。因为列向量是一个列,所以循环一次。

Q: 如果A是一个行向量呢?

A: 行向量有多少个元素,就循环多少次。

这里还挺有意思的,Matlab的for循环是按列进行的,所以对于一个矩阵,我们可以使用for循环来对每一列进行操作。这是一个很有用的特性。而一维数组,列向量和行向量,是一个维数为1的矩阵,所以对于这些数据,for循环的行为是具有一致性的。

2. 避免使用for循环

2.1 算法矩阵化

Matlab是一种矩阵化的语言。这意味着,Matlab的很多操作都是对整个矩阵进行的。与C、Java等语言不同,Matlab的很多操作都是对整个矩阵进行的,Matlab提供了大量针对矩阵进行计算的操作符和操作函数。这些操作符和函数都是高度优化过的,所以在Matlab中,我们应该尽量使用矩阵化的操作。这一点应该是Matlab的使用者在设计算法之初就应该考虑的。

把算法的步骤推导为矩阵的形式,可以为Matlab来实现提供很大的帮助。比如,我们要计算一个向量的平方和,可以使用for循环:

v = [1 2 3 4 5];
sumv = 0;
for vi = vsumv = sumv + vi^2;
end

这里需要注意,如果v是列向量,那么只会循环一次,得到奇怪的结果。(可以自己试试,并思考为什么)

我们可以使用矩阵化的操作:

v = [1 2 3 4 5];
sumv = v * v';

这里用到了行矩阵x列矩阵的乘法。

A m × n × B n × p = C m × p A 1 × n × B n × 1 = c \begin{split} & A_{m \times n} \times B_{n \times p} = C_{m \times p} \\ & A_{1 \times n} \times B_{n \times 1} = c \end{split} Am×n×Bn×p=Cm×pA1×n×Bn×1=c

2.2 计算向量化

Matlab还提供了另外一个非常强大的工具,那就是向量化。向量化就是把操作符应用到一个矩阵的每一个元素上。比如,计算向量平方和,可以用向量化的方法写成:

v = [1 2 3 4 5];
sumv = sum(v.^2);

这里用到一个向量化操作的函数sum和一个向量化算符.^。前者是对矩阵的每一个元素求和,后者是对矩阵的每一个元素进行平方。

Matlab提供了大量的向量化操作符和函数,这些函数和操作符都是高度优化过的

3. 数组的逻辑索引与arrayfun函数

Matlab还提供了一些数组的逻辑操作,这些操作也是高度优化过的。比如,我们要找出一个向量中所有大于5的元素:

v = [1 2 3 4 5 6 7 8 9];
vgt5 = v(v > 5);

这里用到了一个逻辑操作符>,这个操作符会产生一个逻辑数组,然后我们可以用这个逻辑数组来索引原数组。

通过逻辑数组索引,还能够实现很多高级的操作。比如,我们要把一个向量中所有的偶数都变成0:

v = [1 2 3 4 5 6 7 8 9];
v(v % 2 == 0) = 0;

这里用到了一个逻辑操作符==,这个操作符会产生一个逻辑数组,然后我们可以用这个逻辑数组来索引原数组。

可以通过比较复杂的函数来产生逻辑数组,然后用逻辑数组来索引原数组。这样,我们就可以把很多循环操作转化为矩阵化的操作。特别是,用逻辑判断的函数加上arrayfun函数,可以实现很多循环操作。

v = [1 2 3 4 5 6 7 8 9];
predicate = @(x) x > 5 && x < 8;
index = arrayfun(predicate, v);
v(index) = 0;

通过这样的办法,可以写出非常易读的代码,并且也可能会更快。

4. 总结

在Matlab中,for循环是非常慢的。我们应该尽量避免使用for循环。Matlab提供了大量的矩阵化操作符和函数,向量化操作符和函数,逻辑操作符和函数,这些操作符和函数都是高度优化过的。我们应该尽量使用这些操作符和函数,来代替for循环。

  1. 使用矩阵化的操作,从设计和推导算法的时候就采用矩阵来表示;
  2. 使用向量化的操作,对矩阵的每一个元素进行操作;
  3. 使用逻辑索引操作矩阵的部分元素;
  4. 可以考虑使用arrayfun函数来代替for循环。

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

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

相关文章

罗德与施瓦茨联合广和通全面验证RedCap模组FG132系列先进性能

近日&#xff0c;罗德与施瓦茨联合广和通完成Redcap(Reduce Capability)功能和性能验证。本次测试使用R&SCMX500 OBT(One Box Tester)无线通信测试仪&#xff0c;主要验证广和通RedCap模组FG132系列射频性能以及IP层吞吐量&#xff0c;包括RedCap上下行吞吐量和射频指标如矢…

【计算机网络篇】数据链路层(2)封装成帧和透明传输

文章目录 &#x1f95a;封装成帧和透明传输&#x1f388;封装成帧&#x1f388;透明传输&#x1f5d2;️面向字节的物理链路使用字节填充的方法实现透明传输。&#x1f5d2;️面向比特的物理链路使用比特填充的方法实现透明传输。 &#x1f6f8;练习 &#x1f95a;封装成帧和透…

Linux systemd详解

1、概念 1.1 systemd systemd 是一个用于管理 Linux 系统启动过程和系统服务的系统和服务管理器。它被设计为取代传统的 System V init 系统&#xff0c;提供了更快的启动时间、并行启动服务、更好的日志记录和更强大的管理功能。 1.2 unit Unit 是 systemd 中所有配置文件…

基于ssm校园美食交流系统论文

目 录 摘 要 1 前 言 3 第1章 概述 4 1.1 研究背景 4 1.2 研究目的 4 1.3 研究内容 4 第二章 开发技术介绍 5 2.1Java技术 6 2.2 Mysql数据库 6 2.3 B/S结构 7 2.4 SSM框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行性 10 3.1.3 操作可行性 10…

字符函数与字符串函数

目录 一.字符分类函数 二.字符转化函数 三.strlen函数 函数的介绍 strlen函数的模拟实现 1.计算器法 2.递归 三.指针-指针的方式 四.strcpy函数 函数介绍 strcmp的模拟实现 五.strcat函数 函数介绍 strcat的模拟实现 六.strcmp函数 函数介绍 返回值 strcm…

Mysql学习--深入探究索引和事务的重点要点与考点

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

自动驾驶---Motion Planning之轨迹Path优化

1 背景 在之前的几篇文章中,不管是通过构建SL图《自动驾驶---Motion Planning之Path Boundary》,ST图《自动驾驶---Motion Planning之Speed Boundary》,又或者是构建SLT图《自动驾驶---Motion Planning之构建SLT Driving Corridor》,最终我们都是为了得到boundary的信息。 …

OpenCV实战:智能人脸识别打卡系统

1、介绍 目前&#xff0c;很多公司对员工的考勤同时通过打卡机或者钉钉之类的打卡软件&#xff0c;传统的员工打卡方式有很多&#xff0c;例如点名、签字、刷卡、指纹等等 然而随机机器视觉、计算机视觉的不断发展&#xff0c;算力的不断提升&#xff0c;人工智能对人脸检测的…

如何用联合(共用体)union验证系统大小端

一&#xff1a;思路 由联合体的特点&#xff0c;可知上图&#xff0c;char c 和 int i 共用四个字节&#xff0c;假设是小端&#xff0c;则由左到右是低地址到高地址&#xff0c;四个字节的内容如图所示01 00 00 00 代码展示&#xff1a; 如果第一个字节是1&#xff0c;则证明…

<Linux> 线程池

目录 前言&#xff1a; 一、线程池概念 &#xff08;一&#xff09;池化技术 &#xff08;二&#xff09;优点 &#xff08;三&#xff09;应用场景 二、线程池的实现 &#xff08;一&#xff09;线程池_V1&#xff08;朴素版&#xff09; &#xff08;二&#xff09;线…

Nginx发布之后可以使用IP访问,不能使用localhost访问, Nginx发布之后可以使用localhost访问,不能使用IP访问,

如标题所说 Nginx发布之后可以使用IP访问&#xff0c;不能使用localhost访问&#xff0c; Nginx发布之后可以使用localhost访问&#xff0c;不能使用IP访问&#xff0c; 修改配置文件也没有用 清除浏览器缓存数据

配置DHCPV6

组网需求 如果大量的企业用户IPv6地址都是手动配置&#xff0c;那么网络管理员工作量大&#xff0c;而且可管理性很差。管理员希望实现公司用户IPv6地址和网络配置参数的自动获取&#xff0c;便于统一管理&#xff0c;实现IPv6的层次布局。 图1 DHCPv6服务器组网图 配置思路 …

自动化改变金融科技文档生命周期

金融科技公司可能处于软件开发的最前沿&#xff0c;但即使是最先进的系统也必须能够支持金融服务领域采用的一系列文档密集型程序。因此&#xff0c;绝大多数金融科技企业都使用数字文档管理解决方案&#xff0c;无论是内部构建的还是由第三方供应商开发的。金融科技公司可以通…

UI自动化测试面试题小结

列举web自动化中常见的元素定位方式&#xff1f; id&#xff1a;根据id来获取元素&#xff0c;返回单个元素&#xff0c;id值一般是唯一的&#xff1b; name&#xff1a;根据元素的name属性定位&#xff1b; tagName&#xff1a;根据元素的标签名定位&#xff1b; className…

深入理解XML技术(看这一篇就够了)

目录&#xff1a; XMLXML的功能XML基本语法XML组成部分约束DTD约束Schema约束 Jsoup解析器DOMSAXXML常见解析器DOM4JJsoupXPath解析 XML 概念 XML&#xff08;Extensible Markup Language&#xff09;&#xff1a;可扩展标记语言 可扩展&#xff1a;标签都是自定义的。 发展历…

[ C++ ] STL---仿函数与priority_queue

目录 仿函数 示例一&#xff1a; 示例二 : 常见的仿函数 priority_queue简介 priority_queue的常用接口 priority_queue的模拟实现 基础接口 push() 堆的向上调整算法 堆的插入 pop() 堆的向下调整算法 堆的删除 priority_queue最终实现 仿函数 仿函数&#xff…

MusicHiFi: Fast High-Fidelity Stereo Vocoding

MusicHiFi: Fast High-Fidelity Stereo Vocoding 相关链接&#xff1a;arxiv github 关键字&#xff1a;音乐生成、高保真立体声、立体声编解码器、生成对抗网络、频带扩展 摘要 MusicHiFi是一种高效的高保真立体声编解码器&#xff0c;它通过将低分辨率的mel频谱图转换为音频…

【Vue】Vue集成Element-UI框架

&#x1f64b;‍ 一日之际在于晨 ⭐本期内容&#xff1a;Vue集成Element-UI框架 &#x1f3c6;系列专栏&#xff1a;从0开始的Vue之旅 文章目录 Element-UI简介安装Element-UInpm安装CDN安装 引入Element-UI测试是否引入成功总结 Element-UI简介 Element-UI官网&#xff1a;点…

极大提高工作效率的 Linux 命令

作为一名软件开发人员&#xff0c;掌握 Linux 命令是必不可少的技能。即使你使用 Windows 或 macOS&#xff0c;你总会遇到需要使用 Linux 命令的场合。例如&#xff0c;大多数 Docker 镜像都基于 Linux 系统。要进行 DevOps 工作&#xff0c;你需要熟悉Linux&#xff0c;至少要…

vue-quill-editor和vue-ueditor-wrap富文本编辑器应用

目录 一、vue-quill-editor 1.1、界面展示 1.2、代码介绍 1.2.1、安装 1.2.2、配置 1.2.3、代码应用 1.2.4、提取内容 二、vue-ueditor-wrap 2.1、界面展示 2.2、代码介绍 2.2.1、安装 2.2.2、配置 2.2.3、代码应用 一、vue-quill-editor 1.1、界面展示 文本输出…