Matlab学习笔记

本文主要记录一些学习Matlab过程中的一些琐碎的易忘的知识点,以待日后翻阅查看。

快捷键指令

数学运算符

易错点

[x, y] = meshgrid(-3:0.1:2, -5:0.1:5)
[x, y] = meshgrid(-5:0.2:5)

线性代数基础

补充一点线性代数的基础知识:

向量:u=(u1,u2,u3) v=(v1,v2,v3)

单纯行乘列的矩阵乘法公式: u * v'={u1v1+u2v2+u3v3}

叉积公式:cross(u,v)=u x v = {u2v3-v2u3, u3v1-v3u1, u1v2-u2v1}

点积公式:sum(dot(u,v))=sum(u .* v) = u1v1+u2v2+u3v33=|u|*|v|*COS(U,V)

叉乘(向量积)的意义就是通过两个向量来确定一个新的向量,该向量与前两个向量都垂直

点乘(数量积)的结果就是两个向量的模相乘,然后再与这两个向量的夹角的余弦值相乘。或者说是两个向量的各个分量分别相乘的结果的和。很明显,点乘的结果就是一个数,这个数对我们分析这两个向量的特点很有帮助。如果点乘的结果为0,那么这两个向量互相垂直;如果结果大于0,那么这两个向量的夹角小于90度;如果结果小于0,那么这两个向量的夹角大于90度。

求方程的解

普通方法:

增广矩阵:

逆矩阵:

线伪逆矩阵求无限解det(a)=0:

LU分解:

绘制图像

x=[0:0.1:10];
y=cos(x);
plot(x,y),xlabel('x'),ylabel('cos(x)'),gird on,axis equal,legend('cos(x)');

绘制图像+加坐标轴标签+网格+坐标轴间隔相同+图例,当更新x的区间或者间隔的时候,需要重新调用y=cosx来更新y值,否则会报错

fplot('exp(-2*t)*sin(t)',[0, 4]), xlabel('t'), ylabel('f(t)'), title('阻尼弹力')

fplot自动计算间隔,画出平滑的曲线

axis ( [xmin xmax ymin ymax] )

确定绘图的x轴和y轴的绘图范围,axis auto让matlab自动确定x轴和y轴的间距

t = [0:0.02:4];
f = exp(-2*t)*sin(t);??? Error using ==> mtimesInner matrix dimensions must agree.

对方程画图

%ezplot里面的参数需要加''
ezplot('x^2 - 6*x - 12')
d = 'x^2 - 6*x - 12';ezplot(d);
%限定图像定义域
ezplot(d,[x1,x2]);
%限定图像的定义域和值域
ezplot('x+3', [-4, 4, -2, 2])
%错误,ezplot里面没有等号
ezplot('x+3=0')
%正确
ezplot('x+3')

MATLAB 颜色说明符

颜色 key
黑色 k
白色 w
红色 r
黄色 y
绿色 g
蓝色 b
青色 c
洋红 m

绘制极坐标曲线:

theta = [0:pi/90:2*pi];
r = a*theta;
polar(theta,r), title('阿基米德螺线');

绘制双log曲线:

绘制离散图(折线图)

months=['J';'F';'M';'A';'M';'J';'J';'A';'S';'O';'N';'D'];
N=20;
x=(1:N);
y=ceil(12*rand(N,1));
plot(x,y);
set(gca,'YLim',[0 13],'YTick',1:12,'YTickLabel',months)

YLim 限制纵坐标的总范围0~13

YTick 月份对应点在总范围中的部分1~12

YTickLabel 纵轴的文字标定值

绘制离散图(柱状图)

x = [1:5];y = [50,98,75,80,98];
bar(x,y), xlabel('学生'),ylabel('分数'), title('期末测试')
%水平的柱状图
barh(a,b),xlabel('学生人数'),ylabel('考试分数')
%三维柱状图
bar3(a,b),xlabel('考试分数'),ylabel('学生人数')

