MATLAB | MATLAB基本运算

19-03-06更新:现在我又觉得Python(Numpy+Pandas)最好用了 >_< 建议大家坚持初心就好,适合自己的才是最好的。我是CS学生,需要经常用脚本语言处理数据,这个时候,我最需要的就是能将矩阵处理与脚本语言结合的工具,那么当然是Python啦~
18-06-10更新:最近在用Mathematica,发现在矩阵处理以外的领域其功能远超MATLAB,推荐给各位


【原文】

本文旨在总结我在刚结束的MCM/ICM比赛中习得的MATLAB知识。总结的顺序力求由浅到深,以便日后复习。

MATLAB的下标从1开始

一、 基础:矩阵创建篇

这一章的标题用的不是“定义”,而是“创建”。这是因为这一章讲的不是严格的矩阵定义语法,而是在宽泛的应用中能够应用的矩阵创建方法。

MATLAB中,矩阵创建的方法有很多种。我在这里介绍常见的几种。

1 仅指定大小的zeros指令

用到的指令是zeros(n)zeros(sz1, ..., szN)

zeros(n)创建一个n*n的零矩阵。

>> zeros(5)

ans =

     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0

若要指定矩阵的维度和大小,可以用zeros(sz1, ..., szN)创建任意确定大小和维度零矩阵。

>> zeros(1, 5)

ans =

     0     0     0     0     0

>> zeros(5, 1)

ans =

     0
     0
     0
     0
     0

>> zeros(2, 3, 4)

ans(:,:,1) =

     0     0     0
     0     0     0


ans(:,:,2) =

     0     0     0
     0     0     0


ans(:,:,3) =

     0     0     0
     0     0     0


ans(:,:,4) =

     0     0     0
     0     0     0

>> 

有很多类似zeros的指令,可以指定矩阵的维度和大小,还可以对矩阵内的元素赋值。有使用需要时可以自行查找。(如ones, eye等)

2 指定开始 步长 结束 来创建一个向量

语法为

start : step : end
>> 1:1:10

ans =

     1     2     3     4     5     6     7     8     9    10

>> 1:3:10

ans =

     1     4     7    10

这个指令常见于for-end循环,也可以用来快速创建向量。

3 指定值和大小的枚举式定义

这种创建的方法在很多教程中被列为第一种方法,但是我个人并不喜欢这种枚举的定义表达式。

这种创建方法常用于创建维度为2的矩阵。使用时仅需要记住,分隔元素,;分隔行。逗号可以用空格代替。

逗号分隔元素,分号分隔行。

>> [1, 2, 3; 4, 5, 6]

ans =

     1     2     3
     4     5     6

>> [1, 2, 3; 4, 5]     %出错,不同行的长度必须一致
串联的矩阵的维度不一致。 
 
>> [1 2 3; 4 5 6]       %逗号可以用空格代替

ans =

     1     2     3
     4     5     6

>> [1, 2, 3, 4, 5]

ans =

     1     2     3     4     5

>> [1; 2; 3; 4; 5]

ans =

     1
     2
     3
     4
     5

4 不指定值和大小的定义

这个方法的语句很简单。

a = [];

这样定义的矩阵在使用时是直接对特定位置的元素赋值,因此有必要简单了解矩阵索引的形式。

MATLAB的矩阵索引是括号表达式,不同维度间用逗号分隔。如a(3, 2)。当二维矩阵的某一维长度为1时,可以仅用一个数字作为索引。如a(4)

知道了矩阵索引后,我们可以直接对想要赋值的位置赋值。这时该矩阵的行为非常重要。

  • 如果目前的矩阵包含了指定的位置,直接赋值
  • 如果目前的矩阵不够大,以至于指定的元素在矩阵之外。这时矩阵会扩大直至包括了指定的位置。扩大的部分全部赋值为0,指定的位置按指定值赋值。
>> a = [];
>> a (3, 4) = 5

