



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MATLAB小贴士(1) 来源: 章佳杰的日志 这学期担任系统工程导论课的助教,看到同学们的作业,看到大家作业里各种青涩可爱的代码,看到大家说自己的 MATLAB 都是从自控课和系统工程课上学的,不由得想为大家做一点事,希望大家在学习使用 MATLAB 的过程中少走一点弯路,希望能对大家以后的学习和科研带来一点帮助。 MAT 的 LAB 我们从进入大学一开始学习了 C 语言,后来又学习了 C+,也许有同学还接触到了 Java,但是 MATLAB 和他们都有点不一样。从名字就可以看出来了,MATLAB 是针对矩阵运算的,所以在 MATLAB 里最欢迎的就是矩阵。MathWorks 里绝顶聪明的工程师们利用各种令人叹服的手段,榨干了计算机的运算能力,将 MATLAB 中的矩阵运算做到世界第一。不相信的同学可以试试看,自己写一段 C 代码实现矩阵乘法,和 MATLAB 的矩阵乘法相比较,看看谁更快。 既然 MATLAB 针对矩阵运算做了大量的优化,那么我们在用 MATLAB 的时候就尽量利用这种优势,将我们的问题用矩阵进行表示,再用矩阵运算来解决。 什么意思呢? 举个例子吧。比如有一个 n*n 的矩阵 A,我想把第1列乘以1,第2列乘以2,第3列乘以3.怎么实现呢?比如用 C 语言的风格可能会写成这样: fori=1:nforj=1:nA(j,i)=A(j,i)*i;endend 在我的 MATLAB 上,对一个 5000*5000 的矩阵,以上代码运行时间为 0.65s 那有没有一种更矩阵的方式来达到同样的目的呢?当然可以,我们知道列向量和一个标量可以进行数乘,所以可以这样写: fori=1:nA(:,i)=A(:,i)*i;end 上面A(:,i)表示矩阵 A 的第 i 列,类似的A(i,:)表示矩阵 A 的第 i 行。在我的 MATLAB 上,对同样的矩阵只要 0.20s 那能不能更快呢?如果有一个对角矩阵 D 他的对角线元素分别是从 1 到 n,那么这个矩阵和 A 相乘,就可以达到我们的目的。于是这段程序还可以这样写: A=A*sparse(1:n,1:n,1:n); 一句话就搞定了,这里sparse(1:n, 1:n, 1:n)这条语句产生了一个对角线元素从 1 到 n 的稀疏矩阵。在我的 MATLAB 上,这句话只花了 0.14s 好了,这个例子很简单,但从中也可以看出,不同的编码方式,对程序运行效率的影响是很大的。最后这种方法和第一种方法相比,效率提高了接近 5 倍。同学们在大一刚入学的时候就学习了 C 语言,所以很多同学仍然将 MATLAB 当做另一个 C 来使用,这并不是很好的使用 MATLAB 的方式。在 MATLAB 里尽量避免for循环,尽量利用矩阵的运算,或者 MATLAB 内置的一些函数进行计算。接下来我将大家在作业中表现出来的问题简单地分析一下,看看都可以做出哪些改进。 对数据进行标准化 有 n 个 m 维的数据点,减去均值后再除以标准差,就得到了均值为 0 方差为 1 的标准化数据。(扯开去说一点,均值的英文是 mean,方差是 variance 常缩写为 var,标准差是 standard deviation 常缩写为 std,起变量名的时候可以参考)这个过程简单吗?当然简单,于是我看到有类似下面这种 C 风格的代码(我整理的,并非出自哪一位同学的作业): %计算均值fori=1:nforj=1:mx_mean(j)=x_mean(j)+x(i,j);endendx_mean=x_mean/n;%计算方差fori=1:nforj=1:mx_var(j)=x_var(j)+(x(i,j)-x_mean(j)2;endendx_var=x_var/(n-1);%下面进行标准化fori=1:nforj=1:mx(i,j)=(x(i,j)-x_mean(j)/sqrt(x_var(j);endend 这样的代码很清晰易懂,几乎是标准的 C 语言写法。在我们的作业中 n = 3114,m = 14,上面这样的代码在我的 MATLAB 里运行 1000 次需要 5.98s。那么有没有改进的余地呢?前面已经说了,在 MATLAB 里尽量避免使用for循环,尽量使用矩阵运算以及 MATLAB 内置的函数。MATLAB 里有个mean()函数可以计算均值,有个var()函数可以用来计算方差,有个std()函数可以用来计算标准差。好,那么我们就用上这些函数: %计算均值x_mean=mean(x);%计算标准差x_std=std(x);%下面进行标准化fori=1:mx(:,i)=(x(:,i)-x_mean(i)/x_std(i);end 这段代码运行 1000 次只需要 0.74s,相比原先的代码,效率提高了 8 倍,而且代码更简洁了。 特征值和特征向量 在作业中需要求某个矩阵的特征值和特征向量,当然同学们都会使用 MATLAB 内置的函数V, D = eig(A),这样得到的对角矩阵 D 其对角线元素就是从小到大排列的的特征值。有的同学希望能将这个对角线元素单独抽取出来变成一个行向量或者列向量,还希望特征值从大到小排列,为了达到这个目的,大家用了各种各样的方法。其实 MATLAB 内置的函数就有diag()可以将一个对角矩阵转化为一个向量,也可以将一个向量转化为一个对角矩阵。转换完之后对向量进行逆序排列,我看到有同学硬是写了一个冒泡排序来完成这个工作,你的数据结构老师一定非常欣慰。但是在 MATLAB 里不用从头开始,直接调用sort()函数就行了但是在这里还有更简单的方法,wrev()函数就可以将一个向量逆序排列,fliplr()函数可以将一个矩阵左右镜像对称,所以如果想得到从大到小排列的特征值,只要这样就行了: %得到从大到小排列的特征值V,D=eig(A);lambda=wrev(diag(D);V=fliplr(V); 这样特征值和特征向量就都排列好了。 在作业中还需要计算相对误差,要将特征值向量从大到小依次累加,直到大于某个阈值。所以可以直接这样写: %根据相对误差决定主成分个数lambda_sum=sum(lambda);tem_sum=0;fori=1:ntem_sum=tem_sum+lambda(i);iftem_sum/lambda_sum1-rerrbreak;endend 这样当循环结束的时候,i 的值就是需要求的了。但是在 MATLAB 里可以写得更简洁一些: %根据相对误差决定主成分个数m=find(cumsum(lambda)/sum(lambda)1-rerr,1,first); 大家可以利用 MATLAB 的帮助文档,自己查一查上面这句话里各个函数的作用。 另外,如果大家
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 火灾安全知识培训课件建议
- 跨文化交流能力在2025年国际化教育中的跨文化教育创新研究报告
- 巡察民主测评课件
- 濮阳消防知识培训课件服务
- 岳飞满江红诵读课件
- 年产11.6万台精密露点仪项目可行性研究报告
- 奔驰卡钳知识培训课件
- 离婚协议书中2025年度股票资产清算及分割方案
- 二零二五年度特种船舶船员聘用及安全协议
- 二零二五年度办公室房屋转租及企业培训服务合同
- 枣庄学院《图学基础与计算机绘图》2024-2025学年第一学期期末试卷
- GB 46031-2025可燃粉尘工艺系统防爆技术规范
- 养老护理员培训班课件
- 2025-2030城市矿产开发利用政策支持与商业模式创新报告
- 产品线库存管理与补货预测系统
- 2025年高考(山东卷)历史真题及答案
- 医学减重管理体系
- 咯血与呕血的护理
- 初中历史教师培训讲座
- 2025年新营运损失费赔偿协议书
- 手术部运用PDCA循环提高手术室术后设备器材定位归还率品管圈
评论
0/150
提交评论