抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前面的话

准备打数模竞赛,记录一下学习MATLAB的笔记。

最开始看到MATLAB个人版还挺贵的,想着既然有了edu邮箱能不能申请免费的学生版。

申请前还是有点担心SCNU没买MATLAB的教育版授权。

用edu邮箱注册后发现直接就有了学生版许可证。体验到了一把学校带来的福利,挺爽的。

MatLab入门

变量

命名规则

  1. 变量名必须是不含空格的单个词
  2. 变量名区分大小写
  3. 变量名最多不超过19个字符
  4. 变量名必须以字母打头,之后可以是任意字母、数字或下划线,变量名中不允许使用标点符号

看起来跟正常的编程语音命名规则差不多,不过区别在于第三条,平时可能也用不到

特殊变量表

image.png

所以eps相当于无穷小

数学运算符号及标点符号

image-1.png

正常乘法都用点乘,单一个*符号表示矩阵乘

数学函数

image-2.png

大部分还是比较好理解的,有什么用这个函数就叫什么,实在想不起来搜一下也行

M文件

MATLAB的内部函数是有限的,有时为了研究某一个函数的各种性态,需要为MATLAB定义新函数。

自定义函数

函数文件是文件名后缀为M的文件,这类文件的第一行必须是一特殊字符function开始,格式为:

1
function 因变量名=函数名(自变量名)

函数值的获得必须通过具体的运算实现,并赋给因变量.

在命令行里输入edit '文件名.m'就可以打开编辑器,同时在编辑器里打开该文件,如果不存在就创建。创建前注意当前工作区路径。

定义函数例子

f(x1,x2)=100(x2x12)2+(1x1)2f(x_1,x_2)=100\cdot(x_2-x_1^2)^2+(1-x_1)^2

  1. 建立M文件: fun.m
1
2
function f=fun(x)
f=100*(x(2)-x(1)^2)^2+(1-x(1))^2
  1. 可以直接使用函数fun.m

例如:计算f(1,2)f(1,2),只需要在MATLAB命令窗口键入命令:

1
2
x=[1 2]
fun(x)

数组

创建简单的数组

x=[a b c d e f]创建包含指定元素的行向量。
x=first:last
创建从first开始,步长为1,到last结束的行向量。

相当于python中的range(first,end)

x=first:increment:last
创建从first开始,加increment计数,到last结束的行向量。

相当于python中的range(first,last,increment)

x=linspace(first,last,n)
创建从first开始,到last结束,有n个元素的行向量。

linspace并没有指定步长,它一定会生成n个元素。例如linspace(1,10,2)会生成[1 3.25 5.5 7.75 10]这5个均匀分布的元素。
linspace跟上面的区别就是它的步长是不确定的,而上面的是个数不确定。例如1:5:10会以5为步长,生成的个数并没有确定,最终生成的数组是[1 6](因为下一个要生成的是11,大于了last值10,所以最后只有两个数字)

x=logspace(first,last,n)
创建从first开始,到last结束,有n个元素的对数分隔行向量。

这个真有点难理解。大概应该是会生成10first10^{first}10last10^{last},元素个数为nn。元素之间的差值是指数级增长的。
例如:logspace(1,3,4)会生成[10 46.4158883361278 215.443469003188 1000]。它们两两元素之间的差值就是[36.4158883361278 169.027580667060 784.556530996812]。这三个数用指数函数来拟合可以得到:
指数 曲线拟合(exp1)
f(x)=aexp(bx)f(x) = a*exp(b*x) 等价于f(x)=aebxf(x) = a * e^{b{\cdot}x}
系数和 95% 置信边界
值 下限 上限
a 7.8456 7.8456 7.8456
b 1.5351 1.5351 1.5351
拟合优度 值
R 方 1.0000
可以看到R 方数值为1,说明指数函数完全拟合这个间距。

数组元素的访问

  1. 访问一个元素
    x(i)表示访问数组xx的第ii个元素。
  2. 访问一块元素
    x(a:b:c)表示访问数组xx的第aa个元素开始,以步长bb到第cc个元素(但不超过cc),bb可以为负数,bb若不填默认为11
  3. 直接使用元素编址序号
    x([a b c d])表示提取数组xx的第a,b,c,da,b,c,d个元素构成一个新的数组[x(a) x(b) x(c) x(d)][x(a) \space x(b) \space x(c) \space x(d)]