%默认是非分组的柱状图
bar(x, y, grouped);
%设置分组柱状图
bar(x, y, stacked);
x = [54.5,64.5,74.5,84.5,94.5];
garcia= [0; 3; 18; 13; 10];
simpson= [3; 5; 20; 10; 5];
smith= [1; 2; 15; 17; 8];
y = [garcia simpson smith];
bar(x,y),xlabel('考试分数'),ylabel('学生人数'),legend('加西亚','辛普森','史密斯')

绘制离散图(针头图)

plot(t,f),xlabel('时间(秒)'),ylabel('弹簧响应')
%替换为:
stem(t,f),xlabel('时间(秒)'),ylabel('弹簧响应')
%填充绿色菱形标记:
stem(t,f,'--dg','fill'),xlabel('时间(秒)'),ylabel('弹簧响应')


等高线图(二维+三维)

​[x,y] = meshgrid(-5:0.1:5, -3:0.1:3);
%[x,y] = meshgrid(-2:0.1:2);如果两个变量的取值范围相同,可以只写一次z = x.^2 + y.^2;[C,h] = contour(x,y,z);%c是等高线矩阵,h是等高线句柄
%给等高线加上图例set(h,'ShowText','on','TextStep',get(h,'LevelStep')*2)
%变成三维图像,30指的是等高线的密度
contour3(x, y, z, 30);
%装扮图像
surface(x,y,z,'EdgeColor',[.8 .8 .8],'FaceColor','none')
grid off;view(-15,20);%摄像机沿着x,y轴移动

解释set指令的参数:

contour(x,y.z):(x,y)是平面z=0上点的坐标矩阵,z为相应点的高度值矩阵。

[C,h]=contour(x,y,z):C 为返回等值线矩阵,h为图形对象的句柄向量,也就是代表所绘制图形;

set(h,'ShowText','on','TextStep',get(h,'LevelStep')*2)
h:图形对象;

ShowText:显示等高值标签命令,后面设置’on’,就是打开显示标签;

TextStep:标签的步长;

LevelStep:等高线步长;

get(h,'LevelStep'):得到等高线步长的值。

这个命令就是从第一个等高线开始,每隔一个给等高线贴上标签。

三维图像

%绘制圆柱体
t = 0:pi/10:2*pi;[X,Y,Z] = cylinder(1+sin(t));surf(X,Y,Z);
axis square;
%普通三维图像
mesh(x,y,z),xlabel('x'),ylabel('y'),zlabel('z')
%表面颜色过渡的图像
surf(x,y,z),xlabel('x'),ylabel('y'),zlabel('z')
%底部有等高线映射的图像
surc(x,y,z),xlabel('x'),ylabel('y'),zlabel('z')
%图象中的阴影可以设置为flat、interp和faceted。
%flat 是用同一颜色为每个网格进行着色并隐藏网格线
%而 facted 则显示网格
%使用 interp 是 告诉 MATLAB 使用颜色插值的办法进行着色,因此显得非常平滑
surfl(x,y,z),xlabel('x'),ylabel('y'),zlabel('z');shading interp;%将图像着色为灰色colormap(gray);

逻辑控制

if_else判断

myaverage.m文件的内容(文件名与函数名务必相同,否则无法调用)

function ave = myaverage(x,N)
sizex = size(x);
sizeN = size(N);
if sizex(2) ~= sizeN(2)
disp('错误:数据必须具有相同的维数。')
else
total = sum(N);
s = x.*N;
ave = sum(s)/total;
end
end

for循环

for index = start : increment : finish
statements end

input输入

r = input('输入半径:')

while循环

while condition
statements end

switch_case语句

switch expression
case 1
do these statements
case 2
do these statements
case n
do these statements
end

解方程

一元一次方程

%'a'的意义是标定未知量,这样剩下的一个字母被认为是常量
%solve('a*x + 5=0','a')和solve('a*x + 5','a')是一样的,=0是默认值
solve('a*x + 5','a')
MATLAB 响应输出为:
ans =
-5/x

一元二次方程

