Математическое уравнение для определения количества итераций в асимптотическом цикле?

У меня есть цикл, рост которого уменьшается по мере увеличения количества итераций. Мне нужно рассчитать количество итераций, которые он пройдет (я объясняю, почему мне это нужно, в конце этого вопроса). Первые 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).

Другие вопросы по тегам