Математическое уравнение для определения количества итераций в асимптотическом цикле?
У меня есть цикл, рост которого уменьшается по мере увеличения количества итераций. Мне нужно рассчитать количество итераций, которые он пройдет (я объясняю, почему мне это нужно, в конце этого вопроса). Первые 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
во внимание, чтобы получить количество итераций?
Зачем мне это нужно?
Я пытаюсь преобразовать пример кода внизу этой статьи в код шейдера GLSL. Проблема в том, что видеокарты могут выполнять только циклы for с целыми числами, считающимися до константы, поэтому мне нужно знать, сколько итераций будет выполняться цикл, прежде чем запускать цикл.
Мне нужно что-то вроде этого: for(int i = 0; i < MAX_COUNT; i++)
но сначала мне нужно знать, что MAX_COUNT
будет.
2 ответа
Как было предложено несколькими людьми в комментариях, этот шаблон не следует логическому графику, гармоническому графику или любому узнаваемому шаблону. Чтобы решить эту проблему, мне пришлось применить метод "грубой силы": просто запустить цикл один раз, а затем использовать в качестве результата счетчик итераций. Не было элегантного математического уравнения.
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;
}
Итак, у меня есть 2 решения, сначала математика:
Как упоминалось в комментариях, у вас есть гармонический ряд, который не имеет простой закрытой формы. Поэтому аналитическое получение верхней границы цикла будет сложной задачей.
Однако это не значит, что вы не можете решить проблему.
Решения:
Первый вариант, как предлагается в комментариях, - запускать код на ЦП до тех пор, пока не будет найдено максимальное количество итераций, а затем отправить это число в качестве верхней границы цикла (например, в виде униформы).
Другое решение, которое, возможно, лучше, - установить максимальное количество итераций на огромное число, а затем внутри тела цикла break
если вы превысили свой порог (это возможно в современных, т.е. 4+ версиях GLSL).