Matlab数值积分之数论问题3n+1序列

本人萌新一枚,花了一段时间终于看懂了这些代码。

原代码照搬:

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)

这就是给图画坐标轴,起名字,不多说了。

希望我说的能让你明白,一起加油吧

你可能感兴趣的:(数值分析,matlab,数论)