百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Matlab 中编程技法分享

bigegpt 2024-09-16 12:22 4 浏览

“时问桫椤”公众号,一个不太正式的学术加油站,专为本科生到研究生的你提供“非正式”援助。当你感到迷茫、痛苦,或是被学术大山压得喘不过气时,我们就是你的“学术救生圈”。我们用研究生们的血泪经验,帮你快速适应研究生生活,揭开科研的神秘面纱。祝你一路顺风,科研路上不翻车!

非常感谢各位的点赞,关注和转发,你们的点赞和关注是我更新的动力[1]

技法分享

  1. 尽量避免使用循环结构

MATLAB变量的基本类型是矩阵,当对矩阵的每个元素循环处理时,运算速度很慢。因此编程时应尽量把数组和矩阵看作一个整体来进行编程,而不是像其他的程序设计语言那样,使用循环结构对矩阵的元素循环进行处理。

利用MATLAB提供的用于矢量化操作的函数,把循环矢量化,这样既可以提高编程效率,也可以提高程序的执行效率。

下面给出一个循环的例子:

i=0;

for n =0:0.1:100

i=i+1;

y(i)=cos(n)

end

上述程序段把数组中的每个元素都进行函数值计算,这样会耗费大量的运算时间,我们可以把数组看作一个整体来处理,计算函数值,可以修改这个程序段如下。

n = 0:0.1:100;

y = cos(n)

通过使用MATLAB专门提供的测试程序运行时间的函数,可以发现,把数组看作一个整体,进行操作后,执行效率提高约300倍。

另外,在必须使用多重循环的情况下,建议在循环的外环执行循环次数少的,内环执行循环次数多的,这样也可以显著提高程序执行速度。

  1. 在使用数组或矩阵之前先定义维数

MATLAB中的变量在使用之前不需要明确地定义和指定维数。

但当未预定义数组或矩阵的维数时,当需赋值的元素下标超出现有的维数时,MATLAB 就为该数组或矩阵扩维一次,这样就会大大降低程序的执行效率。

因此,在使用数组或矩阵之前,预定义维数可以提高程序的执行效率。

  1. 对矩阵元素使用下标或者索引操作

在MATLAB中,矩阵元素的引用可用两个下标来表示。例如:

A(i,j) 表示矩阵的第i行第j列的元素;

A(1:k,j)表示矩阵A的第j列的前k个元素;

A(:,j) 表示矩阵的第j列的所有元素。

求矩阵A的第j列元素的平均值的表达式为mean(A(:,j))。
  1. 尽量多使用函数文件少使用脚本文件

因为每次调用MATLAB的脚本文件都需要将不必要的中间变量加载到内存中,每执行一次,就加载一次。

函数在调用时被编译成了伪代码,只需要加载到内存一次。当多次调用同一个函数时会运行快一些。

因此尽量多使用函数文件而少使用脚本文件,也是提高执行效率的一种方法。

  1. 在必须使用循环时,可以考虑转换为C-MEX

当必须使用耗时的循环时,可以考虑将循环体中的语句转换为C-MEX。

C-MEX是将M文件通过MATLAB 的编译器转换为可执行文件,是按照 MEX 技术要求的格式编写相应的程序,通过编译连接,生成扩展名为.dll的动态链接库文件,可以在MATLAB环境下直接执行。

这样,循环体中的语句在执行时不必每次都解释(interpret)。一般来说,C-MEX 文件的执行速度是相同功能的M文件执行速率的20~40倍。

编写C-MEX不同于M文件,需要了解MATLAB C-MEX规范。幸运的是MATLAB提供了将M文件转换为C-MEX的工具。

  1. 内存优化

MATLAB在进行复杂的运算时需要占用大量的内存。

合理使用内存和提高内存的使用效率,可以加快运行速度,减少系统资源的占用。

  1. 内存管理函数和命令

● Clear variablename:从内存中删除名称为variablename的变量。

