MATLAB®历史,现代MATLAB,第1部分

ACM编程语言特别兴趣小组(SIGPLAN)预计将在2020年举行第四次关于编程语言历史的系列会议HOPL-IV.论文初稿将于2018年8月前提交。这么长的准备时间让我有机会写出MATLAB的详细历史。我计划将这篇论文分成几个部分来写,如果有的话,我会在这个博客上发布。

这是第五篇文章,也是关于现代MATLAB的多篇文章的第一篇。

尽管它的名字,MATLAB不再只是一个矩阵实验室。在过去的35年里,它已经发展成为一个丰富的技术计算环境。

内容

图形

PC-MATLAB只有十几个图形命令,包括情节对于二维工作对于三维空间。结果是在低分辨率显示器上呈现的,内存有限,颜色也很少。但随着设备的发展,MATLAB的绘图能力也在不断发展。

1986年,我们发布了一个名为PRO-MATLAB的MATLAB版本,适用于包括Sun-3在内的UNIX工作站。这些工作站上的显示器和窗口系统支持更强大的图形。金宝app

1992年,我们发布了适用于个人电脑和工作站的MATLAB 4。这个版本包含了重要的图形新功能,包括颜色。我记得在将RGB颜色表示转换为CMYK表示的过程中遇到的困难,RGB颜色表示是我们软件的基础,而CMYK表示是我们纸质文档的打印机所期望的。这个问题没有详细说明。我们有三个值,R, G和b。它们是C, M, Y和k四个值的加权平均值。这四个值是什么?我非常高兴,当我看到第一个成功的页样张的彩色插入。

这里并不是描述我们今天在MATLAB中所拥有的所有图形特征的地方。这是一个样本,四个不同的视图,我们的一个古老的测试表面。

[x,y,z] =峰值;

$ $ z = 3 (1 - x) e ^ {- x ^ 2 - (y + 1) ^ 2} -10 (\ textstyle \压裂{x} {5} - x ^仍^ 5)e ^ {- x ^ 2 y ^ 2} \ textstyle \压裂{1},{3}e ^{——(x + 1) ^ 2 y ^ 2} $ $

首先,一个朴素的表面情节。P1 = subplot(2,2,1);冲浪(x, y, z)轴接下来,一个3D柱状图,对默认注释进行了一些调整。P2 = subplot(2,2,2);K = 1:4:49;B = bar3(flipud(z(k,k)));修正(p2, b)然后,数组的列的2D绘图。P3 = subplot(2,2,3);情节(z)最后,一个20层的填充等高线图和一个适度的彩色地图。P4 = subplot(2,2,4);contourf (z, 20);colormap (p4,粉红色)轴

数据类型

多年来,MATLAB只有一种数字数据类型,即IEEE标准754双精度浮点数,以64位格式存储。

清除格式=(1 +√(5))/2
Phi = 1.618033988749895

在几个版本中,我们增加了对单一精度的支持。金宝app单精度只需要32位存储空间,将大型阵列的内存需求减少了一半。它可能会更快,也可能不会。

MATLAB没有声明,因此单精度变量由双精度变量通过可执行转换函数得到。

P =单()
P =单1.6180340

2004年,MATLAB 7引入了三种无符号整数数据类型,uint32uint16而且uint8,三种有符号整数数据类型,int32int16,int8,和一个逻辑数据类型,逻辑

Q = uint16(1000*phi) r = int8(-10*phi) s =逻辑(phi)
Q = uint16 1618 r = int8 -16 s =逻辑1

让我们看看这些数量需要多少存储空间

名称大小字节类属性p 1x1 4单phi 1x1 8双q 1x1 2 uint16r 1x1 1 int8 s 1x1 1逻辑

稀疏矩阵

1992年,MATLAB 4引入了稀疏矩阵。只存储非零元素,以及行索引和指向列开始的指针。对MATLAB外观的唯一改变是一对函数,稀疏的而且完整的.几乎所有的运算都同样适用于全矩阵或稀疏矩阵。稀疏存储方案在空间上表示一个与非零项数量成比例的矩阵,并且大多数操作计算稀疏结果的时间与对非零的算术操作的数量成比例。

例如,考虑拉普拉斯微分算子的经典有限差分近似。这个函数numgrid为二维网格中的点编号,在这种情况下,正方形内部的n × n点。

