Я хочу написать SQL запрос, который рассчитает iterated function sequence некоторой функции до тех пор, пока не достигнет фиксированной точки, а затем вернуть эту стационарную точку:Вычислять фиксированную точку функции в sql?
f(f(f(f ..(x)))) = x0 = f(x0)
Э.Г. пусть f(x) = (256/x + x)/2
:
create function f(x float) returns float as $$
select (256/x + x)/2
$$ language sql;
Вот моя попытка написать запрос:
create function f_sequence(x float) returns table(x0 float) as $$
with recursive
t(a,b) as
(select x, f(x)
union all
select b, f(b) from t where a <> b)
select a from t;
$$ language sql;
Теперь можно получить итерированную последовательность, сходящуюся к некоторой фиксированной точке:
=# select f_sequence(333);
f_sequence
------------------
333
166.884384384384
84.2091902577822
43.6246192451207
24.7464326525125
17.5456790321891
16.0680829640781
16.0001442390486
16.0000000006501
16
(10 rows)
(на самом деле он сходится к √256, потому что это расчета квадратных корней.)
Теперь мне нужно еще один запрос, чтобы получить только последнюю строку из последовательности:
=# with
res as (select array_agg(f_sequence) as res from f_sequence(333))
select res[array_length(res,1)] from res;
res
-----
16
(1 row)
Вопрос заключается в: как написать это более кратким?
В частности, мне не нравится этот отдельный запрос, чтобы получить последнее значение (и мне нужно скопировать все промежуточные значения в массиве).
В стороне: вы делаете это для развлечения или есть серьезная причина для использования pg здесь? –
Это не похоже на использование SQL для меня. – duffymo
Это часть некоторой реальной проблемы. Мне нужно рекурсивно построить подмножество объектов. На каждом шаге я выбираю лучший объект для добавления к набору, пока невозможно добавить больше. –