● Clear all:从内存中删除所有的变量。

● Save:将指令的变量存入磁盘。

● Load:将save命令存入的变量载入内存。

● Quit:退出MATLAB,并释放所有分配的内存。

● Pack:把内存中的变量存入磁盘,再用内存中的连续空间载回这些变量。考虑到执行效率问题,不能在循环中使用。

  1. 节约内存的方法

● 避免生成大的中间变量,并删除不再需要的临时变量。

● 当使用大的矩阵变量时,预先指定维数并分配好内存,避免每次临时扩充维数。

● 当程序需要生成大量变量数据时,可以考虑定期将变量写到磁盘,然后清除这些变量。当需要这些变量时,再重新从磁盘加载。

● 当矩阵中数据极少时,将全矩阵转换为稀疏矩阵。

函数式编程

函数式编程是一种编程范式,它强调使用纯函数、不可变数据和高阶函数来构建应用程序。在函数式编程中,我们避免使用副作用和可变状态,而是通过函数来处理数据。以下是一些常见的函数式编程技巧和方法,用于替代传统的循环和条件判断:

  1. 使用map替代for循环map函数接受一个函数和一个数组,返回一个新数组,其中的元素是原始数组元素应用给定函数的结果。 // 传统for循环
    let numbers = [1, 2, 3, 4];
    let squaredNumbers = [];
    for (let i = 0; i < numbers.length; i++) {
    squaredNumbers.push(numbers[i] * numbers[i]);
    }

    // 函数式编程中的map
    let squaredNumbersFunctional = numbers.map(x => x * x);
  2. 使用reduce进行累加或聚合操作reduce函数接受一个累加器函数和一个初始值,将数组中的所有元素减少到单个值。 // 传统for循环累加
    let sum = 0;
    for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
    }

    // 函数式编程中的reduce
    let sumFunctional = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
  3. 使用filter进行条件筛选filter函数接受一个测试函数和一个数组,返回所有使得测试函数返回true的元素组成的新数组。 // 传统for循环筛选
    let evenNumbers = [];
    for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
    evenNumbers.push(numbers[i]);
    }
    }

    // 函数式编程中的filter
    let evenNumbersFunctional = numbers.filter(x => x % 2 === 0);
  4. 使用find或findIndex寻找满足条件的第一个元素find返回数组中满足提供的测试函数的第一个元素的值。如果没有这样的元素,则返回undefined // 传统for循环查找
    let firstEvenNumber;
    for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
    firstEvenNumber = numbers[i];
    break;
    }
    }

    // 函数式编程中的find
    let firstEvenNumberFunctional = numbers.find(x => x % 2 === 0);
  5. 使用some或every进行条件检查some测试数组中是否至少有一个元素满足提供的测试函数。every测试数组中的所有元素是否都满足提供的测试函数。 // 传统if else检查
    if (numbers.some(x => x > 10)) {
    console.log("At least one number is greater than 10.");
    }

    // 函数式编程中的some
    numbers.some(x => x > 10) && console.log("At least one number is greater than 10.");
  6. 使用compose和pipe进行函数组合composepipe允许你将多个函数组合成一个函数,从而减少嵌套和提高可读性。 // 函数组合
    const squareAndAddOne = R.pipe(
    R.map(R.add(1)),
    R.map(R.multiply(2))
    );

    squareAndAddOne([1, 2, 3]); // [4, 6, 8]
  7. 使用switch替代多个if else分支: 虽然switch不是函数式编程特有的,但在某些情况下,它可以替代多个if else分支,使代码更加清晰。 // 传统if else分支
    if (condition) {
    // do something
    } else if (anotherCondition) {
    // do something else
    } else {
    // default case
    }

    // 使用switch
    switch (condition) {
    case 'case1':
    // do something
    break;
    case 'case2':
    // do something else
    break;
    default:
    // default case
    break;
    }

