让我们先从一张图片说起:
这幅画是由德国大画家丢勒(Albrecht Dürer)所画,其中布满了数学符号。在右上方的窗户上,你会发现那是一个矩阵。我们就从这里开始。
那么,在这幅名画中出现的矩阵究竟有何神通呢?
其实,这个矩阵被叫做Magic Square,是因为他的每行每列、主对角线和副对角线数字之和全部相等,且都是(1+16)*2=34。
(话说微博网红、艺术科普作家、广告狗顾爷还曾花了很大篇幅在《小顾聊绘画》里介绍丢勒大师,有兴趣的童鞋可以去翻翻,个人感觉挺好看的)
那我们就把它输入到MATLAB里吧~
A = [16 3 2 13; 5 10 11 8; 9 6 7 12; 4 15 14 1]
Hint:试一试第一章介绍的其他的输入方式!
现在,你已经能在工作区(workspace)看到它了,此时我们可以直接用变量名A代指它。
现在我们来介绍几个MATLAB基本函数:
1.求和函数sum:对矩阵的每列求和,如sum(A)的运行结果为:
ans= 34 34 34 34
现在ans已经是一个一行四列的向量了。
如果不指定输出值保存在哪个变量中,MATLAB就会把结果暂时保存在ans变量中。
Q:想一想有几种方法求矩阵A每行之和呢?
Hint:查阅一下官方文档对sum函数的介绍,命令为:doc sum
2.转置矩阵A‘:返回矩阵A的转置矩阵,如A‘的运行结果为:
ans = 16 5 9 4 3 10 6 15 2 11 7 14 13 8 12 1
Hint:在命令行中试一试B=A‘这条命令!
3.翻转函数fliplr:将矩阵的第一列与最后一列交换、第二列与倒数第二列交换……篇幅所限,这里就不再演示fliplr(A)了~
4.对角阵diag:取主对角线元素,作为一个向量。
Hint:试一试sum(diag(fliplr(A‘)))!
5.生成幻方的magic函数:如B = magic(4),MATLAB就会返回给你一个满足条件的幻方:
B = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1
Hint:现在矩阵B与矩阵A都满足幻方(magic square)的性质,那么这两个矩阵有什么不同?
在MATLAB中,你可以通过三种方法来获得一个矩阵:
1.手动输入
2.在mat文件中读取
3.通过MATLAB函数(除了自带的函数,你还可以自己定义一些函数!)生成
其中,最常用的就是第一种和第三种了。
而MATLAB也有许多有用的矩阵构造函数,如:zeros、ones、rand、randn、perms等。
Hint:记得查阅下find函数的官方资料。
变量名:话说MATLAB的变量名会区分大小写,且变量名长度不应大于63个字符(肯定够用啦)。
>>N = namelengthmax >>N = 63
数字:MATLAB支持科学计数法和复数的输入(i 和 j 都是虚数单位),而以下数字都是合法的:
3 -99 0.0001 9.6397238 1.60210e-20 6.02252e23 1i -3.14159j 3e5i
有时,数字的存储方式不当也会造成一些溢出错误,如:
MATLAB stores all numbers internally using the long format specified by the IEEE?
floating-point standard. Floating-point numbers have a finite precision of roughly 16
significant decimal digits and a finite range of roughly 10-308 to 10+308.
Numbers represented in the double format have a maximum precision of 52 bits. Any
double requiring more bits than 52 loses some precision. For example, the following code
shows two unequal values to be equal because they are both truncated:
x = 36028797018963968;
y = 36028797018963972;
x == y
ans =
1
Integers have available precisions of 8-bit, 16-bit, 32-bit, and 64-bit. Storing the same
numbers as 64-bit integers preserves precision:
x = uint64(36028797018963968);
y = uint64(36028797018963972);
x == y
ans =
0
这里,x==y表示“x与y是否相等”。如相等则返回1,否则返回0。
这里再介绍一下MATLAB中的内置排序函数sort: MATLAB把一切数字都当做复数处理,因此每个数字都有其相位角(即与x轴的夹角)。而sort函数则按照“先模长,后相位”的优先级进行排序,如:
>> sort([3+4i, 4+3i,6+8i,5,6]) ans = Columns 1 through 4 5.0000 + 0.0000i 4.0000 + 3.0000i 3.0000 + 4.0000i 6.0000 + 0.0000i Column 5 6.0000 + 8.0000i
你可以通过angle函数查询相位角:
>> angle(3+4i) ans = 0.9273
当然,这是以弧度制储存的。
关于矩阵的基本运算,笔者在MATLAB Quick Start的第一篇就写过了,详情请见这里?http://my.oschina.net/bgbfbsdchenzheng/blog/501141
在构造矩阵时,这些运算特别方便,如:
>> n = (0:9)‘; >> pows = [n n.^2 2.^n] pows = 0 0 1 1 1 2 2 4 4 3 9 8 4 16 16 5 25 32 6 36 64 7 49 128 8 64 256 9 81 512
函数:在MATLAB库中,函数何止千千万。笔者自然也不能逐个介绍。但是官方文档则介绍的相当详细:
For a list of the elementary mathematical functions, type
help elfun %You will see you are familiar with some of them, such as sin,cos,exp....
For a list of more advanced mathematical and matrix functions, type
help specfun
help elmat
Some of the functions, like sqrt and sin, are built in. Built-in functions are part of the
MATLAB core so they are very efficient, but the computational details are not readily
accessible. Other functions are implemented in the MATLAB programing language, so
their computational details are accessible.
There are some differences between built-in functions and other functions. For example,
for built-in functions, you cannot see the code. For other functions, you can see the code
and even modify it if you want.
还有一些预定义过的常量:
如果你让一个非零值除以0,或者得到数值大于matlab允许的最大值(大约为10^308),MATLAB很可能会返回给你一个Inf。而一些无法用数学方法表达的数字,如 Inf-Inf 或者 0/0,则是NaN。
但是,你甚至可以暂时的改变这些常量
>> pi = 4 pi = 4 %此时pi是一个临时变量 >> clear pi %清除对pi的改变 >> pi ans = 3.1416
有时候,我们需要MATLAB按照特定格式显示数字。那么,如何在MATLAB中改变数字格式呢?
很简单,使用 format 命令就好了。
x = [4/3 1.2345e-6] format short %最简单的short型 1.3333 0.0000 format short e %科学计数法,显示的有效位数与short相同 1.3333e+000 1.2345e-006 format short g %优先使用short,必要时使用科学计数法 1.3333 1.2345e-006 format long %long型,输出更多位数 1.33333333333333 0.00000123450000 format long e %%科学计数法,显示的有效位数与long相同 1.333333333333333e+000 1.234500000000000e-006 format long g %优先使用long,必要时使用科学计数法 1.33333333333333 1.2345e-006 format bank %保留两位小数 1.33 0.00 format rat %化为最接近的分数 4/3 1/810045 format hex %十六进制输出 3ff5555555555555 3eb4b6231abfd271
Hint:如果你觉得这些格式还不够用,那么你甚至可以用fprintf和sprintf函数来自定义格式!
说了这么多了,那么如何进行一整行的删除操作呢?其实很简单,把它赋值为空即可!
A(2,:) = [] %删除第二行 A(:,3) = [] %删除第二列
还可以这样玩:
A(1:2,2:3) = 0 %分别将第一、二行的第二、三列元素置为0
逻辑操作:我们可以对特定的元素操作,即使现在不知道它们的下标,而只需要满足一定逻辑条件(如“是实数”、“是素数”等)即可。
现在有这样一个向量:
x = [2.1 1.7 1.6 1.5 NaN 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8];
我们如果想去掉NaN,再把“离群”的5.1去掉,就可以这样操作:
x = x(isfinite(x)) x = 2.1 1.7 1.6 1.5 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8 x = x(abs(x-mean(x)) <= 3*std(x)) %std(x)表示x的标准差 x = 2.1 1.7 1.6 1.5 1.9 1.8 1.5 1.8 1.4 2.2 1.6 1.8
Find函数:非常的简单,如把A中的素数元素替换为NaN,就可以这样操作:
>> A = magic(4) A = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1 >> isprime(A) ans = 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 >> find(isprime(A))‘ ans = 2 5 6 7 9 13 >> A(k) = NaN A = 16 NaN NaN NaN NaN NaN 10 8 9 NaN 6 12 4 14 15 1
现在,我们就可以自己生成“幻方”(Magic Square)了~
p = perms(1:4); %生成4!=24个1-4的组合序列,如(1 2 3 4、 2 3 4 1)等 A = magic(4); M = zeros(4,4,24); for k = 1:24 M(:,:,k) = A(:,p(k,:)); end %此时M就是24个4*4的幻方的“结合体”了,是一个三维的数组。现在我们来查看一下M的大小: >>size(M) ans = 4 4 24
最后,是元胞数组与结构体:
元胞数组(Cell Array)是个筐,什么都能往里装→_→ 只是定义时记得用大括号{}就好了
>>C = {A sum(A) prod(prod(A))} %A是magic square,prod函数即produce of,用于求连乘 C = [4x4 double] [1x4 double] [20922789888000]
还可以用cell来定义一个元胞数组,如下:
M = cell(8,1); %定义一个8行1列的元胞数组 for n = 1:8 M{n} = magic(n); end M M = [ 1] [ 2x2 double] [ 3x3 double] [ 4x4 double] [ 5x5 double] [ 6x6 double] [ 7x7 double] [ 8x8 double]
要想从中选取第四个“元胞”,只需要输入M{4}即可:
>> M{4} ans = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1
下面来说说初级结构体操作:
在MATLAB中,甚至不需要定义一个结构体,直接对它赋值即可:
S.name = ‘Ed Plum‘; S.score = 83; S.grade = ‘B+‘ %查看现在的S >>S S = name: ‘Ed Plum‘ score: 83 grade: ‘B+‘
再来定义个:
S(2).name = ‘Toni Miller‘; S(2).score = 91; S(2).grade = ‘A-‘; S(3) = struct(‘name‘,‘Jerry Garcia‘,... ‘score‘,70,‘grade‘,‘C‘) %现在这个结构体数组已经太大了,因此不会在屏幕上直接显示 S = 1x3 struct array with fields: name score grade
现在我们想要S中的所有grade:
>> S.grade %与S(1).score, S(2).score, S(3).score相同 ans = B+ ans = A- ans = C
我们再来对score做做文章:
>>scores = [S.score] %把S中的score全部提取到scores中 scores = 83 91 70 >>avg_score = sum(scores)/length(scores) avg_score = 81.3333
name元素也一样
>>names = char(S.name) names = Ed Plum Toni Miller Jerry Garcia >>names = {S.name} names = ‘Ed Plum‘ ‘Toni Miller‘ ‘Jerry Garcia‘ >>[N1 N2 N3] = S.name N1 = Ed Plum N2 = Toni Miller N3 = Jerry Garcia
好啦,今天就到这里。话说最近的竞赛一个接一个,上周末因为大学生数模一直没更,这周的周末又是ACM北京区域赛的网赛,下周周末又是合肥区域赛的网赛,所以估计又要几天不更了,恩就是这样。。= =