level 6
d = 4993; pell = 65; P[0] = 1; Q[0] = 2;
x[0] = (P[0] + Sqrt[d])/Q[0];
a[0] = IntegerPart[x[0]];
i = 0;
While[(x[i] != 1/(x[0] - a[0]) && P[i] != pell) || i == 1,
P[i + 1] = Q[i] a[i] - P[i];
Q[i + 1] = (d - P[i + 1]^2)/Q[i];
x[i + 1] = (P[i + 1] + Sqrt[d])/Q[i + 1];
a[i + 1] = IntegerPart[x[i + 1]];
Print[{i, Q[i], P[i], a[i]}]; i++];
运行结果:
{0,2,1,35}
{1,116,69,1}
{2,24,47,4}
{3,108,49,1}
{4,14,59,9}
{5,36,67,3}
{6,92,41,1}
{7,26,51,4}
{8,84,53,1}
{9,48,31,2}
现在我如果只求最终的结果,而不求其中计算的过程,即不保存数组Q[i],P[i],a[i]的中间值,该怎样修改代码。。。
2013年11月10日 06点11分
1
level 6
有不同意见的么,好像有个动态利用的函数,是dynamic吧,能用上吗?
2013年11月10日 09点11分
3
level 6
以上程序就是迭代展开(P+Sqrt[d])/Q 的连分式 ,求怎样修改代码,只输出最后一行的值。中间的运算结果都不要,因为如果是200到300之间的大数,程序保存并输出所有的结果内存是吃不消的,其实也没有必要保存中间的运算结果,只需求出最后的程序迭代值,帮帮忙啊。。。
2013年11月10日 10点11分
5
你应该解释一下什么是连分式。
2013年11月11日 05点11分
回复 xzcyr:我没给你说清楚如果 d 是200到300位之间的大数 :
2013年11月11日 07点11分
这个其实无所谓,只是参数的具体数值的话并不影响这段代码的优化思路。只是要节约内存的话7楼的代码应该足够了。
2013年11月11日 07点11分
吧务
level 15
由于你没有解释什么是连分式,也没有解释你的代码依据的是什么算法(我想对于这些问题,已经有不止一人在不止一个你的帖子里面提过,你为什么就不能听听我们的意见呢?),所以这里只能根据你的代码做出很有限的修改:
Clear[test, x, a, f, t]
d = 4993; pell = 65; p = 100; q = 200;
x[p_, q_] := (p + Sqrt[d])/q;
a[p_, q_] := IntegerPart[x[p, q]];
t = 1/(x[p, q] - a[p, q]);
f[{_, {i_, p_, q_}}] := {{i, p, q}, {i + 1,
q a[p, q] - p, (d - (q a[p, q] - p)^2)/q}}
test[{_, {i_, p_, q_}}] := (x[p, q] != t && p != pell) || i == 1
First@NestWhile[f, {Null, {0, p, q}}, test] // AbsoluteTiming
2013年11月11日 06点11分
7
回复 wsc8100 :你的P[0]和Q[0]啊——因为你之前只说“如果是200到300之间的大数”所以我就以为你是要改大这两个的数值——于是,我又要啰里巴嗦得再说一次了:为什么你不能问得更清楚一些呢?你的提问方法是有问题的,对此应该有不止一人在不止一个你的帖子里面提过,你为什么就不能听听我们的意见呢?
2013年11月11日 07点11分
麻烦你多费心修改,但是我看你修改的时候,把X,a的值看做P,Q的函数
2013年11月11日 07点11分
回复 wsc8100 :是啊,因为本质上就是如此。
2013年11月11日 07点11分
level 6
程序有bug,
d = 4181; pell = 65; P[0] = 1; Q[0] = 2;
{0,2,1,32}
{1,106,63,1}
{2,22,43,4}
{3,98,45,1}
{4,14,53,8}
{5,50,59,2}
{6,50,41,2}
{7,14,59,8}
{8,98,53,1}
{9,22,45,4}
{10,106,43,1}
{11,2,63,63}
这是最后正确迭代后的结果(其实是最后一行),而你的程序会出现死循环。
2013年11月11日 07点11分
10
level 6
说明一下,以上程序的迭代本质上是一个非线性的混沌序列。(Q,2P,Q')就是满足
d=P^2 + Q*Q'的二元二次型F(x,y)=Qx^2 + 2Pxy + Q'y^2 的系数。
2013年11月11日 08点11分
13
level 5
简单的因子分解程序
基于二次不尽根的连分式展开
Clear[t, a]; d = 997331; pell = -1; P[0] = 4; Q[0] = 11;
t[0] = (P[0] + Sqrt[d])/Q[0]
a[0] = IntegerPart[t[0]];
i = 0; While[(t[i] != 1/(t[0] - a[0]) && P[i] != pell) || i == 1,
P[i + 1] = Q[i] a[i] - P[i];
Q[i + 1] = (d - P[i + 1]^2)/Q[i];
t[i + 1] = (P[i + 1] + Sqrt[d])/Q[i + 1];
a[i + 1] = IntegerPart[t[i + 1]];
If[Q[i + 1] == Q[i] || P[i + 1] == P[i], Break[]];
Print[{i, Q[i], P[i], a[i]}]; i++]; {i, Q[i], P[i], a[i]}
这个程序怎么修改,要求只得到最后结果
{30, 127, 889, 14}
其中127是997331的素因子
2017年05月21日 09点05分
14
level 5
d = 1241445
15376516209
037603246
15647307570
85
13733445081
7128010073;
pell = -1; P[0] = 0; Q[0] = 1;
t[0] = (P[0] + Sqrt[d])/Q[0]
a[0] = IntegerPart[t[0]];
i = 0; While[
i <= 100 && (t[i] != 1/(t[0] - a[0]) && P[i] != pell) || i == 1,
P[i + 1] = Q[i] a[i] - P[i];
Q[i + 1] = (d - P[i + 1]^2)/Q[i];
t[i + 1] = (P[i + 1] + Sqrt[d])/Q[i + 1];
a[i + 1] = Floor[t[i + 1]];
p[-1] = 0; p[0] = 1; p[i + 1] = a[i] p[i] + p[i - 1];
q[-1] = 1; q[0] = 0; q[i + 1] = a[i] q[i] + q[i - 1];
If[Q[i + 1] == Q[i] || P[i + 1] == P[i] ||
FractionalPart[Sqrt[Q[i + 1]]] == 0, Break[]];
Print[{i, Q[i], P[i], a[i]}] i++];
{i, Q[i], P[i], a[i]}
{i + 1, Q[i + 1], P[i + 1], a[i + 1]}
GCD[Q[0] p[i + 1] - P[0] q[i + 1] + Sqrt[Q[i + 1] Q[0]], d]
怎样将以上代码修改为动态计算,即不保存中间的运算过程,直接输出最后计算结果
2021年07月11日 07点07分
15
小吧主帮帮忙
2021年07月12日 22点07分
level 7
把print那句删掉,最后加句if:当循环结束时输出一个结果。。这种问题已经和mma无关了。
2021年07月18日 13点07分
19
改成动态计算的目的是为了提高运算效率,当d是60位的整数时,迭代非常费时了,保留中间数组的运算值,计算机内存也吃不消
2021年07月18日 13点07分
@codrw 没仔细看你的代码,以为你这是要只输出最后结果。要写出迭代的代码可以参考下nest和nestwhile这两个函数。如果我没理解错你的意思的话。
2021年07月18日 13点07分
@三炮快跑☞ 这两个函数都是那上一次运算的结果做迭代,应该不会保存之前的结果,故而比while快一点吧,应该。
2021年07月18日 13点07分