Добавить в корзинуПозвонить
Найти в Дзене
Postgres DBA

Как определить точку бифуркацию для дискретной функции с использованием PostgreSQL?

Создадим таблицу для генерации последовательности: CREATE TABLE bifurcation ( mu FLOAT, -- параметр системы n INT, -- номер итерации x FLOAT -- значение функции ); -- Заполняем данными: xₙ₊₁ = μ * xₙ * (1 - xₙ) INSERT INTO bifurcation WITH RECURSIVE seq AS ( SELECT mu, 0 AS n, 0.5 AS x -- начальное значение x₀ FROM generate_series(2.5, 4.0, 0.01) AS mu -- диапазон μ UNION ALL SELECT mu, n + 1, mu * x * (1 - x) -- формула итерации FROM seq WHERE n < 500 -- количество итераций ) SELECT * FROM seq WHERE n > 400; -- используем последние 100 итераций (аттрактор) CREATE TABLE attractors AS SELECT mu, ROUND(x::numeric, 3) AS x_rounded, -- округление для группировки COUNT(*) AS count_points FROM bifurcation GROUP BY mu, x_rounded; WITH periods AS ( SELECT mu, COUNT(*) AS period -- количество уникальных точек ≈ период цикла FROM attractors GROUP BY mu ) SELECT * FROM periods; WITH periods AS ( SELECT mu, COUNT(DISTINCT x_rounded) AS period FROM attractors GROUP BY mu
Оглавление
Чтобы понять бифуркацию , нужно погрузится в бифуркацию
Чтобы понять бифуркацию , нужно погрузится в бифуркацию

1. Подготовка данных

Создадим таблицу для генерации последовательности:

CREATE TABLE bifurcation (
mu FLOAT, -- параметр системы
n INT, -- номер итерации
x FLOAT -- значение функции
);
-- Заполняем данными: xₙ₊₁ = μ * xₙ * (1 - xₙ)
INSERT INTO bifurcation
WITH RECURSIVE seq AS (
SELECT
mu,
0 AS n,
0.5 AS x -- начальное значение x₀
FROM generate_series(2.5, 4.0, 0.01) AS mu -- диапазон μ
UNION ALL
SELECT
mu,
n + 1,
mu * x * (1 - x) -- формула итерации
FROM seq
WHERE n < 500 -- количество итераций
)
SELECT * FROM seq WHERE n > 400; -- используем последние 100 итераций (аттрактор)

2. Поиск точек бифуркации

Шаг 1. Группируем значения аттрактора для каждого μ

CREATE TABLE attractors AS
SELECT
mu,
ROUND(x::numeric, 3) AS x_rounded, -- округление для группировки
COUNT(*) AS count_points
FROM bifurcation
GROUP BY mu, x_rounded;

Шаг 2. Определяем период цикла

WITH periods AS (
SELECT
mu,
COUNT(*) AS period -- количество уникальных точек ≈ период цикла
FROM attractors
GROUP BY mu
)
SELECT * FROM periods;

Шаг 3. Находим скачки периода (точки бифуркации)

WITH periods AS (
SELECT
mu,
COUNT(DISTINCT x_rounded) AS period
FROM attractors
GROUP BY mu
),
changes AS (
SELECT
mu,
period,
LAG(period) OVER (ORDER BY mu) AS prev_period,
period - LAG(period) OVER (ORDER BY mu) AS period_jump
FROM periods
)
SELECT
mu,
period,
period_jump
FROM changes
WHERE period_jump > 0; -- фильтр скачков

3. Визуализация результатов

COPY (
SELECT mu, x_rounded FROM attractors
) TO '/tmp/bifurcation.csv' CSV HEADER;

4. Автоматическое определение критических μ

WITH period_changes AS (
SELECT
mu,
period,
LAG(period) OVER (ORDER BY mu) AS prev_period
FROM (
SELECT mu, COUNT(DISTINCT x_rounded) AS period
FROM attractors GROUP BY mu
) t
)
SELECT
mu,
period,
prev_period
FROM period_changes
WHERE period >= 2 * prev_period; -- условие удвоения периода

5. Точный расчет через производные (дополнительно)

WITH derivatives AS (
SELECT
mu,
AVG(ABS(mu * (1 - 2 * x))) AS df_dx -- производная ∂f/∂x
FROM bifurcation
GROUP BY mu
)
SELECT
mu,
df_dx,
CASE
WHEN ABS(df_dx - 1) < 0.01 THEN 'Бифуркация'
ELSE '-'
END AS status
FROM derivatives
WHERE ABS(df_dx - 1) < 0.01; -- условие потери устойчивости

Ключевые моменты

  1. Генерация данных: Используйте WITH RECURSIVE для итераций.
  2. Аттрактор: Анализируйте последние итерации (n > 400).
  3. Период цикла: Группируйте округленные значения x.
  4. Точки бифуркации: Ищите скачки периода или где |∂f/∂x| ≈ 1.
  5. Визуализация: Экспорт в CSV + построение диаграммы рассеяния.