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
    原文作者:shawn233
    原文地址: https://www.jianshu.com/p/93a2c2f954c7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