如何在 mathemathica 中定义一个使用复杂递推关系的函数?
How do I define a function in mathemathica that uses a complicated recurrence relation?
我正在尝试编写一个小脚本来计算整数序列。我试图用代码编写的函数是黑板上的函数 a(n)。问题是我期待我在脚本中定义的函数 h(n) 作为结果给出一个数字,但它给出了其他东西:对于 h(2) 它给出了 ArgMax[{p, HarmonicNumber[p] <= 1}, p, Integers]
我该如何更正? (你必须明白,我绝不是一个程序员,也不了解 mathematica。谢谢你的 advnace。
我写的脚本是这个:
h[n_] := (ArgMax[{p,
Sum[1/s, {s, 1 + Sum[h[k], {k, 1, (n - 1)}], p}] <= 1}, p,
Integers]) - Sum[h[k], {k, 1, (n - 1)}]; h[1] = 1;
a(n)=(maximum p such that the sum from s equals r to p is less or equal than one)-r+1, where r=1+the sum from k=1 to (n-1) of a(k), and a(1)=1
PD:那些看起来像 v 的字母是 r。对不起。
您收到此答案的主要原因是 Mathematica 中的 Sum 命令进行了复杂的符号计算,将术语和表达式重写为经典数学函数,试图对所有事情做出尽可能少的假设。
当然,如果您对整数的倒数求和,它会尝试返回调和数。
它通常很有用,但可能有交叉用途。
为避免这种情况,只需替换
Sum[ , {var, start, end}]
来自
Total[Table[ , {var, start, end}]]
它应该给你你想要的,而不需要额外的时间来对被加数进行符号解释。
总之,你的代码有大毛病。
你应该为 h 使用 memoization
您想要找到最大 p,使得从 r 开始的逆元之和小于或等于 1。您的代码不会这样做。您不能简单地将不等式放入范围参数中。您必须使用控件循环求和或使用反函数。
a[1] = 1;
a[n_] := Module[{sum = 0},
r = 1 + Sum[a[k], {k, n - 1}];
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1]
Table[a[n], {n, 6}]
{1, 2, 6, 16, 43, 117}
a[4]
的结果是 16 而不是 14。
为了说明,当n = 4
r = 1 + Sum[a[k], {k, 4 - 1}]
= 1 + a[1] + a[2] + a[3] (* refer to established results for a[n] *)
= 1 + 1 + 2 + 6 = 10
sum = 0;
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1
16
或者换一种形式
Total[Table[1/s, {s, 10, 25}]] <= 1 (* True *)
p - r + 1 = 25 - 10 + 1 = 16
使用 memoisation,正如奥杰拉德所提到的
Clear[a]
a[1] = 1;
a[n_] := a[n] = Module[{sum = 0},
r = 1 + Sum[a[k], {k, n - 1}];
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1]
只减少后面的运行时间9秒
Timing[Table[a[n], {n, 14}]]
{40.8906, {1, 2, 6, 16, 43, 117, 318, 865, 2351, 6391, 17372, 47222,
128363, 348927}}
我正在尝试编写一个小脚本来计算整数序列。我试图用代码编写的函数是黑板上的函数 a(n)。问题是我期待我在脚本中定义的函数 h(n) 作为结果给出一个数字,但它给出了其他东西:对于 h(2) 它给出了 ArgMax[{p, HarmonicNumber[p] <= 1}, p, Integers]
我该如何更正? (你必须明白,我绝不是一个程序员,也不了解 mathematica。谢谢你的 advnace。
我写的脚本是这个:
h[n_] := (ArgMax[{p,
Sum[1/s, {s, 1 + Sum[h[k], {k, 1, (n - 1)}], p}] <= 1}, p,
Integers]) - Sum[h[k], {k, 1, (n - 1)}]; h[1] = 1;
PD:那些看起来像 v 的字母是 r。对不起。
您收到此答案的主要原因是 Mathematica 中的 Sum 命令进行了复杂的符号计算,将术语和表达式重写为经典数学函数,试图对所有事情做出尽可能少的假设。
当然,如果您对整数的倒数求和,它会尝试返回调和数。
它通常很有用,但可能有交叉用途。
为避免这种情况,只需替换
Sum[ , {var, start, end}]
来自
Total[Table[ , {var, start, end}]]
它应该给你你想要的,而不需要额外的时间来对被加数进行符号解释。
总之,你的代码有大毛病。
你应该为 h 使用 memoization
您想要找到最大 p,使得从 r 开始的逆元之和小于或等于 1。您的代码不会这样做。您不能简单地将不等式放入范围参数中。您必须使用控件循环求和或使用反函数。
a[1] = 1;
a[n_] := Module[{sum = 0},
r = 1 + Sum[a[k], {k, n - 1}];
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1]
Table[a[n], {n, 6}]
{1, 2, 6, 16, 43, 117}
a[4]
的结果是 16 而不是 14。
为了说明,当n = 4
r = 1 + Sum[a[k], {k, 4 - 1}]
= 1 + a[1] + a[2] + a[3] (* refer to established results for a[n] *)
= 1 + 1 + 2 + 6 = 10
sum = 0;
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1
16
或者换一种形式
Total[Table[1/s, {s, 10, 25}]] <= 1 (* True *)
p - r + 1 = 25 - 10 + 1 = 16
使用 memoisation,正如奥杰拉德所提到的
Clear[a]
a[1] = 1;
a[n_] := a[n] = Module[{sum = 0},
r = 1 + Sum[a[k], {k, n - 1}];
x = r;
While[sum <= 1, sum += 1/x++];
p = x - 2;
p - r + 1]
只减少后面的运行时间9秒
Timing[Table[a[n], {n, 14}]]
{40.8906, {1, 2, 6, 16, 43, 117, 318, 865, 2351, 6391, 17372, 47222, 128363, 348927}}