a =

     0     0     0     0
     0     0     0     0
     0     0     0     5

>> a = [];
>> a (5) = 6

a =

     0     0     0     0     6

5 矩阵分割,获取大矩阵的一部分

MATLAB支持矩阵分割操作,但和python的分割不完全相同。主要体现在:的使用上。

二维矩阵分割语法:

b = a(m1 : m2, n1 : n2);

如果某一维不分割,即保留整行或整列时,这一维的分割可以直接写为:,不用加数字。但是,只要不是整行或整列,冒号前后的数字都要写,不能省略。(和python的区别)

>> a = [1, 2, 3; 4, 5, 6; 7, 8, 9]

a =

     1     2     3
     4     5     6
     7     8     9

>> b = a(1:2, 1:2)

b =

     1     2
     4     5

>> b = a(:, 1:2)

b =

     1     2
     4     5
     7     8

>> b = a(:2, 1:2)      %出错,此时冒号前后的数字都不能省略
 b = a(:2, 1:2)
        ↑
错误: 不应为 MATLAB 表达式。
 

经检验,用上述指令分割的矩阵独立,即程序为新的矩阵单独开辟了存储空间。

二、MATLAB基本指令一览

MATLAB只使用单引号。

1 控制台输入输出 input, disp, 和 fprintf

num = input ('请输入数字:');
disp(num);

input指令的括号中是提示语句,执行时会在控制台显示。
disp括号中是显示的元素,一般任何变量都能用disp显示,不过只能显示一个变量。

重点讲fprintf。这个指令非常类似c++printf,第一个参数是控制串,用%d %f %s等控制格式,后面跟着的参数是控制符对应的变量。

>> a1 = 3;
>> a2 = 5.4;
>> a3 = 'matlab good';
>> fprintf('%d is not %f, but %s', a1, a2, a3);
3 is not 5.400000, but matlab good>> 
%在控制台键入该指令时会询问输出到哪个文件里

2 文件输入输出

3 图片输入输出

saveas (gcf, <filename>);

gcf是一个保留字,作为saveas的第一个参数。

filename的位置上填路径和文件名,Windows操作系统中路径由\连接而成,注意文件名包含了后缀,即指定了目标格式。

常用的文件名可以有*.pic

4 判断语句 if-elseif-else-end 和 switch-case-end

if判断的语法

if 条件1
    语句块1
elseif 条件2
    语句块2
elseif ...
    ...
elseif 条件n-1
    语句块n-1
else
    语句块n
end

switch判断的语法

switch-case-end语法1 单值匹配

switch (switch_expr)
    case case_expr_1,
        statement_1
    case case_expr_2,
        statement_2
            ...
    otherwise,
        statement_other
end

swtich-case-end语法2 多值匹配

switch(switch_expr)
    case {case_1, case_2, case_3},
        statement_1
    case {case_4, ...},
        ...
    otherwise,
        statement_other
end

5 循环语句 for-end 和while-end

for-end循环的基本语法是

for <var> = <vector>
    循环体
end

<var>是控制变量,在for-end循环中不停地从<vector>向量中获取下一个元素。

因此,for-end循环每循环一次,向量<vector>中的下一个元素就被赋值给控制变量<var>。知道<vector>中元素耗尽,循环结束。

while-end循环的基本语法是

while 条件
    循环体
end

只要条件为真,就会执行一遍循环体。

可以用continuebreak指令控制循环。

6 绘图指令 plot 及图像调整指令 legend 等

plot指令用来绘制折线图,语法如下。

plot ( <x>, <y>, <shape> );

<x>向量和<y>向量对应一系列点的横纵坐标,<shape>参数用来指定折线的形状。常见的有*-, x-, o-, r:x等。

画出来的图会直接显示出来,如果想要将多条曲线画在一幅图上,只需要在plot后执行

hold on;

下面的指令可以设定图像的一些信息。

