heun 方法 matlab代码_MATLAB中代码优化的两种方法

2023-11-06

MATLAB中的代码优化

MATLAB中的代码优化有两种重要的方法:预分配组和向量化循环。

我们举一个简单的例子来看,创建一个MATLAB函数来计算f(x) = sin(x / 100π):

function y = sinfun1(M)
x = 0: M - 1;
for k = 1: numel(x)
y(k) = sin(x(k) / (100 * pi));
end
  • 1

  • 2

  • 3

  • 4

  • 5

这里 我们使用函数timeit来计算调用函数所需的时间。(timeit可用于得到函数调用的可靠的、可重复的时间测量。)

此时我们得到M数量级为20000时的时间测量,如图1所示:

3b7c028ed96762e60f20af34899e1cda.png

图1 函数sinfun1在M=20000的时间测量

我们在编写完函数sinfun1后可以看到MATLAB编辑器给出了一个提示:变量’y’似乎会随迭代次数而改变,请预分配内存以获得更高的运算速度。

为什么会出现这样的情况?那是因为在sinfun1这个函数中,输出变量y每经过一次循环后都会增长一个元素大小,它必须重新分配新的存储空间,并且在每次数组生长时都要复制前一组数组元素。这种频繁的内存重新分配和复制的开销非常大,与sin本身的计算相比需要更多的时间。

此时我们采用预分配数组的办法进行尝试:

预分配组:是指在进入一个计算数组元素的for循环之前,初始化数组。预分配就意味着咋循环开始之前把它初始化为所希望的输出大小。

function y = sinfun2(M)
x = 0: M - 1;
y = zeros(1, numel(x));
for k = 1: numel(x)
y(k) = sin(x(k) / (100 * pi));
end
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

在这里我们使用了zeros生成一个矩阵来预分配存储空间,然后调用timeit计算M=20000时候的时间测量,如图2:

46109608a5e10cceba709d71e5e452f4.png

图1 函数sinfun2在M=20000的时间测量

通过对比可以得出,在M=20000的数量级下,使用预分配数组的办法,要比不使用运行快4倍。接下来我们在M的数量级为200000和2000000下对两种方法进行比较,得出的结果如图3,图4所示:

722bf88aafc21a3aa991960031542839.png

图3 两种方法在M=200000下的时间测量

c44f27afe6245b0d7138ca4cdea260ac.png

图4 两种方法在M=2000000下的时间测量

我们通过计算可以得出,函数sinfun1基本维持了所要求的的时间与M成正比,sinfun2则在数量级到了一定程度后维持正比。另外比较两个函数在200000和2000000下的速度比,可见在这两个数量级下预分配数组的方法大约要比sinfun1快6倍。

向量化循环是指使用矩阵/向量运算符、索引技术和现有的MATLAB或工具箱函数来完全消除循环的一种技术。

我们使用向量化循环对矩阵的输入进行逐元素的操作来消除循环:

function y = sinfun3(M)
x = 0: M - 1;
y = sin(x ./ (100 * pi));
end
  • 1

  • 2

  • 3

  • 4

此时我们再用timit在M=20000时进行时间测量,如图5:b74e9a776137e188d2652b476cd54a5d.png

图5 函数sinfun3在M=20000的时间测量

由图可知我们使用向量化时,在M=20000时要比预分配数组快3倍。接下来测量M的数量级为200000和2000000的时间。如图6所示:5cf7880d9529f7d4203168fd6408d8fd.png

图6 函数sinfun3在M=200000和2000000的时间测量

由此可见,不带循环sinfun3的执行速度和带一个循环的sinfun2的执行速度大致相同,但又略快于sinfun2。在教材中为了为了更好地说明这个比较两种优化方法,给出了下面这个例子。

这个例子是基于公式f(x) = Asin(u0x + v0y)创建一幅合成图像,首先使用嵌套的for循环来计算f:

function f = twodsin1(A, u0, v0, M, N)
%f = zeros(M, N);
for c = 1 : N
v0y = v0 * (c - 1);
for r = 1 : M
u0x = u0 * (r - 1);
f(r, c) = A * sin(u0x + v0y);
end
end
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

不使用预分配和使用后的执行时间如图7所示:ceb4e188c5af926fb29d28385ab48621.png

图7 函数twodsin1使用预分配的前后比较

我们在这里发现使用预分配前后,执行时间的差距并没有很大。接下来来看向量化后的结果。