s = solve('x^2 - 6*x - 12 = 0')
s=
3 + 21^(1/2)
3 - 21^(1/2)
%这两个值可以用s(1),s(2)取到
d = 'x^2 + 9*x -7 = 0';
solve(d);
%强制转换格式,可以将多项式转化为小数
x = double(s(1))

二元一次方程组

s = solve('5*x + 4*y = 3','x - 6*y = 2');
%使用点句号“.” 我们就可以取得相应的 x 和 y 值
s.x
s.y

方程的展开(多个多项式相乘)

%定义变量x
syms x expand((x - 1)*(x + 4))

方程的合并和化简(分配多项式)

collect(x*(x^2 - 2))
%经测试,可以被expand代替

因式分解

factor(112)%分解数字
factor(x^2 - y^2)
factor([x^2-y^2, x^3+y^3])%多个因式同时分解

多项式相除

%多项式相除
syms x;
simplify((x^4-81)/(x^2-9))
ans =
x^2+9
%log函数化简
syms x;
simplify(exp(2*log(3*x)))
ans =
9*x^2
%三角恒等式
syms x;
simplify(cos(x)^2-sin(x)^2)
ans =
2*cos(x)^2-1
simplify(cos(x)^2+sin(x)^2)
ans =
1

使用指数和对数函数求解方程

eq = 'log10(x) - log10(x - 3) = 1';
s = solve(eq);

泰勒级数展开式

taylor(sin(x),'order',20)//20为展开的项数

极限计算

独立变量趋近于0

%limit(f)
limit((x^3 + 1)/(x^4 + 2))

独立变量趋近于非0

%limit(f, a)
limit(x + 5,3)

独立变量趋近于无穷大(小)

%limit(f,inf)
%limit(f,-inf)
limit(sqrt(x^2+x)-x,inf)

左极限和右极限

a = limit(f,x,3,'left')
b = limit(f,x,3,'right')

求导数

%一阶导数
diff(f)
%n阶导数
diff(f,n)

检查等式两边的式子是否相等

isequal(a,f)

将常数代入方程得到结果

subs(h,2)
%将多个常数代入求得方程的结果
subs(F,{b,x},{2,4})

求解符号微分方程

%dsolve('eqn', 'cond1', 'cond2', ...),cond1等是初始条件
dsolve('Dy = y*t/(t-5)','y(0) = 2')
dsolve('D2y - y = 0','y(0) = -1','Dy(0) = 2')

常微分方程(ODE)求解

s = dsolve('Dy=a*y')
s =
C1*exp(a*t)
C1 = 2; a = 4;
%将常数代入字母为系数的方程
f = subs(s)
f=
2*exp(4*t)
%或者
f = subs(s,'C1',2);

方程组和相平面图

设置曲线图像细节

%调用 findobj 命令告诉 MATLAB 查找图象中的线条,然后使用 set 命令为线条设置颜色(最后所有的line都变为红色)
ezplot(s.X),set(findobj('Type','line'),'Color','r')
%调用 get 命令,它将返回当前图形对象的句柄
h=get(gca,'children');
%使用下面的命令改变它(单独的一条line变为虚线)
set(h(1),'linestyle','--')

常微分方程(ODE)的数值解

使用ODE23和ODE45求解一阶方程

我们创建一个.m文件,输入下面的内容。

function ydot = eq1(t,y)
ydot = cos(t);

通过调用ODE32/ODE45函数来求解ODE(产生的是t和对应的y的数组元素)

%[t,y] = ode23('func_name', [start_time, end_time], y(0))
[t,y] = ode23('eq1',[0 2*pi],2);
%[t,y] = ode45('func_name', [start_time, end_time], y(0))
[t,w] = ode45('eq1',[0 2*pi],2)

首先我们产生一个表示解析解的数集,然后我们可以比较:

f = 2 + sin(t);

使用下面的命令来产生图象:

plot(t,y,'o',t,f),xlabel('t'),ylabel('y(t)'),axis([0 2*pi 0 4])
plot(t,w,'o',t,f),xlabel('t'),ylabel('y(t)'),axis([0 2*pi 0 4])