xlabel ( <xlabelname> );     %指定横坐标的名字
ylabel ( <ylabelname> );     %指定纵坐标的名字
legend ( <name1>, <name2>, ..., <nameN> );    %依次指定各曲线的图例文本

7 拟合工具 cftool 和 lsqcurvefit

直接在控制台执行cftool即可显示cftool的界面,左上选定每一维的向量,右上设定拟合方式,左下显示拟合结果,右下图示拟合结果。

>> cftool;

lsqcurvefit用于多元非线性拟合。详细讲来很复杂,我直接贴上代码。

function multifit (pp, gdp, prd, prc, cons)
%多元拟合函数,参数是很多向量

x = [pp; gdp; prd; prc];   %创建x矩阵
y = cons;   %指定y轴变量

opt = optimset('MaxFunEvals',50000, 'MaxIter', 10000, 'TolFun', 1E-10);   
%指定lsqcurvefit的一些选项
%MaxFunEvals 设定最大拟合次数
%MaxIter
%TolFun

b0 = [1, 1, 1, 1, 10];   
%制定初始参数,这个变量有时会影响拟合结果,注意最后一个是常数项

b = lsqcurvefit (@myfun, b0, x, y, [], [], opt);   
%拟合,myfun函数见下,拟合的结果参数存在变量b中

disp (b);
plot (y, 'o-');   %画出y,此时横坐标从1开始,直到size(y)
hold on;   %在这副图中再叠加一条曲线

plot (myfun(b, x), 'r:x');   %画出拟合的曲线(折线)
saveas(gcf, 'data\part1_b_fit\tx_petro.fig') %保存图片
end

function y = myfun (x, xdata)
%myfun是指定的拟合函数原型,这里是一个对数线性函数原型
%参数x表示函数原型中的参数
%参数xdata中包含了所有变量的所有取值

A = x(1);
B = x(2);
C = x(3);
D = x(4);
E = x(5);   %常数项

pp = xdata (1, :);
gdp = xdata (2, :);
prd = xdata (3, :);
prc = xdata (4, :);

y = exp(A*log(pp+1) + B*log(gdp+1) + C*log (prd+1) + D*log(prc+1) + E);
end

三、其他函数

size

一个参数时返回一个矩阵,表示参数变量的尺寸。

可选第二个参数n,指定返回第n维的尺寸。

figure

保留原图像,创建一张新的图像。

strcmp

比较字符串内容,相同返回真,不同返回假。常用在条件语句中。

cell

创建一个元胞(cell)矩阵。参数为矩阵的行数和列数。

数值操作

这一部分介绍4个指令:floor,ceil,round,fix

  • floor 是下取整
  • ceil 是上取整
  • round是绝对值四舍五入取整
  • fix是向0取整
floor(1.6) %=1
ceil(1.6) %=2
round(1.6) %=2
fix(1.6) %=1

floor(-3.5) %=-4
ceil(-3.5) %=-3
round(-3.5) %=-4
fix(-3.5) %=-3
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 显示中文帮助的方法 预设→常规→帮助→在mathworks.com网站上(需要Internet连接)→语言(简体中...
    VeyronC阅读 2,460评论 0 34
  • MATLAB基本数据类型 双精度/单精度/整形 数据的范围 务必注意溢出的问题。 函数 类型检查 class is...
    hainingwyx阅读 5,664评论 0 6
  • 写在之前 因为简书字数限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx阅读 13,900评论 0 41
  • 雨点终于掉下来了 在亲戚们都离开的时候 巷子里的犬吠 在描绘童年的回忆 心情早被连绵不绝的想念淹没 而故事卡在某个...
    租了五颗星阅读 401评论 1 1
  • 你说你要走了 虽然我知道 不说但我真的不舍 虽然我知道 我的爱慕只于你 虽然我知道 知道只能是你知心的朋友 知道可...
    夜雪东山阅读 216评论 0 1