Files
lucidia-main/codex/mirror/mirror_mechanics.py
2025-08-10 18:39:18 -07:00

114 lines
3.0 KiB
Python

"""
mirror_mechanics.py
This module implements the mirror operator \u03a8' and breath operator \u2102
for the harmonic oscillator. It provides a basic demonstration of
oscillator dynamics and how positive and negative frequency components
are defined.
Functions:
mirror_split(signal) -> (pos, neg)
breath_step(q, p, omega=1.0, dt=0.01) -> (q_new, p_new)
run_oscillator(steps=1000, dt=0.01, omega=1.0) -> (qs, ps)
Example:
if __name__ == "__main__":
qs, ps = run_oscillator()
pos, neg = mirror_split(qs)
"""
import numpy as np
try:
from scipy.signal import hilbert
except ImportError:
hilbert = None
def mirror_split(signal: np.ndarray):
"""
Split a real-valued signal into its positive and negative frequency components.
Parameters
----------
signal : np.ndarray
Real-valued time series.
Returns
-------
pos : np.ndarray
The positive frequency component (analytic signal divided by 2).
neg : np.ndarray
The negative frequency component.
"""
if hilbert is None:
raise ImportError(
"scipy is required for mirror_split; install scipy to use this function"
)
analytic = hilbert(signal)
pos = analytic / 2.0
neg = np.conj(analytic) - pos
return pos, neg
def breath_step(q: float, p: float, omega: float = 1.0, dt: float = 0.01):
"""
Perform a single leap-frog (symplectic) update for a harmonic oscillator.
Parameters
----------
q : float
Position.
p : float
Momentum.
omega : float, optional
Oscillator frequency (default 1.0).
dt : float, optional
Time step (default 0.01).
Returns
-------
q_new : float
Updated position.
p_new : float
Updated momentum.
"""
p_half = p - 0.5 * dt * (omega ** 2) * q
q_new = q + dt * p_half
p_new = p_half - 0.5 * dt * (omega ** 2) * q_new
return q_new, p_new
def run_oscillator(steps: int = 1000, dt: float = 0.01, omega: float = 1.0):
"""
Run a harmonic oscillator using the breath operator.
Parameters
----------
steps : int, optional
Number of time steps (default 1000).
dt : float, optional
Time step (default 0.01).
omega : float, optional
Oscillator frequency (default 1.0).
Returns
-------
qs : np.ndarray
Array of positions over time.
ps : np.ndarray
Array of momenta over time.
"""
q, p = 1.0, 0.0
qs, ps = [], []
for _ in range(steps):
qs.append(q)
ps.append(p)
q, p = breath_step(q, p, omega, dt)
return np.array(qs), np.array(ps)
if __name__ == "__main__":
# Simple demonstration: simulate and split into mirror components
qs, ps = run_oscillator(steps=1024, dt=0.01, omega=1.0)
if hilbert is not None:
pos, neg = mirror_split(qs)
print(f"First few positive components: {pos[:5]}")
print(f"First few negative components: {neg[:5]}")
else:
print("Scipy not installed; cannot compute mirror components.")