简单系列的奇怪和意外结果

时间:2015-07-24 15:47:07

标签: javascript math series

使用简单的JS代码,我计算以下系列的总和:

Series

b是常量,可以是任何值。 JS代码试图找到哪个最小r(在此示例中 1000次尝试),这个不等式是有效的:

Series 2

如果r低于1.50000,结果就会变得愚蠢。

var pre = 0.0;
var r = 1.50010;
var b = 0.01;

for (var p = 0; p < 1000; p++) {
   var sum = 0;
   for (var i = 0; i <= 33; i++) {
      sum += Math.pow(r, i);
   }

   sum *= b;

   if ((2 * b * Math.pow(r, 34)) > sum) {
      pre = r;
      r -= 0.00001;
      r = parseFloat(r.toFixed(5));
   } else {
      console.log(pre);
      console.log(((2 * b * Math.pow(r + 0.00001, 34)) - sum).toFixed(8));
      break;
   }
}

代码在pre == 1.5处中断,如果我强制r = 1.49999console.log(pre)会返回0。为什么呢?

2 个答案:

答案 0 :(得分:1)

当r = 1.5时代码停止,因为这是你的不等式有效的最小值(无论如何你在使用的准确度内)。如果你以小于那个开始关闭,它将在第一次循环中断,因为if语句永远不会为真,所以你永远不会将pre设置为r。

这是一个图表,显示r = 1.5附近不平等的两边会发生什么:Plot of 2 * r^34 and sum of r^i from i = 0 to 33

上图的代码:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1.4, 1.6, 100)
plt.plot(x , 2 * x ** 34, label = '$2r^{34}$')
plt.plot(x , sum([x ** i for i in xrange(34)]), label = '$\sum_{i = 0}^{33}\/ r^i$')
plt.yscale('log')
plt.legend()
plt.show()

另外,如果b是正数,则不需要在代码中对b进行任何操作,因为你将不等式的两边都乘以b。如果b为负数,那么你需要逆转不等式。

哦,还有另一件事:对于这种类型的算法,您可能需要考虑更像bisection method的东西,它会在每次迭代时将搜索空间减半。您可以使用1和2作为端点,因为1绝对太低而2绝对太高。当不平等的两边之间的差异低于某个阈值时,你就会停止。

答案 1 :(得分:1)

我假设当循环中断时,你想要显示不等式左右之间的差异。问题是因为&#34;总和&#34;是一个来自前一个循环的运行总和,计算不正确。

现在当你强制r = 1.49999时,if子句永远不会被执行,所以&#34; pre&#34;在第一行开始时保持为零。

您的完整解决方案应该是这样的:

var pre = 0.0;
var r = 1.50010;
var b = 0.01;

for (var p = 0; p < 1000; p++) {
   var sum = 0;
   for (var i = 0; i <= 33; i++) {
      sum += Math.pow(r, i);
   }

   sum *= b;

   var diff = (2 * b * Math.pow(r, 34) - sum).toFixed(8);
   console.log('diff: ' + diff);
   if ((2 * b * Math.pow(r, 34)) > sum) {
      pre = r;
      r -= 0.00001;
      r = parseFloat(r.toFixed(5));
   } else {
      console.log('--breaking--');
      console.log(pre);
      //console.log(((2 * b * Math.pow(r + 0.00001, 34)) - sum).toFixed(8));
      break;
   }
}

,输出为:

diff: 3.91098781
diff: 3.52116542
diff: 3.13150396
diff: 2.74200338
diff: 2.35266364
diff: 1.96348468
diff: 1.57446646
diff: 1.18560893
diff: 0.79691205
diff: 0.40837575
diff: 0.02000000
diff: -0.36821526
--breaking--
1.5