matlab pi的连续分数逼近

a5g8bdjr  于 2023-01-09  发布在  Matlab
关注(0)|答案(1)|浏览(155)

在学习Matlab时,我遇到了这个问题:给定一个整数1<d<15,找出最小的p,q(正整数),使得abs(p/q-pi)<=10^-d
我的尝试是这样的:我首先想到我需要绑定p,q来创建循环,所以我分别输入p,qM,N上界作为输入数据,下面是我的算法:

M=input('Give an upper bound for p:')
       N=input('Give an upper bound for q:')
       d=input('Give a positive integer between 1 and 15:')

       for q=1:N
       for p=1:M
       if abs(pi-p/q)<=10^(-d)
       break
       end
       end
       end

有什么问题吗?先谢谢你。

jrcvhitl

jrcvhitl1#

问题在于您选择终止for循环的方式:break仅停止内部循环。请尝试以下代码,并检查pq的值,执行将在该值处停止:

M=input('Give an upper bound for p:')
 N=input('Give an upper bound for q:')
 d=input('Give a positive integer between 1 and 15:')

 for q=1:N
 for p=1:M
   if abs(pi-p/q)<=10^(-d)
     [p,q]
     error('Found!') % Arrest the program when condition is met
 end
 end
 end

其给出以下输出:

当然,有更好的方法来捕获所有满足条件的整数对(例如,使用disp代替error),这超出了本答案的范围,但我将在这里提供几个例子:

clear; clc;

M=input('Give an upper bound for p:')
N=input('Give an upper bound for q:')
d=input('Give a positive integer between 1 and 15:')

pairs = []; % p,q pairs are stored here
k = 1; % counter

for q=1:N
    for p=1:M
        if abs(pi-p/q)<=10^(-d)
            pairs(k,1) = p; 
            pairs(k,2) = q;
            k = k + 1; % increment the counter
        end
    end
end

上面的脚本将安静地结束:(p,q)对将被存储在pair矩阵中。
下面的代码将直接打印这些对:

clear; clc;

M=input('Give an upper bound for p:')
N=input('Give an upper bound for q:')
d=input('Give a positive integer between 1 and 15:')

for q=1:N
    for p=1:M
        if abs(pi-p/q)<=10^(-d)
            out = sprintf("(%d, %d)", p,q);
            disp(out);
        end
    end
end

为了实验的需要,并根据@Cris Luengo的评论,这里有一个稍微更详细的脚本版本:x1M7 N1 x循环被封装在专用函数中,并且x1M8 N1 x循环很好地跟踪进程,并且用x1M10 N1 x对填充x1M9 N1 x矩阵:

clear; clc;

M=input('Give an upper bound for p:');
N=input('Give an upper bound for q:');
d=input('Give a positive integer between 1 and 15:');

close_to_pi = @(px,qx) abs(pi-px/qx)<=10^(-d); % returns true/false

p = 1; q = 1;
count = 0;

res = nan(N*M,2) ; % (p,q) pairs are stored here; preallocate for speed!

tic % starts the timer
while (q <= N)
    [p,q, found] = approx_pi(p, q, N, M, close_to_pi);
    
    if found
        count = count + 1;
        res(count,:) = [p,q]; % populates output var

    end
    
    if p<M % we aren't done with p
        p = p + 1;
    else % reset p and increment q
        p = 1;
        q = q + 1;
    end

    
end
res(isnan(res(:,1)),:) = []; % gets rid of the empty elements
disp(count)
toc % stops the timer and prints elapsed time

function [p, q, found] = approx_pi(p0, q0, N, M, fun)

for q=q0:N
    for p=p0:M
        if fun(p,q)
            found = 1;
            return
        end % if
    end % for p
    p0 = 1;
end % for q

found = 0;

end % approx_pi

如果您对pi的连续分数近似值感兴趣,请尝试rat(pi, Tol),其中Tol是公差。

相关问题