Matlab-基础

句柄

句柄handle是什么?
(1) 句柄的英文是 handle。在英文中,有操作、处理、控制之类的意义。作为一个名词时,是指某个中间媒介,通过这个中间媒介可控制、操作某样东西。
(2) 举个例子。door handle 是指门把手,通过门把手可以去控制门,但 door handle 并非 door 本身,只是一个中间媒介。又比如 knife handle 是刀柄,通过刀柄可以使用刀。
(3) 广义来说,指针也是某种 handle,可以操作对象。但实际语境中,指针跟句柄是有区别的。
(4) handle?其实就是对象的id而已,不要纠结里面存的什么,靠这个id访问对象而已。
(5) 虽然你握住的只是把手,却能拉动整扇门,而且你根本不用在意那门长什么样子。

例子1

比如定义f(x) = x^2,可以写为 f = @(x)(x.^2) 其中@(x)(x.^2)就是匿名函数,第一个括号里面是自变量,第二个括号里面是表达式,@是函数指针, f=@(x)(x.^2)表示将匿名函数@(x)(x.^2)赋值给f,于是f就表示该函数。 于是f(2) = 2.^2 = 4;f(1:3) = [1:3].^2=[1 4 9]

定义匿名函数时也可以调用别的匿名函数,比如:

  • f1 = @(x,y)(x.^2+y.^2) 定义了函数x^2+y^2
  • f2 = @(t)(f1(t,2)) 定义了函数t^2+4
  • f3 = @(x)(f1(x(1),x(2))) 定义了函数x(1)^2+x(2)^2   (此处有多个形参)

使用匿名函数时一定要注意函数本身的参数形式,如:

  • f1(2,3) 表示2^2+3^2
  • f2(3) = 13 表示3^2+4
  • f3([1,2]) = 5 表示1^2+2^2 说白了就是函数指针

注:
(1) 等效表示: f1 = @(x,y)(x.^2+y.^2) 和f1 = @(x,y)x.^2+y.^2;
(2) 错误表示:如果把f(x) = x^2写成 f=x.^2,或者把f1 = x.^2+y.^2用于表示f(x, y)  =  x^2+y^2。这些都是不行的,因为matlab必须事先定义好x或者y,你才能书写接下来的函数,如果按照句柄的写法,那么我们定义的就是函数,自变量到底怎么取可以在后续决定,这个和函数调用类似。

例子2

(a) 命名函数求积分
function y = cubicPoly(x)  % 创建一个名为 cubicPoly 的函数
y = x.^3 + x.^2 + x + 1;  % 该函数接受一个输入来计算三次多项式
end

(b) 匿名函数求积分
f = @(x) x.^3 + x.^2 + x + 1;  %创建一个匿名函数的句柄 f,该函数对给定的 x 值计算三次多项式
q = integral(f,0,1)   %要求该匿名函数从 0 到 1 的积分,请将其句柄传递给 integral。

例子3