清除n = 100;S = numgrid(“年代”(n + 2);

这个函数delsq创建五点离散拉普拉斯矩阵,存储为稀疏N × N矩阵,其中N = N ^2。如果每行有5个或更少的非零,则非零的总数略小于5*N。

A = delsq(S);nz = nnz(A)
新西兰元= 49600

为了便于比较,让我们创建矩阵的完整版本并检查所需的存储量。所需的存储一个成正比于N,而对于F它与N²成比例。

F =满(A);谁
名称大小字节类型属性A 10000x10000 873608双稀疏F 10000x10000 800000000双S 102x102 83232双n 1x1 8双nz 1x1 8双

让我们计算边值问题的解的时间。对于稀疏矩阵,时间是O(N²)。当n = 100时,它是瞬间的。

B = ones(n²,1);tic u = A\b;toc
运行时间为0.018341秒。

整个矩阵时间是O(N^3)计算相同的解需要几秒钟。

tic u = F\b;toc
运行时间为7.810682秒。

细胞数组

Cell数组是在1996年用MATLAB 5引入的。单元格数组是一个索引的,可能是不均匀的MATLAB对象集合,包括其他单元格数组。单元格数组由花括号{}创建。

C ={魔术(3);uint8 (1:10);“hello world”
C = 3×1 cell array {3×3 double} {1×10 uint8} {'hello world'}

单元格数组可以用花括号和圆括号进行索引。加上大括号,c{k}是第k个单元格的内容。在括号中,c(k)是另一个包含指定单元格的单元格数组。

M = c{1} c2 = c(1)
M = 8 1 6 3 5 7 4 9 2 c2 = 1×1 cell array {3×3 double}

可以将单元格数组看作邮箱的集合。箱(k)k-邮箱。盒子{k}邮件在吗kth盒子。

文本

多年来,文本一直是MATLAB中的二等公民。

考虑到跨平台的可移植性,历史性的MATLAB有自己的内部字符集。由单引号描述的文本每次将一个字符转换为范围为0:51的浮点数。小写变成大写。这个过程被DISP函数反转。

下面是一些来自Historic MATLAB的输出。

<> H = 'hello world'
H = 17 14 21 21 24 36 32 24 27 21 13
< > disp (H)
你好世界

MathWorks版本的MATLAB依赖于ASCII字符集,包括大写和小写。字符向量仍然用单引号来描述。

h =“hello world”
H = 'hello world'
disp (h)
你好世界
D = uint8(h)
D = 1×11 uint8行向量104 101 108 108 111 32 119 111 114 108 100

短字符串通常用作函数的可选参数。

[U,S,V] = svd;“经济学”%经济规模,U与A的形状相同。
情节(x, y,“啊——”在数据点处用圆绘制直线。

数组中的多行文本或多个单词必须用空格填充,以便字符数组是矩形的。的字符函数提供此服务。例如,这是一个3 × 7的数组。

Cast = char(“爱丽丝”“鲍勃”“查理”
cast = 3×7字符数组'Alice ' 'Bob ' 'Charlie'

或者,你可以使用单元格数组。

Cast = {“爱丽丝”“鲍勃”“查理”} '
cast = 3×1单元格数组{'Alice'} {'Bob'} {'Charlie'}

字符串

在2016年,我们开始为文本提供更全面的支持,引入了双引号字符和金宝app字符串数据结构。

Cast = [“爱丽丝”“Bob”“查理”]“
cast = 3×1字符串数组"Alice" "Bob" "Charlie"

对于新的字符串数据类型,有一些非常方便的函数。

谚语=“滚石聚势”言语=分裂(谚语)
谚语= "rolling stone gathering momentum" words = 5×1字符串数组"A" "rolling" "stone" " gathering " "momentum"

字符串的相加就是串联。

Merge = cast(1);+ =“+”K = 2:长度(cast) merge = merge + + + cast(K);结束合并
合并= "爱丽丝+鲍勃+查理"

正则表达式函数提供正则表达式在Unix和许多其他编程语言中看到的模式匹配。

命令

在MATLAB的早期,函数和命令之间的区别从来都不清楚。这个问题最终由命令/功能的对偶性:该形式的命令语句

cmd__arg1最长

是同一个函数语句吗字符参数

cmd (“__arg1”,最长”)

例如

日记notes.txt

f =“notes.txt”;日记(f)

函数处理

MATLAB中有以其他函数为参数的函数。这些被称为“函数函数”。多年来,函数参数都是由字符串指定的。例如,假设我们想数值解常微分方程范德堡尔振荡器.创建文件vanderpol.m对微分方程求值。

类型vanderpol
函数dydt = vanderpol(t,y) dydt = [y(2);5 * (1 y (1) ^ 2) * y (2) - y (1)];结束

然后将函数名作为字符串传递给ODE求解器数值

Tspan = [0 150];Y0 = [10 0]';[t,y] = ode45(“vanderpol”tspan, y0);

事实证明,这个计算所需的一半以上的时间都花在重复解码字符串参数上。为了提高性能,我们引入了函数处理,即函数名前加“at”号,@vanderpol

“at符号”还用于创建定义对象的函数句柄匿名函数,是Church的MATLAB实例化微积分

@ (x) sin (x) / x

具有讽刺意味的是,匿名函数通常被分配给变量,从而否定了匿名性。

Sinc = @(x) sin(x)./x;VDP = @(t,y) [y(2);5 * (1 y (1) ^ 2) * y (2) - y (1)];

让我们比较一下Van der pol与字符串、函数句柄和匿名函数集成所需的时间。

Tic, [t,y] = ode45(“vanderpol”tspan, y0);Toc tic, [t,y] = ode45(@vanderpol,tspan,y0);Toc tic, [t,y] = ode45(vdp,tspan,y0);toc
运行时间为0.173259秒。运行时间为0.041710秒。运行时间为0.032854秒。

我们看到后两者所需的时间是相当的,并且明显快于第一个。




发布与MATLAB®R2018a

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。