在实验中使用一个meshgrid的MATLAB函数将函数重写为没有for循环的形式。

function f = twodsin2(A, u0, v0, M, N)
r = 0 : M - 1;
c = 0 : N - 1;
[C, R] = meshgrid(c, r);
f = A * sin(u0 * R + v0 * C);
  • 1

  • 2

  • 3

  • 4

  • 5

继续用timeit测试,得到的结果如图8:46aff04786803ea5b2a783507e8f969c.png

图8 函数twodsin2的时间测量

可见使用向量化后,比使用预分配快了30%,比不使用任何优化方法快了50%。

小结

综合以上两个实验表明,两种代码优化方法(预分配数组和向量化循环)在具体的使用中的差别并不是很大,都可以提升循环运行的速度。我们可以在遇到具体问题后,根据具体情况选择具体的方法:若是循环存在没有预分配内存的问题,那我们可以考虑采用预分配的方法,这样对代码的改动不大,更直观,也更容易表示我们代码得到实际工作机理;若是确定没有预分配的问题,就可以选择向量化循环的办法,这样与基于循环的代码相比,向量化后的代码更易于阅读,更为简洁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

heun 方法 matlab代码_MATLAB中代码优化的两种方法 的相关文章

  • vtkPythonAlgorithm 控制管道执行

    我正在尝试用 python 编写一个 vtk 过滤器ProjectDepthImage进行投影不是问题 它控制 vtk 管道的执行 基本上 我对 UserEvent 有一个回调 当用户在渲染窗口处于活动状态时按下 u 键时会触发该回调 这将
  • 媒体文件上的 404 - Django

    昨晚我将项目上传到 pythonanywhere com 我想在那里测试我的项目生产设置 在我允许的模型之一中用户上传JPG 团队徽标 上传过程运行良好 文件位于我的 MEDIA ROOT 中 问题是 当我尝试在模板中访问它 以将其显示在页
  • 将 Web 场迁移到 ASP.NET 运行时版本 4,同时保持会话

    我们已将 Web 应用程序从 net 运行时 2 v 3 5 迁移到 net 运行时 4 v 4 5 我有一个部署问题 我们的 sessionstate 服务器是一个 stateserver 并在单独的服务器上运行框架 2 中的 aspne
  • 如何获取打印机设备上下文?

    我在 Windows 上尝试使用以下命令打印增强型图元文件 EMF 播放增强元文件 http msdn microsoft com en us library dd162800 28VS 85 29 aspx 我当前正在使用屏幕上窗口的设备
  • Data-config.xml 和 mysql - 我只能加载“id”列

    我在 Windows Server 2012 上安装了 Solr 5 0 0 我想将表中的所有数据加载到 solr 引擎中 我的 data config xml 如下所示
  • 脚本块上的新闭包

    考虑这段代码 PS gt timer New Object Timers Timer PS gt timer Interval 1000 PS gt i 1 PS gt Register ObjectEvent timer Elapsed
  • Eclipse 有 IntelliJ Keymapping 插件吗?

    我是一位 IntelliJ 老用户 现在正在从事一个需要 Eclipse 的项目 我不介意学习 Eclipse 默认键盘快捷键 如果有 但是很多操作都没有分配快捷键 grrrr 我想知道是否有任何插件可以自动将 IntelliJ 默认值分配
  • Arduino 串行输出丢弃字符

    当我尝试为我的 Arduino Uno 编写一些代码时 我遇到了一个奇怪的串行输出 我有这个原始代码 MyClass myclass void setup Serial Begin 9600 Serial println Starting
  • 为什么格式化程序不适用于隔离范围?

    为什么格式化程序不适用于隔离范围 这是有角度的错误还是我做错了什么 这包含隔离范围并且不起作用 http jsfiddle net YbdXQ 56 http jsfiddle net YbdXQ 56 restrict A scope l
  • 通过 jquery,设置为 html-select 元素的选项,通过文本而不是值选择属性

    我有一个选择元素
  • 每次 apache 重新启动时,flask-login 会话都会被破坏

    我正在使用烧瓶登录https github com maxcountryman flask login https github com maxcountryman flask login和领域记住登录用户 http packages py
  • 如何找到数组中的最小数字并返回该数组的主索引?

    我有一个如下所示的数组 我想找到 diff 索引中数字最小的数组 所以在这种情况下 我想取回数组 7 我需要的只是数组编号 即 7 而不是任何其他信息 我知道我可以使用 array column 轻松找到最小的数字 但如何返回整个数组索引
  • 文件按文件名模式存在

    我在用 File Exists filepath 我想做的是将其替换为模式 因为文件名的第一部分发生了变化 例如 该文件可以是 01 peach xml 02 peach xml 03 peach xml 如何根据某种搜索模式检查文件是否存
  • pylint:忽略 rcfile 中的多个

    在我的 django 项目中 我使用的是外部编写的应用程序 但编写得很糟糕 现在我想从我的 pylint 报告中忽略这个应用程序 但是我无法让 pylint 忽略它 Pylint 已经忽略了南方的迁移 如下所示 MASTER ignore
  • Android ACTION_MOVE阈值

    我正在编写一个应用程序 需要使用手指或最终使用手写笔在屏幕上书写 我有那部分工作 在 ACTION DOWN 时 开始绘制 在 ACTION MOVE 上 添加线段 在 ACTION UP 上 完成该行 问题是 在 ACTION DOWN
  • 如何使用socket.io处理节点服务器上的并发文件写入请求

    如何使用 socket io 处理节点服务器上的并发文件写入请求 我用这个来写 fs writefile abc txt datatobewritten utf8 function err 我有一个文件 abc txt 假设两个用户尝试同时
  • Apollo 服务器,Graphql - 必须提供查询字符串

    我不确定我在这里做错了什么 我现在已经被困了一段时间 让我的突变在无服务器设置中与我的 apollo server lambda 一起运行 当我尝试运行这样的查询时 我的查询工作正常 mutation signIn username Som
  • Encog:BasicNetwork:无需预先构建数据集的在线学习

    我正在尝试使用 encog 库作为强化学习问题的函数逼近器 更准确地说 我正在尝试启动并运行多层感知器 BasicNetwork 由于我的代理将根据我选择的任何 RL 算法以某种方式探索世界 因此我无法预先构建任何 BasicNeuralD
  • Python 线程与 Linux 中的多处理

    基于此question https stackoverflow com questions 807506 threads vs processes in linux我假设创建新流程应该几乎和创造新线程在Linux中 然而 很少的测试显示出截
  • 单元测试 HttpClientModule 时出错(Angular 4.3+)

    我正在探索新的 Angular HttpClientModule 并遇到莫名其妙的错误 该模块足够新 我还找不到任何有关如何进行单元测试的有用信息 并且官方文档没有任何示例 该应用程序包含一个具有一种方法的服务 该方法将 URL 传递给ht

