MATLAB软件资源全解析
1. 计算与可视化软件
MATLAB为技术计算和图形处理提供了一个强大的环境。由于其专注于这方面,并且包含了丰富的子程序库,它对于学习和实践应用数学与工程数学是一个非常有用的辅助工具。
从本质上讲,MATLAB是一个交互式解释器,能让用户轻松进行各种数学计算。不过,它并非唯一在子程序库基础上提供交互式脚本语言的项目,许多文字处理和电子表格程序也有类似的功能,这对于大多数计算机用户来说并不陌生。
有不少以数学为导向的程序都具备交互式脚本语言界面。在商业程序中,Maple(TM)和Mathematica(TM)可进行符号处理;而免费软件项目Maxima和Ginac也能实现这一功能。其中,Ginac选用C++作为脚本语言,因此项目可以进行编译以提高运行速度。Maple和Mathematica还支持图形处理和数据导入,在这方面与MATLAB形成竞争。
强调统计功能的交互式程序也具备图形处理能力,比如商业软件SPlus(TM),GNU R程序也有类似的功能。此外,还有一些程序的功能与MATLAB有重叠,例如Octave和Scilab都是免费可用的。Octave遵循GNU GPL许可协议发布,而Scilab则有其独特的许可协议。
MATLAB在科学计算领域应用广泛,并且经过了长期的发展。这意味着随着时间的推移,它添加了许多功能,其中一些以特定领域的“工具箱”形式存在。一般来说,MATLAB会不断融入基础数值分析例程的改进,因此其例程的数值质量很高。
MATLAB的图形处理灵活性和功能也十分强大,这使得它不仅适用于处理测量数据,还能用于展示模拟和其他计算的输出结果。同时,MATLAB还可作为编程环境使用,一方面可以通过“脚本”利用子程序库和图形进行计算,另一方面它还具备“用户”界面构建功能,可用于许多工具箱产品的鼠标驱动界面,也能为数据收集和分析项目开发自定义界面。此外,该程序还支持动态链接用户编写和编译的模块,在特定应用中,如果解释器的速度成为问题,这一功能可以有效解决。
2. MATLAB数据结构
MATLAB开发初期主要侧重于线性代数库的交互式使用,其名称“Matrix Laboratory”(矩阵实验室)就体现了这一点。在后续的发展中,MATLAB增加了其他功能和支持的数据结构。
其基本数据结构包括多维数值数组、结构体和元胞数组。在发布后的一段时间里,数值数组是唯一的数据类型,因此处理字符串比较麻烦。现在,主要通过使用非数值数组的数据结构来解决这个问题。例如:
a = ['abc'; 'defg']
% 会报错,因为所有行的列数必须相同
MATLAB的元胞数组使用“花括号”代替数值数组的方括号表示法,花括号也可用于下标引用。以下是一些元胞变量的示例:
a = {'abc'; 'defg'}
size(a)
a{1}
a(1)
几乎任何MATLAB数据类型都可以存储在元胞数组中,因此它作为容器类型非常有用。
在其他编程语言中,常用的容器类型是带有命名字段的结构体,MATLAB也使用这种结构,并且能够实现“通用存储”。示例如下:
a.first_string = 'abc';
a.second_string = 'defg';
a.float = pi;
a.number = exp(1);
MATLAB还支持在函数调用中传递函数作为变量,有两种可接受的语法形式。一种是使用引号引用函数名,这种形式在很多“遗留代码”中使用;另一种是使用“@”(表示“地址”),例如:
smelly_call('myfunc', 1, 2);
smelly_call(@myfunc, 1, 2);
在傅里叶级数的计算中就运用了这种机制,不同的傅里叶级数的项系数公式不同,绘图函数调用会将“项函数”作为参数传递。在零查找或数值积分等操作中也可以利用这一功能。
3. MATLAB运算符和语法
MATLAB有一个在线帮助系统,其中包含编写程序和脚本所需的有用信息。只要能猜到一个可能的运算符实例,帮助系统就会提供可用运算符的列表。例如:
>> help *
这会列出各种运算符和特殊字符,包括算术运算符(如加、减、乘、除、幂等)、关系运算符(如等于、不等于、小于、大于等)、逻辑运算符(如短路逻辑与、或,元素级逻辑与、或等)、特殊字符(如冒号、括号、花括号等)、位运算符(如按位与、按位取反等)和集合运算符(如集合并、交、差等)。
4. MATLAB编程结构
作为一种编程语言,MATLAB提供了常见的编程便利,这可以通过列出语言关键字来体现:
>> iskeyword
关键字包括’break’、 ‘case’、 ‘catch’、 ‘continue’、 ‘else’、 ‘elseif’、 ‘end’、 ‘for’、 ‘function’、 ‘global’、 ‘if’、 ‘otherwise’、 ‘persistent’、 ‘return’、 ‘switch’、 ‘try’、 ‘while’等。
一般来说,受控块以end语句结束。for循环的外观与传统的有所不同,控制变量会遍历一个数组,这种方式实际上更加灵活。例如:
for x = 0: .1: 1
... x ...
end
MATLAB提供了break和continue语句用于提前退出循环,这与C语言家族的用法类似。不过,break语句在MATLAB的case结构中不使用,因为代码在匹配成功后会自动退出块(不存在类似C语言的穿透现象)。标点符号也有所不同,可能是因为在数组索引中使用了“:”。但由于有内置的帮助系统,用户不必过于担心这些差异。例如:
>> help case
会显示CASE语句的相关信息,其一般形式如下:
SWITCH switch_expr
CASE case_expr,
statement, ..., statement
CASE case_expr1, case_expr2, case_expr3,...
statement, .... statement
OTHERWISE,
statement, ..., statement
END
另外,需要注意的是全局声明和函数声明。全局变量必须在使用它们的函数定义内部以及交互式解释器级别进行声明。函数体内的persistent声明类似于C语言中的静态变量,实际上是一个在外部不可见的全局变量。
5. MATLAB程序和脚本
MATLAB的函数定义与其他编程语言有所不同,它没有表示函数定义结束的标记。这导致无法在交互式环境中输入函数来尝试“玩具”版本,因为交互式解释器无法判断函数定义何时结束以及交互式变量赋值何时开始。
函数需要写在外部文件中,只要文件位于加载路径上且后缀为“.m”,就可以作为命令交互式执行,也可以在其他函数中调用。加载路径可以设置,默认情况下包括当前目录。许多函数定义的示例都采用以注释行开头的标准格式,这些注释行用于生成函数的在线帮助,因此在编写时需要考虑这一点。例如,前面提到的case语句的帮助文本实际上就是MATLAB系统目录中case.m文件的开头注释行。case函数实际上是一个编译实体,对应的“.m”文件是为了帮助系统而存在的。
函数按定义会返回一个值,也可以通过在加载路径上的“.m”文件中填充在键盘上输入时会执行的行来构建命令。输入命令名会将键盘输入重定向到文件,直到文件执行完毕。这使得可以将交互式历史记录的一部分保存为命令,还可以编辑掉交互式会话中的“错误步骤”。
6. 常见习惯用法
MATLAB的许多应用都涉及数组处理,其语法特性使得数组处理变得简单。除法和乘法可以透明地提供矩阵版本,通常被认为是标量值的函数可以进行元素级评估,而无需编写循环来遍历数组的值。由于数组元素可以是复数,这种方法在处理复数参数时同样有效。
不过,使用这一功能时需要注意一个小问题。在某些问题中,理论上计算结果应该是实数,但计算有时会产生带有非常小虚部的结果,这通常是因为包含的复共轭项在理论上应该相互抵消,但由于舍入误差,它们实际上并没有完全抵消,这些小的复数值可能会在后续计算中传播,导致的错误可能会让人意外,而且很难找出问题的原因。
“:”运算符在MATLAB中有多种简洁的用法。它非常适合生成(主要是)线性间隔的数组,例如:
x0 : delta: xf
这是一个从x0开始,以delta为步长,直到并包括xf的数组。这种类型的数组常用于for循环的控制元素,当省略增量值时,默认步长为1,例如:
for k = 1 : length (x)
...
end
“:”运算符还可以作为维度通配符使用,例如:
% 获取第一行
x = a(1, :);
% 提取第七列
x = a(:, 7);
也许“:”最神秘的用法是作为列创建代理,表达式:
x = a{:}
会将行向量a转换为列向量,更一般地,它会按列主序将a的元素创建为列。由于MATLAB内部按列主序存储数组,因此这实际上是一个免费的操作。这种操作的存在使得在许多MATLAB代码中,列向量成为常用的向量形式,因为它提供了一种强制使用标准格式并处理意外行向量输入的简单方法。
代码片段中有时会将以分号结尾的赋值行和不以分号结尾的赋值行混合使用。以分号结尾的行可以抑制控制台对该行结果的回显。在“.m”文件中,如果一行不加分号,通常会导致大量的终端输出,但这也为经典的“打印语句”调试方法提供了一种简单的机制,因为看到一个不可能的值出现往往足以触发对代码问题的识别。
7. 常见陷阱
和任何编程或操作环境一样,使用MATLAB需要一定的时间来适应其约定、语法和功能。其中一个需要适应的是标量和数组操作的区别。一般模式是:
a.operb
% 例如
a.* b
表示a和b的元素之间进行逐元素操作,这种模式适用于乘法、除法和幂运算。如果其中一个操作数是数值,既可以使用逐元素形式,也可以使用数组形式。使用标量语法时,MATLAB会将标量提升为一个适当大小的全1数组的标量倍数,然后进行指定的逐元素操作。
不过,.+表达式是操作列表中“点操作”模式的一个例外。有些用户可能会习惯用它来进行数组的逐元素加法,但这种形式不在运算符列表中,尝试使用时会得到一个不太有用的错误信息。
另外,还要注意不小心使用Shift键的影响。例如:
t = 0:.01 ;2*pi;
plot(t, sin(t))
这个结果可能会让人惊讶,尤其是在绘图之前进行了许多快速的中间计算时。实际上,t被赋值为一个从0到0.01,步长为1的数组,因此t最终实际上是一个单元素的0。2*pi会在控制台回显,但由于后面的“;”而被忽略。
8. 图形处理
8.1 二维绘图
从用户的角度来看,MATLAB的绘图功能分为高级和低级两个层面。高级绘图功能可以处理数据数组,实际上,用户可以让MATLAB绘制单个向量(行向量或列向量),结果将是一个以数组索引为“x轴”值的图形。
更常见的情况是需要指定自变量的值,此时需要将两个参数传递给plot函数。多个数据对可以生成叠加的图形,例如:
t = 0:.01 :2*pi;
plot(t, sin(t), t, cos(t));
许多函数示例是通过分段公式定义的,绘制这些示例对于研究级数收敛性等问题很有用。为此,需要一个MATLAB版本的Heaviside阶跃函数,可以基于MATLAB关系运算符返回1(真)和0(假)的特性来构建:
% heaviside(t)
% = 0, for elements of t < 0
% = 1, for elements of t >= 0
function out = heaviside(t)
out = (t >= 0);
将关系表达式与逻辑运算符结合使用,实际上可以直接编写分段函数定义,例如用于拉普拉斯变换计算的函数。长度为1的方波脉冲可以定义为:
% squarepulse(t)
% = 1, for elements of t >= 0 and < 1
function out = squarepulse(t)
out = (t >= 0) & (t < 1);
使用这个函数,一个在r到r + T之间值为1的函数可以简单地表示为squarepulse((t - r)/T)。
为了绘制包含非常大数值的图形数据,有时需要在一定级别上裁剪数据。如果不抑制大值,默认的自动绘图缩放可能会掩盖有用的数据。可以定义一个裁剪函数:
% clip(x, limits)
% works usefully for real valued things only, probably
function y = clip(x, limits)
y = min(max(x, limits(1)), limits(2));
8.2 曲面绘图
MATLAB支持两种曲面绘图模型,一种是“(x,y)上方的高度”模型,另一种是在MATLAB文档中被称为参数化方法的“正确”方法,这种方法适用于曲面(和多变量函数)。
参数化方法的一个主要优点是它可以扩展到二维以上的情况,不过在本文中我们主要关注二维情况。在R3中的二维曲面由参数区域 (u, v) ∈ P(通常是R2中的一个矩形)和坐标函数定义:
[
X(u, v)
Y(u, v)
Z(u, v)
]
在MATLAB中,二维数组实际上是两个整数值参数的函数,映射关系为 (i, j) → A(i, j)。在计算时,u和v参数会被一组有限的样本值替换,两个参数的函数就变成了两个样本下标的函数,即二维数组。
例如:
u = linspace(0, 2, 5);
v = linspace(-2, 1, 6);
[X, V] = meshgrid(u, v);
Z = exp(-(X.^2 + V.^2));
surf(X, V, Z);
这里生成的曲面图可能比较粗糙,但通过使用更精细的网格并设置图形对象的属性(如插值值、引入透明度等),可以生成更美观的图形。
meshgrid函数并不是必需的,参数数组也可以通过数据向量与适当大小的全1数组的外积来生成。不过,meshgrid函数更方便,只是它会稍微掩盖一些底层的操作。需要明确的是,这些数组中的值的排列直接决定了绘制曲面的方向理解这一点有助于操作和解释绘图输出。
下面是一个必须使用参数化表示的曲面示例,即平方根函数的黎曼曲面的图形表示。这个曲面是一个双叶曲面,沿着负实轴拼接在一起。通过使用周期为4π的正弦函数定义Z坐标,可以实现双叶效果。当极坐标圆被追踪两次时,会得到对称地位于(x, y)平面上方和下方的值。
r = 0: .05: 1;
theta = linspace(0, 4*pi, 720);
[R, Theta] = meshgrid(r, theta);
x = R .* cos(Theta);
y = R .* sin(Theta);
Z = (1/pi) * atan(25 * cos(.5 * Theta));
h = surf(x, y, Z);
set(h, 'EdgeColor', 'none', 'FaceColor', 'interp');
alpha(.5);
set(gca, 'XTickLabel', 0);
set(gca, 'YTickLabel', 0);
set(gca, 'ZTickLabel', []);
print -deps riemannsqrt.eps
通过以上介绍,我们对MATLAB的软件资源、数据结构、编程结构、常见用法和图形处理等方面有了较为全面的了解。在实际应用中,我们可以根据具体需求灵活运用这些知识,充分发挥MATLAB的强大功能。
MATLAB软件资源全解析
8.2 曲面绘图(续)
在前面我们已经介绍了MATLAB中曲面绘图的基本概念和一些示例,下面我们进一步深入探讨曲面绘图的相关内容。
参数化方法在处理复杂曲面时具有很大的优势。以平方根函数的黎曼曲面为例,我们可以更详细地分析其实现过程。
r = 0: .05: 1;
theta = linspace(0, 4*pi, 720);
[R, Theta] = meshgrid(r, theta);
x = R .* cos(Theta);
y = R .* sin(Theta);
Z = (1/pi) * atan(25 * cos(.5 * Theta));
h = surf(x, y, Z);
set(h, 'EdgeColor', 'none', 'FaceColor', 'interp');
alpha(.5);
set(gca, 'XTickLabel', 0);
set(gca, 'YTickLabel', 0);
set(gca, 'ZTickLabel', []);
print -deps riemannsqrt.eps
在这个代码中,我们首先定义了半径
r
和角度
theta
的范围。
linspace
函数用于生成均匀分布的角度值,
meshgrid
函数将
r
和
theta
转换为二维网格,这样就可以方便地计算
x
、
y
和
Z
坐标。
Z
坐标的计算使用了
atan
函数进行平滑裁剪,使得曲面呈现出双叶的效果。
surf
函数用于绘制曲面,返回一个曲面句柄
h
,通过
set
函数可以设置曲面的属性,如边缘颜色、面颜色和透明度等。
最后,我们使用
print
函数将绘制的曲面保存为EPS文件,方便后续使用。
下面是一个简单的流程图,展示了曲面绘图的基本步骤:
graph TD;
A[定义参数范围] --> B[生成网格数据];
B --> C[计算坐标值];
C --> D[绘制曲面];
D --> E[设置曲面属性];
E --> F[保存图形];
9. MATLAB的优势总结
MATLAB在科学计算和工程领域具有众多优势,下面我们通过一个表格来总结:
| 优势 | 描述 |
|---|---|
| 强大的计算能力 | 包含丰富的子程序库,可进行各种数学计算,如线性代数、数值分析等。 |
| 灵活的图形处理 | 支持二维和三维绘图,可用于数据可视化和结果展示。 |
| 便捷的编程环境 | 提供常见的编程结构和关键字,易于学习和使用。 |
| 丰富的数据结构 | 支持多维数值数组、结构体和元胞数组等,方便数据存储和处理。 |
| 广泛的应用领域 | 在信号处理、图像处理、控制理论等多个领域都有广泛应用。 |
10. 实际应用案例
为了更好地说明MATLAB的实际应用,我们来看一个简单的信号处理案例。假设我们有一个包含噪声的信号,我们希望使用低通滤波器对其进行滤波。
% 生成包含噪声的信号
t = 0:0.01:1;
signal = sin(2*pi*5*t);
noise = 0.5*randn(size(t));
noisy_signal = signal + noise;
% 设计低通滤波器
fs = 100; % 采样频率
fc = 10; % 截止频率
[b, a] = butter(4, fc/(fs/2), 'low');
% 应用滤波器
filtered_signal = filter(b, a, noisy_signal);
% 绘制原始信号、含噪声信号和滤波后信号
figure;
subplot(3,1,1);
plot(t, signal);
title('原始信号');
subplot(3,1,2);
plot(t, noisy_signal);
title('含噪声信号');
subplot(3,1,3);
plot(t, filtered_signal);
title('滤波后信号');
在这个案例中,我们首先生成了一个包含噪声的正弦信号。然后使用
butter
函数设计了一个四阶低通滤波器,该滤波器的截止频率为10Hz。最后,使用
filter
函数将滤波器应用到含噪声的信号上,得到滤波后的信号。
通过绘制原始信号、含噪声信号和滤波后信号,我们可以直观地看到滤波器的效果。
11. 学习建议
对于初学者来说,学习MATLAB可能会遇到一些困难。下面是一些学习建议:
- 学习基础知识 :熟悉MATLAB的数据结构、运算符、编程结构等基础知识。可以通过阅读官方文档、教程和书籍来学习。
- 多做练习 :通过实际的练习来巩固所学的知识。可以从简单的示例开始,逐渐增加难度。
- 参考示例代码 :MATLAB官方提供了大量的示例代码,可以参考这些代码来学习如何使用不同的功能。
- 参与社区 :加入MATLAB社区,与其他用户交流经验和心得。可以在论坛上提问、分享自己的代码和经验。
12. 未来发展趋势
随着科技的不断发展,MATLAB也在不断更新和完善。未来,MATLAB可能会在以下几个方面有进一步的发展:
- 深度学习支持 :随着深度学习的兴起,MATLAB可能会加强对深度学习的支持,提供更多的深度学习工具和模型。
- 云计算集成 :与云计算平台集成,使得用户可以在云端进行大规模的计算和数据分析。
- 跨平台兼容性 :提高跨平台兼容性,使得用户可以在不同的操作系统上使用MATLAB。
- 可视化增强 :进一步增强可视化功能,提供更加美观和交互性强的图形界面。
总之,MATLAB作为一款强大的科学计算和工程软件,在未来仍然具有广阔的发展前景。通过不断学习和掌握MATLAB的新功能,我们可以更好地应对各种复杂的问题。
超级会员免费看
1117

被折叠的 条评论
为什么被折叠?