请注意,这些方法在不同的编程语言中可能有不同的实现方式,但核心思想是相同的。在JavaScript中,你可以使用Ramda库或Lodash库等来实现这些函数式编程模式。在其他语言中,如Haskell或Scala,函数式编程是内置的,并且有更多内置的函数式编程特性。

参考资料

[1]

首发平台: 非常感谢各位的点赞,关注和转发,你们的点赞和关注是我更新的动力。哔哩哔哩,知乎和墨滴平台同名账号。

相关推荐

最全的MySQL总结,助你向阿里“开炮”(面试题+笔记+思维图)

前言作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上...

Redis数据库从入门到精通(redis数据库设计)

目录一、常见的非关系型数据库NOSQL分类二、了解Redis三、Redis的单节点安装教程四、Redis的常用命令1、Help帮助命令2、SET命令3、过期命令4、查找键命令5、操作键命令6、GET命...

netcore 急速接入第三方登录,不看后悔

新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢。如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下:https://oauthlogin.net/前言此次带来得这个小项目是...

精选 30 个 C++ 面试题(含解析)(c++面试题和答案汇总)

大家好,我是柠檬哥,专注编程知识分享。欢迎关注@程序员柠檬橙,编程路上不迷路,私信发送以下关键字获取编程资源:发送1024打包下载10个G编程资源学习资料发送001获取阿里大神LeetCode...

Oracle 12c系列(一)|多租户容器数据库

作者杨禹航出品沃趣技术Oracle12.1发布至今已有多年,但国内Oracle12C的用户并不多,随着12.2在去年的发布,选择安装Oracle12c的客户量明显增加,在接下来的几年中,Or...

flutter系列之:UI layout简介(flutter-ui-nice)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。在flutter中,基本上所有的对象都是wi...

Flutter 分页功能表格控件(flutter 列表)

老孟导读:前2天有读者问到是否有带分页功能的表格控件,今天分页功能的表格控件详细解析来来。PaginatedDataTablePaginatedDataTable是一个带分页功能的DataTable,...

Flutter | 使用BottomNavigationBar快速构建底部导航

平时我们在使用app时经常会看到底部导航栏,而在flutter中它的实现也较为简单.需要用到的组件:BottomNavigationBar导航栏的主体BottomNavigationBarI...

Android中的数据库和本地存储在Flutter中是怎样实现的

如何使用SharedPreferences?在Android中,你可以使用SharedPreferencesAPI来存储少量的键值对。在Flutter中,使用Shared_Pref...

Flet,一个Flutter应用的实用Python库!

▼Flet:用Python轻松构建跨平台应用!在纷繁复杂的Python框架中,Flet宛如一缕清风,为开发者带来极致的跨平台应用开发体验。它用最简单的Python代码,帮你实现移动端、桌面端...

flutter系列之:做一个图像滤镜(flutter photo)

简介很多时候,我们需要一些特效功能,比如给图片做个滤镜什么的,如果是h5页面,那么我们可以很容易的通过css滤镜来实现这个功能。那么如果在flutter中,如果要实现这样的滤镜功能应该怎么处理呢?一起...

flutter软件开发笔记20-flutter web开发

flutterweb开发优势比较多,采用统一的语言,就能开发不同类型的软件,在web开发中,特别是后台式软件中,相比传统的html5开发,更高效,有点像c++编程的方式,把web设计出来了。一...

Flutter实战-请求封装(五)之设置抓包Proxy

用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来...

为什么不在 Flutter 中使用全局变量来管理状态

我相信没有人用全局变量来管理Flutter应用程序的状态。毫无疑问,我们的Flutter应用程序需要状态管理包或Flutter的基本小部件(例如InheritedWidget或St...

Flutter 攻略(Dart基本数据类型,变量 整理 2)

代码运行从main方法开始voidmain(){print("hellodart");}变量与常量var声明变量未初始化变量为nullvarc;//未初始化print(c)...