现在的位置: 首页 > 综合 > 正文

《matlab实用教程》书评

2014年01月18日 ⁄ 综合 ⁄ 共 3998字 ⁄ 字号 评论关闭

由于工作需要使用matlab,我自己对这个语言的掌握程度也很一般,就下定决心,将《matlab实用教程》(第二版)看完了,这本书英文版已经出了第三版了。
这是一本很好的通用入门教材。并不涉及专门的应用领域:比如通信系统、信号处理、小波、图像处理、神经网络等等(这些工具箱通常都有专门的书籍讲解)。书中的例子都不是很难,大多数都是套公式,只需要初等数学的知识;对于后面的一些例子(第11章以后),需要基本的微积分以及数值分析的初步知识。
首先,这本书的翻译的名字就有问题,英文原名是《MATLAB for Engineers》,即工程师使用的matlab。而并不是所谓的实用教程。我也不理解为什么要翻译成“实用教程”。
其次,这本书很好的把握了matlab编程的特点。第一是计算为主,而不是选择、循环等程序设计流程。演示也很重要,所以画图的内容也很靠前,而将“程序设计”这一传统的编程关键内容放到了第8章。
其次,由于程序设计内容放的靠后,所以这本书的风格比较像谭浩强的c语言,例子都很短小,说明问题即可。这也就意味着你看完这本书以后一般只能达到能看懂程序的地步,而谈不上编写大型复杂的程序。当然如果你有其他语言编写程序的经验的话,这也就不成问题了,毕竟编程的基本思想都是想通的。

关于matlab的编程思想,与C语言有一个很大的不同点在于循环并不是那么常用了,主要是因为matlab对变量本身就是矩阵操作。举一个例子,就是计算一下成绩中大于90的个数。使用类似于C语言的风格,我们会这么写:
scores = [76,45,98,97];
count = 0;
k = 0;
while k < length(scores)
    k = k+1;
    if scores(k)>90
        count = count+1;
    end
end
disp(count)
但是使用matlab的观点,可以写为:
count = length(find(scores>90))
顺便说一句,find是一个很犀利的函数,可以免去很多时候的遍历向量,查找其中的一个是否符合条件的程序。
当然,你也可以认为这种写法类似于对C++中STL库的调用。
还有一些细节问题需要注意,比如:
matlab的数组,矩阵下标都是从1开始的,对于一个长为SIZE的数组A,元素是A(1)……A(SIZE),并不是C语言中的A(0)……A(SIZE-1),以前写程序时在这里吃过亏,记忆特别深刻。
虽然matlab中允许向量长度增加或者减小,但是在for循环中,matlab总是建议你:向量的长度似乎在for循环中发生变化,为了考虑效率,建议在循环前就分配好大小。因为matlab底层很多内容使用C实现的,看来面对用户而言,也需要考虑效率问题。
我们知道在C语言中的switch case语句是可以这样用的:
switch type
case 1:
case 2:
do something;
default:
do some other thing;
但是在matlab中,就不能直接这么用了,得改为:
switch type
case {1,2}
do something
otherwise
do some other thing;
不过这个知识点并不是书里写的,也是我有需要以后上网发帖,热心的网友给我的回答。
新版本的matlab(2012b)中,会建议你使用li代替表示复数的i或者j,这是一个很不错的注意,因为i、j、k总是被我们当做循环下标使用,搞不好就乱了。

解方程组Ax=B时,使用inv(A)*B是用的矩阵求逆的方法;而是用A\B则使用的是高斯消元的办法。

在C语言中,对于一些比较长的表达式,我们都通过回车会将它们分为多行,这是因为C语言每一行默认情况下是以“;”结尾的,只要没有遇见“;”,就将它们认为是一行;而对于matlab,由于没有规定每一行必须以“;”结尾,所以只要形式上不在一行,就会被matlab认为是2条语句,如果遇到表达式太长,需要换行的情况(最近就遇到了这种情况,主要原因是在for循环里访问两个数组,每个数组的起始和结尾地址都是一个变量名控制的,而这个名字也不是很短),可以通过前后用空格隔开的“...”表示续行。

C语言中,高维数组是通过1维数组递归定义的,1维数组的每个元素又是一个数组,这虽然满足了控制了语言规模的优点,但是在使用时对于新手而言还是会频繁出错的。而matlab的方法就很奇特(以3维数组为例,因为matlab将2维矩阵定义为基本的数据类型):你先写好多个2维矩阵,然后把它们“串”起来,变成一个3维矩阵,举一个例子:
A = [1 2 3;4 5 6;7 8 9];
B = [11 22 33;44 55 66;77 88 99];
C = [111 222 333;444 555 666;777 888 999];
my_3D_arr(:,:,1) = A;
my_3D_arr(:,:,2) = B;
my_3D_arr(:,:,3) = C;
然后通过下标访问:my_3D_arr(1,1,2)

