简体   繁体   English

在渐近循环中找到迭代次数的数学方程?

[英]Math equation to find number of iterations in asymptotic loop?

I have a loop that decreases in growth as the iterations go up.我有一个循环随着迭代 go 的增加而减少。 I need to calculate the number of iterations it'll go through (I explain why I need this at the bottom of this question).我需要计算通过 go 的迭代次数(我在这个问题的底部解释了为什么我需要这个)。 The first 6 steps are前6步是

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

X 轴:迭代次数,Y 轴:计数 X-axis: iterations, Y-axis: count X 轴:迭代次数,Y 轴:计数

The count starts at 0.5 and grows at a decreasing rate until it reaches 20. The loop boils down to this:计数从 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++;
}

You can see the graph grows more slowly as it progresses because of count += SCALE / count , so as count increases, the denominator increases too.您可以看到,由于count += SCALE / count ,图表的增长速度越来越慢,因此随着 count 的增加,分母也会增加。

I thought it followed an exponential pow(MAX, 1 / SCALE) line, but not quite:我认为它遵循指数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

Plus this approach falls apart when SCALE isn't 0.5.此外,当SCALE不是 0.5 时,这种方法就会崩溃。

Question问题

What equation can I use that takes both SCALE and MAX into account to get the iteration count?我可以使用什么方程式同时考虑SCALEMAX来获得迭代计数?

Why do I need this?为什么我需要这个?

I'm trying to convert the sample code at the bottom of this article into GLSL shader code.我正在尝试将本文底部的示例代码转换为 GLSL 着色器代码。 The problem is that graphics cards can only perform for-loops with integers counting up to a constant, so I need to know how many iterations the loop will take before starting the loop.问题是显卡只能执行整数计数到一个常数的for循环,所以我需要知道在开始循环之前循环将进行多少次迭代。

I need something like this: for(int i = 0; i < MAX_COUNT; i++) but first I need to know what MAX_COUNT will be.我需要这样的东西: for(int i = 0; i < MAX_COUNT; i++)但首先我需要知道MAX_COUNT是什么。

So I have 2 solutions, first the math:所以我有两个解决方案,首先是数学:

As mentioned in the comments what you have is the harmonic series, which does not have a simple closed form.正如评论中提到的,你所拥有的是谐波级数,它没有简单的封闭形式。 So getting the upper bound of the loop analytically will be a challenge.因此,通过分析获得循环的上限将是一个挑战。

However that doesn't mean you can't solve the issue.但是,这并不意味着您无法解决问题。

Solutions:解决方案:

Option one is, as suggested in the comments run your code on the CPU until you find the maximum number of iterations and then send that number as the upper bound of your loop (eg as a uniform).选项一是,正如评论中所建议的那样,在 CPU 上运行您的代码,直到您找到最大迭代次数,然后将该数字作为循环的上限(例如作为统一)发送。

Another solution that is perhaps better is, set the maximum number of iterations to a huge number and then, inside the body of the loop, break if you have exceeded your threshold (this is possible in modern. ie 4+ versions of GLSL).另一个可能更好的解决方案是将最大迭代次数设置为一个巨大的数字,然后在循环体内,如果您超过了阈值,则break (这在现代是可能的。即 4+ 版本的 GLSL)。

As suggested by several people in the comments, this pattern doesn't follow a log graph, a harmonic graph, or any recognizable pattern.正如评论中的几个人所建议的那样,这种模式不遵循对数图、谐波图或任何可识别的模式。 To solve it I had to go with a "brute-force" approach of just running the loop once, then using the iteration count as the result.为了解决它,我不得不使用“蛮力”方法来 go 只运行一次循环,然后使用迭代计数作为结果。 There was no elegant math equation.没有优雅的数学方程式。

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM