【问题标题】:Math equation to find number of iterations in asymptotic loop?在渐近循环中找到迭代次数的数学方程?
【发布时间】:2020-09-21 22:25:03
【问题描述】:

我有一个循环随着迭代次数的增加而减少。我需要计算它将经历的迭代次数(我在这个问题的底部解释了为什么我需要这个)。前6步是

0.50, 1.50, 1.83, 2.11, 2.34, 2.55, ...

X 轴:迭代次数,Y 轴:计数

计数从 0.5 开始并以递减的速度增长,直到达到 20。循环归结为:

var SCALE = 0.5; // Starting value, also affects increment
var MAX = 20;    // Maximum value
var i = 0;       // Just for counting

for (var count = SCALE; count < MAX; count += SCALE / count) {
    console.log(count, i);
    i++;
}

您可以看到,由于count += SCALE / count,图表的增长速度越来越慢,因此随着计数的增加,分母也会增加。

我认为它遵循指数 pow(MAX, 1 / SCALE) 线,但不完全是:

MAX = 5 :  23 iterations      Math.pow(5, 2) = 25
MAX = 10 : 97 iterations      Math.pow(10, 2) = 100
MAX = 15 : 222 iterations     Math.pow(15, 2) = 225
MAX = 20 : 397 iterations     Math.pow(20, 2) = 400

另外,当SCALE 不是 0.5 时,这种方法就会失效。

问题

我可以使用什么公式同时考虑 SCALE 和 MAX 来获得迭代次数?

我为什么需要这个?

我正在尝试将示例代码at the bottom of this article 转换为 GLSL 着色器代码。问题是显卡只能执行整数计数到一个常数的for循环,所以我需要知道在开始循环之前循环将进行多少次迭代。

我需要这样的东西:for(int i = 0; i &lt; MAX_COUNT; i++),但首先我需要知道MAX_COUNT 会是什么。

【问题讨论】:

  • 看起来是log plot 不是吗?
  • @RahulDwivedi 我对此表示怀疑...记录图are negative in the [0, 1) range。它看起来更像square root graph,但我无法破解它。
  • @trincot 哦,该图看起来更像我得到的结果。我想你是对的,看了这篇文章,感觉如果我先做一个测试循环,计算i会更容易,并将迭代次数保存在一个常量中,以便在我的实际代码中使用。跨度>
  • @trincot 如果我错了,请纠正我,但我不认为这是一个谐波级数,因为除数是count 的值而不是当前的迭代次数(即count += SCALE / i )。
  • 你说得对,@meowgoesthedog,这不是谐波系列。

标签: javascript math glsl logarithm asymptote


【解决方案1】:

所以我有两个解决方案,首先是数学:

正如 cmets 中提到的,您所拥有的是调和级数,它没有简单的封闭形式。因此,通过分析获得循环的上限将是一个挑战。

但这并不意味着您无法解决问题。

解决方案:

选项一是,如 cmets 中建议的那样,在 CPU 上运行您的代码,直到您找到最大迭代次数,然后将该数字作为循环的上限(例如作为制服)发送。

另一个可能更好的解决方案是将最大迭代次数设置为一个巨大的数字,然后在循环体内,break 如果你已经超过了你的阈值(这在现代是可能的。即 4+ GLSL 版本)。

【讨论】:

  • 第二种解决方案听起来很有趣。我正在使用基于 OpenGL ES2.0 的 WebGL1。 WebGL1 使用哪个版本的 GLSL?
  • iirc 3+ 但我认为您仍然可以跳出循环。第二种解决方案的好处是,它需要 5 分钟来测试并查看它是否有效。但我认为你可以打破 glsl 3+ 中的循环
【解决方案2】:

正如 cmets 中的几个人所建议的,这种模式不遵循对数图、谐波图或任何可识别的模式。为了解决这个问题,我不得不采用一种“蛮力”方法,即只运行一次循环,然后使用迭代计数作为结果。没有优雅的数学方程式。

function calculateSampleCount() {
    const SCALE = 0.5; // Starting value, also affects increment
    const MAX = 20;    // Maximum value
    let i = 0;
    for (let r = SCALE; r < MAX; r += SCALE / r) {
        i++;
    }
    return i;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 2012-10-27
    相关资源
    最近更新 更多