h1 = scatter(t(1:15),k1,'k','filled');
h2 = scatter(t(1:15),k2,'k','filled');
h3 = scatter(t(1:15),k3,'k','filled');
legend([h1 h2],'180 ^oC'' ,'0 ^oC','FontSize',12); % 图例只显示两个

 

 

 

实例

计算1到100加和

答:其中的“fprintf”表示输出(将数据写入文本),%f 、%e、 %g分别表示显示小数形式 、显示科学计数法形式 两者的综合。

%方法一
>> i=1:100;
>> sum(i)

ans =

        5050

% 方法二
sum=0;
for i=1:100
    sum=sum+i;
end
 fprintf('result=%g\n',sum)

%方法三
sum=0;
i=0;
while i<101
    sum=sum+i;
    i=i+1;
end
fprintf('%g',sum)

 

模拟random walk

注意这里调用了前面的随机函数。选取100*100的正方形10000个小方格位置,随机抽取两个点,然后每一秒,该点在x轴方向可以选择-1、0、+1的移动方式,y轴也一样,边界上的点,部分自由度受到限制,所以用if 函数分类。主要分成在四个角、在处四个角之外的四条边、以及其他位置三种大的情况。前面两种大的情况又各自有四种子情况。(注意,这里elseif的用法出现问题,代码错误,下一个问题解决)

walk=[-1,-1;-1,0;-1,1;0,-1;0,0;0,1;1,-1;1,0;1,1];

xm=25;
xma=xm;
ym=75;
yma=ym;
xn=75;
xna=xn;
yn=25;
yna=yn;
step=0;
for pp=1:500
     step=0;
     xm=xma;
ym=yma;
     xn=xna;
yn=yna;
while 1
   
%%
if xm==1&&ym==1;   
    m=ran([1,5,2,4]);   % call random number function
%    xm=xm.*walk(m,1);ym=ym.*walk(m,2);
else if   xm==0&&ym==0; 
    m=ran([5,6,8,9]);
   
else if xm==0&&ym==1;
     m= ran([5,7,4,8]);
    
else if xm==1&&ym==0;     
     m= ran([5,3,2,6]);
    
elseif xm==1;
     m= ran([4,5,6,7,8,9]);
elseif xm==100;
   
     m=ran([1,2,3,4,5,6]);
elseif ym==1;
   
     m=ran([2,3,5,6,8,9]);
elseif ym==100;
   
     m=ran([1,2,4,5,7,8]);
    else
        m=ran([1,2,3,4,5,6,7,8,9]);
    end
    end
    end
end
xm=xm+walk(m,1);ym=ym+walk(m,2);

% xm(step+1)=xm;
%%
if xn==1&&yn==1;   
    m=ran([1,5,2,4]);
%    xm=xm.*walk(m,1);ym=ym.*walk(m,2);
else if   xn==0&&yn==0; 
    m=ran([5,6,8,9]);
   
else if xn==0&&yn==1;
     m= ran([5,7,4,8]);
    
else if xn==1&&yn==0;     
     m= ran([5,3,2,6]);
    
elseif xn==1;
     m= ran([4,5,6,7,8,9]);
elseif xn==100;
   
     m=ran([1,2,3,4,5,6]);
elseif yn==1;
   
     m=ran([2,3,5,6,8,9]);
elseif yn==100;
   
     m=ran([1,2,4,5,7,8]);
    else
        m=ran([1,2,3,4,5,6,7,8,9]);
    end
    end
    end
end
xn=xn+walk(m,1);yn=yn+walk(m,2);
% scatter(xn,yn)

%%
if (xm-xn).^2+(ym-yn).^2==1
   number(pp)=step;
    break
end
step=step+1;
end

% hold on
% scatter(xm,ym)
end
aaaaa=sum(number)./500;

 

利用蒙特卡洛积分求解\( \pi\)

xs=rand(3000,1);
ys=rand(3000,1);
plot(xs,ys,'o');
xlim([0 1]);ylim([0 1])
ang=0:0.01:2*pi;
x=0.5+0.5*cos(ang);
y=0.5+0.5*sin(ang);
hold on
plot(x,y,'r')

in_circle=(xs-0.5).^2+(ys-0.5).^2<0.5^2  %布尔求解,每一个点判断之后,得到1或者0
a=sum(in_circle);
result=a*4/3000;

 

稀疏矩阵(Sparse matrix)

矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。 定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。

matlab是用spy函数描述,非零的位置用点表示,零元素的位置则空白。

B=[1,2,0,0; 3,4,0,0; 0,0,5,6; 0,2,1,2];
spy(B)

上面的nz=9表示的有9个点的元素不为零。
如果在命令窗口输入"spy"那么doge image pops up。

一个圆内随机取点

采用如下极坐标的方法得到圆,但是不同的rou上点分布的概率是不一样的,因为面积是一个平方关系。下图画的圆中,中心的随机点密度大,外围的随机点密度小

rou=60*rand(1,2000);
th=2*pi*rand(1,2000);
x=rou.*cos(th);
y=rou.*sin(th);
scatter(x,y,'r')

加入开方函数即可解决

rou=60*sqrt(rand(1,2000));  %sqrt对随机取的半径值开方
th=2*pi*rand(1,2000);

x=rou.*cos(th);
y=rou.*sin(th);
scatter(x,y,'r')

 

画动态图像

(1)图像固定(所有数据已经全部生成),变化坐标轴的范围(主要是横坐标范围随着时间的增长而变化)。

%%
%先画好,然后更改坐标系
%在命令行中 使用 Ctrl+C 结束
t=0:0.1:100*pi;
m=sin(t);
plot(t,m);
x=-2*pi;
axis([x,x+4*pi,-2,2]);
grid on
while 1
    if x>max(t)    % 如果坐标轴横轴的起始点大于函数图像的最大横坐标值,就停止循环 
        break;
    end
    x=x+0.1;
    axis([x,x+4*pi,-2,2]); %移动坐标系
    pause(0.1);   % 暂停0.1 秒
end

 

(2)使用hold on 模式,新的一帧的画面和前一帧的画面重叠在一张图上。

%%
% Hold On 法
% 此种方法只能点,或者分段划线
hold off
t=0;
m=0;
t1=[0 0.1]; %要构成序列
m1=[sin(t1);cos(t1)];
p = plot(t,m,'*',t1,m1(1,:),'-r',t1,m1(2,:),'-b','MarkerSize',5);  
x=-1.5*pi;
axis([x x+2*pi -1.5 1.5]);
grid on;1

for i=1:100
    hold on
    t=0.1*i;  %下一个点
    m=t-floor(t); % 按照0.1,0.2......0.8,0.9,0 十个数据循环10次
    t1=t1+0.1; %下一段线(组)
    m1=[sin(t1);cos(t1)];
    p = plot(t,m,'*',t1,m1(1,:),'-r',t1,m1(2,:),'-b','MarkerSize',5);  
    x=x+0.1;
    axis([x x+2*pi -1.5 1.5]);
    pause(0.1);
end

 

(3) Matlab如何制作和保存gif动图
MATLAB:动图画法

成绩等级分类(if/elseif/else)

注意elseif和if是平行的,而else if是嵌套的。elseif 要比if的嵌套程序语言上更简洁,更不容易出错。对比例子如下:
elseif的使用

% 目标:
% 判定成绩等级
%定义变量
% 输入:分数grade
%清除变量或指令
clc;
% 允许用户输入参数
disp ('该功能练习if语句');
disp ('输入你的成绩,系统将判定等级. ');
grade = input ('输入分数: ');

%根据分数情况讨论
if grade > 95.0  %等级A
     disp('你的成绩是A等! ');
elseif  grade > 86.0    %等级B
     disp('你的成绩是B等! ');
elseif  grade > 76.0   %等级C
     disp('你的成绩是C等! ');
elseif  grade > 66.0   %等级D
     disp('你的成绩是D等! ');
else  %等级E
   disp('你的成绩是E等! ');  
end

 

if的嵌套

% 判定成绩等级
%定义变量
% 输入:分数grade
%清除变量或指令
clc;
% 允许用户输入参数
disp ('该功能练习if语句');
disp ('输入你的成绩,系统将判定等级. ');
grade = input ('输入分数: ');

%根据分数情况讨论
if grade > 95.0  %等级A
     disp('你的成绩是A等! ');
else
    if  grade > 86.0    %等级B
     disp('你的成绩是B等! ');
    else
        if  grade > 76.0   %等级C
            disp('你的成绩是C等! ');
        else
            if  grade > 66.0   %等级D
            disp('你的成绩是D等! ');
            else  %等级E
            disp('你的成绩是E等! '); 
            end pr
        end
    end
end

 

积分的处理

trapz函数(Trapezoidal numerical integration,梯形积分)
(1) 如果给出的x值是均匀的间隔为1,那么可以直接用trapz(y),比如我们要计算y = x^2在[1,5]的积分面积,我们可以设定x = 1:1:5,然后y = x.8x,最后trapz(y)即可。由于y = x^2 is concave up (向上凹的),所以这里的计算结果比真实值大。
(2) 如果给出了x的具体间隔,那么直接用trapz(x,y)即可。

二维云图

load String.mat
imagesc(String)
colorbar

其中String是矩阵像素点

 

Leave a Reply