ODE23

ODE45

ODE23与ODE45区别:

  1. 如果误差对你非常重要,那么使用ode45将是明智的选择,ODE45误差小
  2. 根据数值画出的点比前面我们从ode32得到的密度要高

带有扰动的常微分方程

function ydot = eq2(t,y)
global tc w
F = t*exp(-t/tc)*cos(w*t);
ydot = 5*(F-y);
tc = 0.1; w = 6.28;
final_time = 1.0;
[t,y] = ode45('eq2',[0 final_time],y0);
plot(t,y),xlabel('t'),ylabel('y(t)'),axis([0 0.7 0 0.015])
plot(t,y,t,F,'--'),xlabel('t'),ylabel('y(t)'),axis([0 0.7 0 0.05])

二阶方程求解

function xdot = eqx(t,x);
%创建数组储存数据
xdot = zeros(2,1);
xdot(1) = -x(1)^2 + x(2);
xdot(2) = -x(1) - x(1)* x(2);
[t,x] = ode45('eqx',[0 10],[0,1]);
plot(t,x(:,1),t,x(:,2),'--'),xlabel('t'), axis([0 10 -1.12 1.12])

二阶方程求解需要把这个方程换成一阶方程组

积分计算

INT命令

%int(f)
%int(f, v) 语法来调用 int,其中 f 就是要积分的函数,而 v 是积分变量
syms x;
int(x)

对于计算积分的读者来说,不要忘记在你的答案后面带上积分常量

定积分

int('x',2,3)

or

F = int(x);
subs(F,x,3)-subs(F,x,2)

多重积分

int(int(int(x*y^2*z^5,x),y),z)

int(int(f,x,2,4),y,1,2)

数值积分

调用 trapz(x, y)函数 MATLAB 可以进行梯形积分

%等分次数越多,误差越小
x = linspace(0,2,10);
y = x.^2;
a = trapz(x,y);
a=
2.6831

正交积分

MATLAB 有两个命令 quad 和 quad1 可以用来实现正交积分。这种类型的方法基于使用 二次函数代替矩形更能接近曲线下方面积的原理(使用高阶的多项式还能够得到更精确的结 果)。辛普森法则(Simpson’s rule)是把积分区间分成偶数段,相邻两段下面的面积用不同 的二次函数近似表示。quad 函数采用适应辛普森法则的逼近方法进行数值积分。要使用 quad,把被积的函数传递给它,后面跟着积分区间。
quadl 函数采用洛巴托(Lobatto)积分法。这是一种适应正交积分更加灵活复杂的类型, 查阅 MATLAB 的帮助以便获得更多的信息。

quad 和 quadl 函数的不利方面是无法对点集进行积分。

quad('exp(-2*x)'',0,1/8)

数据拟合

%n 是我们要 MATLAB 求出的多项式的次数
%对于 y = mx + b 形式的方程,我们把 n 设为等于 1,
%因此调用的语句将是 polyfit(x, y, 1)
%n次多项式有n+1个常数系数
polyfit(x, y, n)
如果我们使用 p = polyfit(x, y, n)调用 polyfit,第 j 个系数的引用写成 p(j)
m = p(1)
b = p(2)

指数函数的拟合

拟合程度

当r^2接近1,或者,RMS小于1,则说明拟合程度比较好。

%其中,AVE是原有的数据,MEAN是原有数据的平均值,w是拟合数据,S和A公用的数据是AVE,即原有数据
S = sum((Ave - MEAN).^2)
A = sum((w - Ave).^2)
r2 = 1 - A/S

另一种我们可以用来体现拟合程度的方法是计算一个称为均方根(Root-Mean-Square,RMS)误差的数 值,要用过这种方法来评估多项式与实际数据的拟合程度,我们可以使用下面的命令:

w = m*sqft + b
d = price - w;
N = 10;
d2 = d.^2;
RMS = sqrt((1/N)*sum(d2))

可以使用 find 命令提问与数据有关的问题。例如,温度小于 80 度是在什么时候

find(y < 80)