前面例子中的数组都是一行数列,是行方向分布的. 称之为行向量.
数组也可以是列向量,它的数组操作和运算与行向量是一样的,唯一的区别是结果以列形式显示.

产生列向量有两种方法:

  1. 直接产生,例c=[1;2;3;4]
    以空格或逗号分隔的元素指定的是不同列的元素,而以分号分隔的元素指定了不同行的元素.

分号表示当前行结束

  1. 转置产生,例b=[1 2 3 4]; c=b′

单引号(')运算符是转置运算符,它可以将列转为行,行转为列。
例如x=[1 2 3 4]; x'的结果就是[1;2;3;4]。举个333*3矩阵的例子吧。

x=x =

1 2 3
4 5 6
7 8 9

x=x' =

1 4 7
2 5 8
3 6 9

数组的运算

数组对标量

数组对标量的加、减、乘、除和平方运算,是指数组的每个元素对该标量施加相应的加、减、乘、除、平方运算。
设:a=[a1,a2,,an]a=[a_1,a_2,…,a_n], cc是标量.
a+c=[a1+c,a2+c,,an+c]a+c=[a_1+c,a_2+c,…,a_n+c]
a.c=[a1c,a2c,,anc]a.*c=[a_1*c,a_2*c,…,a_n*c]
a./c=[a1/c,a2/c,,an/c] (右除)a./c= [a_1/c,a_2/c,…,a_n/c] \space (右除)
a.\c=[c/a1,c/a2,,c/an] (左除)a. \backslash c= [c/a_1,c/a_2,…,c/a_n] \space (左除)
a. \^\ c= [a_1 ^ c,a_2 ^ {c},…,a_n^{c}]
c. \^\ a= [c ^ {a_1},c ^ {a_2},…,c^{a_n}]

数组对数组

当两个数组有相同维数时,加、减、乘、除、幂运算可按元素对元素方式进行,不同大小或维数的数组是不能进行运算的。
设:a=[a1,a2,,an],b=[b1,b2,,bn]a=[a_1,a_2,…,a_n], b=[b_1,b_2,…,b_n]
a+b=[a1+b1,a2+b2,,an+bn]a+b=[a_1+b_1,a_2+b_2,…,a_n+b_n]
a.b=[a1b1,a2b2,,anbn]a.*b= [a_1*b_1,a_2*b_2,…,a_n*b_n]
a./b=[a1/b1,a2/b2,,an/bn]a./b= [a_1/b_1,a_2/b_2,…,a_n/b_n]
a.\b=[b1/a1,b2/a2,,bn/an]a. \backslash b=[b_1/a_1,b_2/a_2,…,b_n/a_n]
a. \^\ b=[a_1^{b_1},a_2^{b_2},…,a_n^{b_n}]

矩阵

逗号或空格用于分隔某一行的元素,分号用于区分不同的行. 除了分号,在输入矩阵时,按Enter键也表示开始新一行. 输入矩阵时,严格要求所有行有相同的列.
image-3.png

特殊矩阵的建立

a=ones(m,n) 产生一个m行n列的元素全为1的矩阵
b=zeros(m,n) 产生一个m行n列的零矩阵
c=[ ] 产生一个空矩阵,当对一项操作无结果时,返回空矩阵,空矩阵的大小为零
d=eye(m,n) 产生一个m行n列的单位矩阵

所谓的单位矩阵就是一个主对角线元素为11且其他位置元素为00nmn\cdot m矩阵。

矩阵中元素的操作

  1. 矩阵AA的第rrA(r,:)
  2. 矩阵AA的第rrA(:,r)

牢记逗号前后是先行后列

  1. 依次提取矩阵AA的每一列,将AA拉伸为一个列向量:A(:)

[1 2 3;4 5 6;7 8 9]会变成[1;4;7;2;5;8;3;6;9]画一下就能明白了。

  1. 取矩阵AA的第i1i2i_1 \sim i_2行、第j1j2j_1 \sim j_2列构成新矩阵:A(i1:i2, j1:j2)
  2. 以逆序提取矩阵AA的第i1i2i_1 \sim i_2行,构成新矩阵:A(i_2:-1:i_1,:)
  3. 以逆序提取矩阵AA的第j1j2j_1 \sim j_2行,构成新矩阵:A(:,j_2:-1:j_1)
  4. 删除AA的第i1i2i_1 \sim i_2行,构成新矩阵:A(i_1:i_2,:)=[]

赋值操作,赋值一个空数组

  1. 删除AA的第j1j2j_1 \sim j_2列,构成新矩阵:A(:,j_1:j_2)=[]
  2. 将矩阵A和B拼接成新矩阵:[A B]; [A;B]

拼接语句是这个[A;B]

矩阵的运算

  1. 标量-矩阵运算

标量-数组运算相同

  1. 矩阵-矩阵运算
    (1) 元素对元素的运算,同数组-数组运算
    (2) 矩阵运算
    矩阵加法:A+B
    矩阵乘法:A*B
    方阵的行列式:det(A)
    方阵的逆:inv(A)
    方阵的特征值与特征向量: [V,D]=eig[A]

后面三个线代再慢慢理解吧,现在看都看不懂

关系与逻辑运算

逻辑运算符

  1. 关系运算符
    image-5.png
  2. 逻辑运算符
    image-4.png

控制流

MATLAB提供三种决策或控制流结构
for循环 while循环 if-elseif-else结构

for循环

允许一组命令以固定的和预定的次数重复

1
2
3
for x=array
{commands}
end

在for和end语句之间的命令串{commands}按数组(array)中的每一列执行一次. 在每一次迭代中,x被指定为数组的下一列,即在第n次循环中,x=array(:,n)
例如:
n=1,2,...,10n=1,2,...,10,求xn=sin(nπ10)x_n=sin(\frac{n \cdot \pi}{10})的值。

1
2
3
for n=1:10
x(n)=sin(n*pi/10);
end

while循环

与for循环以固定次数求一组命令相反,while循环以不定的次数求一组语句的值。

1
2
3
while  (expression)
{commands}
end

只要在表达式(expression)里的所有元素为真,就执行while和end语句之间的命令串{commands}。

if-elseif-else结构

有一个选择的一般形式是:

1
2
3
if (expression)
{commands}
end

如果在表达式(expression)里的所有元素为真,就执行if和end语句之间的命令串{commands}.
例如:
image-6.png

1
2
3
4
5
6
7
8
9
function f=fun2(x)
if x>1
f=x^2+1
else if x<=0
f=x^3
else
f=2*x
end
end

练习

  1. 用起泡法对10个数由小到大排序. 即将相邻两个数比较,将小的调到前头。

这题其实就是冒泡排序,考察for循环的使用

1
2
3
4
5
6
7
8
a=randi(10,[1 5]); %生成1~10的一个1x5的矩阵(其实就是一个有五个元素的数组)
for i=1:length(a) %i从1->a的长度,相当于for(int i=1;i<=length(a);++i)
for j=1:length(a)-i
if a(j) > a(j+1)
a([1 j])=a([1 j+1]); %这样子写可以一句话交换a[j]和a[j+1]的数据,原理还不清楚
end
end
end
  1. 有一个454*5矩阵,编程求出其最大值及其所处的位置。

直接用max函数。[val idx] = max(a,[],“all”)

1
2
3
4
a=randi(10,[4,5])
[val idx] = max(a,[],"all") %val就是找到的最大值,idx是矩阵的索引(一列一列来)。
%如果只有个max就只是找到每一列的最大值,返回的也不只是一个数,有多少列就有多少个最大值。
%上面这样写就可以返回整个矩阵的最大值
  1. 编程求n=120n!\sum_{n=1}^{20}n!
1
2
3
n=1:20;
y=factorial(n) %求阶乘
y_sum=sum(y) %计算总和
  1. 一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下. 求它在第10次落地时,共经过多少米?第10次反弹有多高?
1
2
3
4
5
6
height=100
s=0
for i=1:10
s=s+height;
height=height./2;
end
  1. 有一函数f(x,y)=x2+sinxy+2yf(x,y)=x^2+sinxy+2y,写一程序,输入自变量的值,输出函数值.
1
2
3
4
x=input("please input the value of x:\n");  %input函数跟python有点像
y=input("please input the value of y:\n");
f=x.^2+sin(x.*y)+2.*y;
fprintf('f(x,y)=%f\n',f) %虽然 disp 可以用于显示数值,但在需要格式化输出的情况下,fprintf 更常用,因为它可以更灵活地处理格式说明符,并更好地适应不同类型的输出。

评论