我之前不知道的是,matlab不仅支持结构体,用法跟C的几乎一样,通过“.”来访问结构体的成员即可;matlab也支持面向对象的方法,比如通信工具箱中的调制。(这一条也不是书上讲的,而是看代码时发现的)
matlab比较犀利的一点,是从Maple继承而来的符号代数系统。什么是代数?就是咱们学过的那一套用变量的运算代替直接数字的加减乘除之类的运算,计算出来的结果还是一个表达式,而不是一个数。下面我着重介绍一下这方面的内容。
首先,你得定义一个符号变量,有两种方法:
x = sym('x')
syms x
他们都将字符x定义为一个符号变量;
有了符号变量,你就可以定义复杂的符号变量了:
y = 2*(x+3)^2/(x^2+6*x+9)
你也可以定义符号表达式或者方程:
E = sym('m*c^2')
注意,这个表达式与y是有区别的。如果已定义了x为变量符号,那么才能用y = 2*(x+3)^2/(x^2+6*x+9)定义y,如果没有定义x,那么只能用第二种方法了。
ideal_gas_lwa = sym('P*V =n*R*Temp')定义了一个方程。
对于表达式,可以进行展开、合并、求分母和分子、化简等等操作,这里就不一一细说了。
对于方程和表达式solve是非常有用的函数,对于方程,是求解跟;对于表达式,是求解被求解变量的显示表达式;solve也可以用于求解方程组,但与矩阵求逆或者高斯消元法不同的是,它们两个只能求解线性方程组,而solve是可以求解非线性的方程组的。
还有一个将表达式带入具体数值的函数subs,也很实用,完全是模仿大家怎么手工求解数学问题的思路来设计的。
至于微积分,简单的提一下吧,diff,求微分,可以通过参数设定求解的变量和次数;int既可以求不定积分,也可以求定积分。就是求出的结果表达式不一定符合数学运算的最简结果,不过也真是辛苦那些编写函数的牛人了。
除了微积分,matlab还能解微分方程。但是要注意,微分方程的自变量是t,而不是x了

书中还专门介绍了数值分析中的一些常用技术、差值、拟合、以及数值积分。
差值就是通过若干离散的点x的值y,构造一条通过这些点的曲线,利用曲线来计算这些离散点之间的y值。比较常见的方法是最近邻,线性差值,3次样条差值。matlab使用interp1来进行差值,举一个例子:
x = 0:5;
y = [15,10,9,6,2,0];
new_x = 0:0.2:5;
new_y = interp1(x,y,new_x,'spline')
差值还支持2维情况,使用interp2即可,其他都差不多。
拟合讲的是另一种处理离散点的办法:利用n次多项式构造一条曲线,使得所有的离散点距曲线的距离之和的绝对值最短。值得注意的是,并不是次数越高,拟合效果就越好的。较高次数会增加运算的复杂度,而且高次多项式的变化非常不稳定;由于“Runge”现象。
拟合的思路跟差值很像,就是也是构造一条曲线,这条曲线不一定过那些已知的离散点,而是使得这些离散点到曲线的距离最短。matlab使用polyfit函数来进行多项式拟合它的参数有3个:x值,y值,以及多项式的阶数。举个例子:
x = 0:5;
y = [15,10,9,6,2,0];
%画出x,y点
plot(x,y,'*');
%3次多项式差值
coefficient=polyfit(x,y,3);
z = coefficient(1)*x.^3 + coefficient(2)*x.^2+coefficient(3)*x+coefficient(4);
hold on;
plot(x,z);
注意到polyfit返回的是多项式的系数。其实有更简单的办法来计算差值的结果,就是使用函数polyval:
z = polyval(coefficient,x);
这一句与
z = coefficient(1)*x.^3 + coefficient(2)*x.^2+coefficient(3)*x+coefficient(4);
是等效的,且更加方便。尤其是对于拟合的多项式阶数较高时。
matlab自带了数值积分和微分函数。quad和quadl输入被积函数、积分上下限,用来求数值积分结果。
至于微分方程的数值解,由于以前学数值分析的时候这里就没学好,我就不卖弄了。

最后一章高级绘图我也没看,估计暂时用不到。

这本书似乎没有包括GUI设计等方面的问题。但是,当你给别人演示时,如果使用的GUI界面,而不是在程序里调整参数,别人的肯定会对你另眼相看的。别觉得界面不重要,当某个软件你用起来很别扭时,就会体会到了。

最后说几点matlab的小操作技巧吧:
整段加上注释可以使用ctrl+r,去掉注释可以使用ctrl+t;
让代码自动对齐可以使用ctrl+i;
可以通过tab键将变量名自动补充完整,就跟linux控制台下写路径一样。
调试里面的加断点,运行下一行,进入子程序等等,跟VS2010差不多。

抱歉!评论已关闭.