在渐近循环中查找迭代次数的数学方程式?
Math equation to find number of iterations in asymptotic loop?
我有一个循环,它随着迭代次数的增加而减少。我需要计算它将经历的迭代次数(我在这个问题的底部解释了为什么我需要这个)。前 6 个步骤是
0.50, 1.50, 1.83, 2.11, 2.34, 2.55, ...
X-axis:迭代,Y-axis:计数
计数从 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-loops 整数计数到一个常数,所以我需要在开始循环之前知道循环将进行多少次迭代。
我需要这样的东西:for(int i = 0; i < MAX_COUNT; i++)
但首先我需要知道 MAX_COUNT
会是什么。
所以我有 2 个解决方案,首先是数学:
如评论中所述,您拥有的是调和级数,它没有简单的闭合形式。因此,通过分析获得循环的上限将是一个挑战。
但这并不意味着您无法解决问题。
解决方案:
选项一是,正如评论 运行 中所建议的那样,您在 CPU 上的代码直到找到最大迭代次数,然后将该数字作为循环的上限发送(例如作为制服)。
另一个可能更好的解决方案是,将最大迭代次数设置为一个很大的数字,然后在循环体内,break
如果您超过了阈值(这在现代. 即 GLSL 的 4 个以上版本)。
正如几个人在评论中所建议的那样,此模式不遵循对数图、调和图或任何可识别的模式。为了解决这个问题,我不得不采用 "brute-force" 方法,即仅 运行 循环一次,然后使用迭代计数作为结果。没有优雅的数学方程式。
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;
}
我有一个循环,它随着迭代次数的增加而减少。我需要计算它将经历的迭代次数(我在这个问题的底部解释了为什么我需要这个)。前 6 个步骤是
0.50, 1.50, 1.83, 2.11, 2.34, 2.55, ...
计数从 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-loops 整数计数到一个常数,所以我需要在开始循环之前知道循环将进行多少次迭代。
我需要这样的东西:for(int i = 0; i < MAX_COUNT; i++)
但首先我需要知道 MAX_COUNT
会是什么。
所以我有 2 个解决方案,首先是数学:
如评论中所述,您拥有的是调和级数,它没有简单的闭合形式。因此,通过分析获得循环的上限将是一个挑战。
但这并不意味着您无法解决问题。
解决方案:
选项一是,正如评论 运行 中所建议的那样,您在 CPU 上的代码直到找到最大迭代次数,然后将该数字作为循环的上限发送(例如作为制服)。
另一个可能更好的解决方案是,将最大迭代次数设置为一个很大的数字,然后在循环体内,break
如果您超过了阈值(这在现代. 即 GLSL 的 4 个以上版本)。
正如几个人在评论中所建议的那样,此模式不遵循对数图、调和图或任何可识别的模式。为了解决这个问题,我不得不采用 "brute-force" 方法,即仅 运行 循环一次,然后使用迭代计数作为结果。没有优雅的数学方程式。
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;
}