本人萌新一枚,花了一段时间终于看懂了这些代码。
function threenplus1R(n)
%"Three n plus 1".
% Study the 3n+1 sequence.
% threenplus1(n) plots the sequence starting with n.
% threenplus1 with no arguments starts with n = 1.
% uicontrols decrement or increment the starting n.
% Is it possible for this to run forever?
% Copyright 2014 Cleve Moler
% Copyright 2014 The MathWorks, Inc.
if ~isequal(get(gcf,'tag'),'3n+1')
shg
clf reset
set(gcf,'menu','none','numbertitle','off','name','3n+1')
uicontrol( ...
'units','normalized',...
'position',[0.455, 0.01, 0.044, 0.054], ...
'string','<','fontunits','normalized','fontsize',0.6,...
'callback','threenplus1(''<'')');
uicontrol( ...
'units','normalized',...
'position',[0.525, 0.01, 0.044, 0.054],...
'string','>','fontunits','normalized','fontsize',0.6, ...
'callback','threenplus1(''>'')');
uicontrol( ...
'units','normalized',...
'position',[0.842, 0.01, 0.07, 0.054], ...
'string','close','fontunits','normalized','fontsize',0.6, ...
'callback','close(gcf)')
set(gcf,'tag','3n+1');
end
if nargin == 0
n = 2;
elseif isequal(n,'<')
n = get(gcf,'userdata') - 1;
elseif isequal(n,'>')
n = get(gcf,'userdata') + 1;
end
if n < 1, n = 1; end
set(gcf,'userdata',n)
y = n;
while n > 1
if rem(n,2)==0
n = n/2;
else
n = 3*n+1;
end
y = [y n];
end
semilogy(y,'.-')
axis tight
ymax = max(y);
ytick = [2.^(0:ceil(log2(ymax))-1) ymax];
if length(ytick) > 8, ytick(end-1) = []; end
set(gca,'ytick',ytick)
Htitle=title(['n = ' num2str(y(1))]);
set(Htitle,'fontunits','normalized','fontsize',0.04)
问题不重述了,应该都是从书本过来的。
if ~isequal(get(gcf,'tag'),'3n+1')
shg
clf reset
set(gcf,'menu','none','numbertitle','off','name','3n+1')
uicontrol( ...
'units','normalized',...
'position',[0.455, 0.01, 0.044, 0.054], ...
'string','<','fontunits','normalized','fontsize',0.6,...
'callback','threenplus1(''<'')');
uicontrol( ...
'units','normalized',...
'position',[0.525, 0.01, 0.044, 0.054],...
'string','>','fontunits','normalized','fontsize',0.6, ...
'callback','threenplus1(''>'')');
uicontrol( ...
'units','normalized',...
'position',[0.842, 0.01, 0.07, 0.054], ...
'string','close','fontunits','normalized','fontsize',0.6, ...
'callback','close(gcf)')
set(gcf,'tag','3n+1');
end
从上到下讲解
if ~isequal(get(gcf,'tag'),'3n+1')
isequal(a1,a2,···,an)是一个确定数组完全相等的函数,比较的这几个数组一模一样的时候,输出1,否则0。在这里就是说gcf的tag叫做‘3n+1’的时候,这一大串操作都不用做了,也就是说,从程序开始到结束,只在开始的时候运行了一次。就是初始化这些按钮,做一次就行。不一定得叫’3n+1’,只是寓意数论3n+1,起别的名字一样。我一开始还以为有玄妙。
shg
clf reset
shg是创建一个图形窗口,类似于摆了一个画板
clf是清除图像窗口当前图像,类似于把画板擦干净
reset是重置所有对象设置,返回默认状态,这两行代码类似于命令行窗口的命令clear all,保证现在的画板不会沾以前的东西
set(gcf,'menu','none','numbertitle','off','name','3n+1')
menu就是菜单栏,设置成none,就是隐藏了菜单栏
numbertitle就是标题号码,比如Figure 1,设置成off就是隐藏了标题号码
name就是窗口的名称,你该叫做3n+1,寓意就是数论3n+1
uicontrol( ...
'units','normalized',...
'position',[0.455, 0.01, 0.044, 0.054], ...
'string','<','fontunits','normalized','fontsize',0.6,...
'callback','threenplus1(''<'')');
uicontrol是设置一个按钮,下面都是这个按钮的一些参数
units是测量单位,设置成normalized就是把窗口坐标归一化,左下角叫做坐标(0,0),右上角叫做(1,1),中间坐标自然不会超过1了。
position是坐标,看你把按钮放在哪个位置,只要坐标符合要求,不大于1就行,四个坐标分别是,距离左边的长度,距离下边的长度,按钮的宽,按钮的高。
string是要显示的文本,你要按钮显示啥就写啥,这里是小于号,按钮就写着小于号
callback是主回调函数,当你按了一次小于号,类似于翻页,就会要重新画图啥的,这个时候就会重新调用函数,重新画个图嘛
set(gcf,'tag','3n+1');
end
最后起名字3n+1,首尾呼应,结束判断语句。
画图部分到此结束。
我要确定n值了,因为我可以输入n值,也可以不输入,所以得判断一下。
if nargin == 0
n = 2;
elseif isequal(n,'<')
n = get(gcf,'userdata') - 1;
elseif isequal(n,'>')
n = get(gcf,'userdata') + 1;
end
if n < 1, n = 1; end
set(gcf,'userdata',n)
nargin是看你输了几个值,没输就是0,输了一个就是1,输了两个就是2。
要注意的是,你按按钮,也算输入,不过输入的是按钮名字对应的值。
如果你是在按按钮,我就判断你是要往左翻页还是往右翻页,左的话,n就要减一,右的话,n就要加一。
如果你是输入了值,那就把值赋给userdata,这样画图的就知道你要画n等于几的图了。比如说你输入threenplus1R(3),那我就知道你要我画n=3的图。
如果你输入threenplus1R(),这时nargin=0,我就自己画n=2的了。
y = n;
while n > 1
if rem(n,2)==0
n = n/2;
else
n = 3*n+1;
end
y = [y n];
end
这部分就是数论要求,不需要讲解。
rem是模运算函数,别的不说了。
semilogy(y,'.-')
axis tight
ymax = max(y);
ytick = [2.^(0:ceil(log2(ymax))-1) ymax];
if length(ytick) > 8, ytick(end-1) = []; end
set(gca,'ytick',ytick)
Htitle=title(['n = ' num2str(y(1))]);
set(Htitle,'fontunits','normalized','fontsize',0.04)
这就是给图画坐标轴,起名字,不多说了。
希望我说的能让你明白,一起加油吧