File size: 4,981 Bytes
3ffebe8
599d710
ec3010d
ab731e4
411f3df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cab60db
6c5a763
411f3df
6c5a763
 
411f3df
 
6c5a763
 
411f3df
 
 
 
ec3010d
411f3df
c00d034
ec3010d
 
 
c00d034
ec3010d
411f3df
 
c00d034
 
411f3df
 
c00d034
 
 
411f3df
ec3010d
411f3df
 
c00d034
 
 
411f3df
c00d034
 
 
411f3df
c00d034
 
 
 
ec3010d
411f3df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec3010d
411f3df
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import numpy as np
import matplotlib.pyplot as plt
import streamlit as st

# === Параметры модели ===
SEQ_LEN = 100  # длина последовательности
HISTORY_LEN = 200  # сколько шагов хранить в статистике
JUMP = 10  # максимальный шаг изменения угла
ENTROPY_BINS = 36  # шаг 10 градусов

# === Инициализация состояния ===
if "seq" not in st.session_state:
    st.session_state.seq = np.random.randint(-180, 180, size=SEQ_LEN)
    st.session_state.history = []
    st.session_state.bist_counts = []
    st.session_state.entropy = []
    st.session_state.autocorr = []
    st.session_state.step = 0

# === Функции анализа ===
def find_local_min_runs(profile, threshold=10):
    """Находит устойчивые участки ("машины"), где значения углов почти не меняются."""
    runs = []
    start = 0
    for i in range(1, len(profile)):
        if abs(profile[i] - profile[i - 1]) > threshold:
            if i - start > 2:
                runs.append((start, i - 1))
            start = i
    if len(profile) - start > 2:
        runs.append((start, len(profile) - 1))
    return runs

def compute_autocorr(profile):
    """Автокорреляция – структурность, насколько повторяется рисунок"""
    profile = profile - np.mean(profile)
    result = np.correlate(profile, profile, mode='full')
    mid = len(result) // 2
    return result[mid + 1] / result[mid]

def compute_entropy(profile):
    """Энтропия – мера хаотичности, насколько случайна структура"""
    hist, _ = np.histogram(profile, bins=ENTROPY_BINS, range=(-180, 180), density=True)
    hist = hist[hist > 0]
    return -np.sum(hist * np.log2(hist))

# === Функция отрисовки ===
def draw_world(seq, axs, step, stat_bist_counts, stat_entropy, stat_autocorr):
    axs[0].cla()
    axs[1].cla()
    axs[2].cla()
    axs[3].cla()

    # Отображение профиля
    axs[0].plot(seq, label=f"Шаг {step}", color='skyblue')
    axs[0].set_title("Торсионный профиль (углы)")
    axs[0].set_ylim(-180, 180)

    # Визуальное выделение устойчивых "машин"
    stable_zones = find_local_min_runs(seq)
    for start, end in stable_zones:
        axs[0].axvspan(start, end, color='yellow', alpha=0.3)
        axs[0].text((start + end) // 2, 160, f'▲{end - start}', ha='center', va='center', fontsize=8, color='darkgreen')

    # График количества "стромбистов"
    axs[1].plot(stat_bist_counts, color='orchid')
    axs[1].set_title("Кол-во устойчивых машин (стромбистов)")

    # Энтропия
    axs[2].plot(stat_entropy, color='crimson')
    axs[2].set_title("Энтропия торсионного поля")

    # Автокорреляция
    axs[3].plot(stat_autocorr, color='seagreen')
    axs[3].set_title("Автокорреляция (память)")

    for ax in axs:
        ax.legend()

# === Функция обновления ===
def update_step():
    seq = st.session_state.seq
    history = st.session_state.history
    stat_bist_counts = st.session_state.bist_counts
    stat_entropy = st.session_state.entropy
    stat_autocorr = st.session_state.autocorr
    step = st.session_state.step

    # Случайная мутация
    i = np.random.randint(0, len(seq))
    delta = np.random.randint(-JUMP, JUMP + 1)
    seq[i] = (seq[i] + delta + 180) % 360 - 180

    history.append(seq.copy())
    if len(history) > HISTORY_LEN:
        history.pop(0)

    stable_regions = find_local_min_runs(seq)
    stat_bist_counts.append(len(stable_regions))
    stat_entropy.append(compute_entropy(seq))
    stat_autocorr.append(compute_autocorr(seq))
    st.session_state.step += 1

# === Интерфейс Streamlit ===
st.set_page_config(layout="wide")
st.title("🧬 Стромбистный анализ торсионного поля")
col1, col2 = st.columns([1, 2])

with col1:
    if st.button("🔁 Следующий шаг"):
        update_step()
    st.markdown(f"**Текущий шаг**: {st.session_state.step}")
    st.markdown("**Стромбисты** — устойчивые участки структуры, подобные памяти или машинам.")
    st.markdown("**Автокорреляция** — отражает повторяемость паттерна.")
    st.markdown("**Энтропия** — мера хаоса.")

with col2:
    fig, axs = plt.subplots(4, 1, figsize=(10, 10), sharex=True)
    draw_world(
        st.session_state.seq,
        axs,
        st.session_state.step,
        st.session_state.bist_counts,
        st.session_state.entropy,
        st.session_state.autocorr
    )
    st.pyplot(fig)