随机推荐

  • linux搭建 PXE 远程安装服务器及无人值守

    注意 新建虚拟机 cpu 2个 内存不能低于4g 内存不低于20g 否则会失败 步骤 root localhost systemctl stop firewalld service 关闭防火墙 root localhost setenfor
  • 修改mysql的时间/时区

    应用背景 有时候会发现数据库存储的时间与当前所在地区的时间不同 尤其是涉及到全球业务的时候 如果有些程序是根据时间判断来进行后面的逻辑 往db中insert数据发现时间不对 尤其是新DB 可能是mysql设置不对 这时由于时区问题影响存入的
  • 【热门框架】Maven怎样进行版本管理?有哪些需要注意事项?

    Maven的版本管理是指对项目的依赖库和发布版本进行管理 可以通过配置pom xml文件来实现 下面是Maven进行版本管理的一些要点和注意事项 依赖库版本管理 在pom xml文件中 可以通过dependencyManagement元素来
  • java 内存分配策略

    1 对象优先在新生代Eden区中进行分配 当Eden区没有足够空间进行分配时 虚拟机进行一次Minor GC 2 大对象直接进入老年代 所谓大对象就是需要大量连续内存空间的java对象 最典型的大对象就是很长的字符串以及数组 3 长期存活的
  • 汇编指令:左移RL和RLC区别

    转载 https www cnblogs com zhangfan2014 p 4583947 html 汇编指令RL和RLC区别 RL是左移指令 参加左移的是8个位 RLC是带进位位的左移 参加左移的共有9个位 设A 0100 0001
  • 跳点搜索算法 (JPS算法) && 效率优化(摘录)

    摘自 腾讯游戏开发精粹 摘录一次加深记忆方便查找 并未盈利 如有侵权 联系作者删除 如感兴趣 请购买原书支持 谢谢配合 JPS主体思路 表现上 JSP算法比A 快很多 实际上快到哪里了 我们大概了解一下 A 会遍历每一个附近的点 然后把符合
  • 【RTT驱动框架分析07】- adc驱动框架分析+adc中断唤醒adc驱动

    ADC adc应用开发 访问 ADC 设备 应用程序通过 RT Thread 提供的 ADC 设备管理接口来访问 ADC 硬件 相关接口如下所示 函数 描述 rt device find 根据 ADC 设备名称查找设备获取设备句柄 rt a
  • xshell5激活

    xshell5产品秘钥 150105 116578 999990 xftp5产品秘钥 150105 116578 999990 xshell5产品秘钥 101210 450789 147200 xftp5产品秘钥 101210 450789
  • 突发奇想-基于重力感应的人体姿态控制型无人机

    基于重力感应的人体姿态控制型无人机 初级阶段目标 短距离重力感应控制 遥控器重力模块直接连接控制 手持遥控器不平稳问题 最终目标 控制系统迁移至人体 进行直接姿态操作 重力感应 压电效应 当晶体受到固定方向外力作用时 内部产生电极化现象 同
  • [YOLO专题-28]:YOLO V5 代码管理 - 如何与官网协同开发自己的项目代码

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122519479 目录 前言
  • C++数组练习题(一)

    在刚开始学习c 的时候刷了很多基础题 这些基础题比较适合初学C 的码友 所以在学完就立即进行了整理 一是为了让初学C 的码友有所参考 二也是为了复习一下所学过知识 但因为当时在整理时 时间有点紧促 可能会出现一些小错误 于是利用五一假期对之
  • Tensorflow:数据特征值的自变量为离散值

    import pandas as pd from sklearn utils import shuffle dataSet pd read csv input mushrooms csv mapPto1Eto0 p 1 e 0 dataSe
  • vite详解

    vite详解 卖菜的小白的博客 CSDN博客 vite 一 认识vite webpack是目前整个前端使用最多的构建工具 但是除了webpack之后也存在其他一些构建工具 比如说rollup parcel gulp vite等等 vite的
  • Twitter开发者账号申请流程

    文章转自 https www jianshu com p cfb741dd52dd 这篇文章主要介绍在最新的推特开发者平台申请账号的流程 首先需要有一个推特账号 其次该推特账号必须是首次申请 因为推特开发者一个账号只能申请一次 申请后被拒绝
  • 【Streamlit学习心得】个人项目实战,并部署在Streamlit Cloud,生成一个公网url随时访问

    Streamlit学习心得 个人项目实战 并部署在Streamlit Cloud 生成一个公网url随时访问 目录 Streamlit学习心得 个人项目实战 并部署在Streamlit Cloud 生成一个公网url随时访问 前言 一 全局
  • TCP的连接

    一 套接字 1 每一条TCP连接有两个端点 TCP连接的端点叫做套接字 socket 或插口 2 套接字 socket IP地址 端口 例如 套接字 socket 192 168 170 1 80 二 TCP连接 1 建立连接时的三次 握手
  • GPU RayTracing

    参考自 https github com Ubpa ToyRTX 使用三种Texture 记录场景数据 1 SceneData 2 MatData 3 PackData 数据 https docs qq com sheet DQ2FqdE1
  • 秋招准备之——MySQL复习

    秋招复习笔记系列目录 不断更新中 1 数据结构全系列 2 计算机网络知识整理 一 3 计算机网络知识整理 二 4 Java虚拟机知识整理 5 计算机操作系统 6 深入理解HashMap 7 深入理解ConcurrentHashMap 8 M
  • TCP协议格式和特点

    文章目录 1 协议格式 2 协议特性 2 1 面向链接 2 1 1三次握手建立连接 2 1 1四次挥手断开连接 相关问题和知识点 1 握手为啥三次 挥手是四次 2 三次握手失败两端是如何处理的 3 SYN泛洪攻击是怎么回事 4 一台主机上出
  • heun 方法 matlab代码_MATLAB中代码优化的两种方法

    MATLAB中的代码优化 MATLAB中的代码优化有两种重要的方法 预分配组和向量化循环 我们举一个简单的例子来看 创建一个MATLAB函数来计算f x sin x 100 function y sinfun1 M x 0 M 1 for