Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import numpy as np
|
| 3 |
+
from scipy.ndimage import gaussian_filter
|
| 4 |
+
import plotly.graph_objects as go
|
| 5 |
+
from time import sleep
|
| 6 |
+
|
| 7 |
+
class NeuralFieldExplorer:
|
| 8 |
+
def __init__(self, size=100, time_depth=50):
|
| 9 |
+
self.size = size
|
| 10 |
+
self.time_depth = time_depth
|
| 11 |
+
self.energy_flow_history = np.zeros((time_depth, size, size))
|
| 12 |
+
|
| 13 |
+
# Field parameters
|
| 14 |
+
self.u = np.zeros((size, size))
|
| 15 |
+
self.v = np.zeros((size, size))
|
| 16 |
+
self.phi = np.zeros((size, size))
|
| 17 |
+
|
| 18 |
+
# Initialize central disturbance
|
| 19 |
+
self.u[size//2, size//2] = 2.0
|
| 20 |
+
|
| 21 |
+
# Physics parameters
|
| 22 |
+
self.dt = 0.1
|
| 23 |
+
self.dx = 1.0
|
| 24 |
+
self.dy = 1.0
|
| 25 |
+
self.c = 1.0
|
| 26 |
+
self.alpha = 0.05
|
| 27 |
+
self.beta = 0.02
|
| 28 |
+
|
| 29 |
+
def update_fields(self):
|
| 30 |
+
laplacian = (
|
| 31 |
+
-4 * self.u +
|
| 32 |
+
np.roll(self.u, 1, axis=0) +
|
| 33 |
+
np.roll(self.u, -1, axis=0) +
|
| 34 |
+
np.roll(self.u, 1, axis=1) +
|
| 35 |
+
np.roll(self.u, -1, axis=1)
|
| 36 |
+
) / (self.dx * self.dy)
|
| 37 |
+
|
| 38 |
+
quantum_input = np.random.normal(0, 0.1, (self.size, self.size))
|
| 39 |
+
classical_input = np.zeros((self.size, self.size))
|
| 40 |
+
|
| 41 |
+
a = self.c**2 * laplacian - self.beta * self.v - self.alpha * (self.u**3) + quantum_input + classical_input
|
| 42 |
+
v_new = self.v + a * self.dt
|
| 43 |
+
u_new = self.u + v_new * self.dt
|
| 44 |
+
phi_new = self.phi + (v_new * self.dt)
|
| 45 |
+
|
| 46 |
+
self.u, self.v, self.phi = u_new, v_new, phi_new
|
| 47 |
+
|
| 48 |
+
def calculate_energy_flow(self):
|
| 49 |
+
grad_x = np.gradient(self.u, axis=0)
|
| 50 |
+
grad_y = np.gradient(self.u, axis=1)
|
| 51 |
+
energy_flow = np.sqrt(grad_x**2 + grad_y**2)
|
| 52 |
+
energy_flow = gaussian_filter(energy_flow, sigma=1)
|
| 53 |
+
return (energy_flow - energy_flow.min()) / (energy_flow.max() - energy_flow.min() + 1e-8)
|
| 54 |
+
|
| 55 |
+
def update_history(self, energy_flow):
|
| 56 |
+
self.energy_flow_history = np.roll(self.energy_flow_history, -1, axis=0)
|
| 57 |
+
self.energy_flow_history[-1] = energy_flow
|
| 58 |
+
|
| 59 |
+
def create_3d_visualization(self):
|
| 60 |
+
x, y = np.meshgrid(np.arange(self.size), np.arange(self.size))
|
| 61 |
+
|
| 62 |
+
# Create empty lists for our surface plots
|
| 63 |
+
surfaces = []
|
| 64 |
+
|
| 65 |
+
# Create a surface for each time slice
|
| 66 |
+
for i in range(0, self.time_depth, 2):
|
| 67 |
+
z = i * np.ones_like(x)
|
| 68 |
+
|
| 69 |
+
# Create surface with custom coloring
|
| 70 |
+
surfaces.append(
|
| 71 |
+
go.Surface(
|
| 72 |
+
x=x,
|
| 73 |
+
y=y,
|
| 74 |
+
z=z,
|
| 75 |
+
surfacecolor=self.energy_flow_history[i],
|
| 76 |
+
showscale=False,
|
| 77 |
+
opacity=0.3,
|
| 78 |
+
colorscale='Magma'
|
| 79 |
+
)
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
return surfaces
|
| 83 |
+
|
| 84 |
+
def main():
|
| 85 |
+
st.title("🧠 Neural Field Pattern Explorer")
|
| 86 |
+
st.write("Exploring the 3D structure of neural field patterns in real-time!")
|
| 87 |
+
|
| 88 |
+
# Initialize session state
|
| 89 |
+
if 'explorer' not in st.session_state:
|
| 90 |
+
st.session_state.explorer = NeuralFieldExplorer()
|
| 91 |
+
st.session_state.frame_count = 0
|
| 92 |
+
|
| 93 |
+
# Control panel
|
| 94 |
+
col1, col2, col3 = st.columns(3)
|
| 95 |
+
with col1:
|
| 96 |
+
running = st.checkbox('Run Simulation', value=True)
|
| 97 |
+
with col2:
|
| 98 |
+
speed = st.slider('Animation Speed', 1, 10, 5)
|
| 99 |
+
with col3:
|
| 100 |
+
transparency = st.slider('Layer Transparency', 0.1, 1.0, 0.3)
|
| 101 |
+
|
| 102 |
+
# Create placeholders for our visualizations
|
| 103 |
+
plot3d = st.empty()
|
| 104 |
+
plot2d = st.empty()
|
| 105 |
+
|
| 106 |
+
# Main simulation loop
|
| 107 |
+
while running:
|
| 108 |
+
# Update fields
|
| 109 |
+
st.session_state.explorer.update_fields()
|
| 110 |
+
energy_flow = st.session_state.explorer.calculate_energy_flow()
|
| 111 |
+
st.session_state.explorer.update_history(energy_flow)
|
| 112 |
+
|
| 113 |
+
# Create 3D visualization
|
| 114 |
+
surfaces = st.session_state.explorer.create_3d_visualization()
|
| 115 |
+
|
| 116 |
+
# Update 3D plot
|
| 117 |
+
fig3d = go.Figure(data=surfaces)
|
| 118 |
+
fig3d.update_layout(
|
| 119 |
+
title='3D Neural Field Patterns',
|
| 120 |
+
scene=dict(
|
| 121 |
+
xaxis_title='X',
|
| 122 |
+
yaxis_title='Y',
|
| 123 |
+
zaxis_title='Time',
|
| 124 |
+
camera=dict(
|
| 125 |
+
up=dict(x=0, y=0, z=1),
|
| 126 |
+
center=dict(x=0, y=0, z=0),
|
| 127 |
+
eye=dict(x=1.5, y=1.5, z=1.5)
|
| 128 |
+
)
|
| 129 |
+
),
|
| 130 |
+
width=800,
|
| 131 |
+
height=600
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
# Update 2D plot
|
| 135 |
+
fig2d = go.Figure(data=go.Heatmap(
|
| 136 |
+
z=energy_flow,
|
| 137 |
+
colorscale='Magma'
|
| 138 |
+
))
|
| 139 |
+
fig2d.update_layout(
|
| 140 |
+
title='Current Energy Flow',
|
| 141 |
+
width=400,
|
| 142 |
+
height=400
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
# Display plots
|
| 146 |
+
plot3d.plotly_chart(fig3d, use_container_width=True)
|
| 147 |
+
plot2d.plotly_chart(fig2d, use_container_width=True)
|
| 148 |
+
|
| 149 |
+
# Control animation speed
|
| 150 |
+
sleep(1.0 / speed)
|
| 151 |
+
|
| 152 |
+
st.session_state.frame_count += 1
|
| 153 |
+
|
| 154 |
+
# Break if checkbox is unchecked
|
| 155 |
+
if not running:
|
| 156 |
+
break
|
| 157 |
+
|
| 158 |
+
if __name__ == "__main__":
|
| 159 |
+
st.set_page_config(page_title="Neural Field Explorer", layout="wide")
|
| 160 |
+
main()
|