<jupyter_start><jupyter_text>Simulating an All-Pass Filter A simple comparison between an analytical evaluation of an all pass filter and using SAX.  Imports<jupyter_code>import jax
import jax.example_libraries.optimizers as opt
import jax.numpy as jnp
import matplotlib.pyplot as plt
import sax
import tqdm<jupyter_output><empty_output><jupyter_text>Schematic```           in0---out0        in1          out1           \        /            ========           /        \ in0  out0```  Simulation & Design Parameters<jupyter_code>loss = 0.1  # [dB/μm] (alpha) waveguide loss
neff = 2.34  # Effective index of the waveguides
ng = 3.4  # Group index of the waveguides
wl0 = 1.55  # [μm] the wavelength at which neff and ng are defined
ring_length = 10.0  # [μm] Length of the ring
coupling = 0.5  # [] coupling of the coupler
wl = jnp.linspace(1.5, 1.6, 1000)  # [μm] Wavelengths to sweep over<jupyter_output><empty_output><jupyter_text>Frequency Domain Analytically As a comparison, we first calculate the frequency domain response for the all-pass filter analytically:\begin{align*}o = \frac{t-10^{-\alpha L/20}\exp(2\pi j n_{\rm eff}(\lambda) L / \lambda)}{1-t10^{-\alpha L/20}\exp(2\pi j n_{\rm eff}(\lambda) L / \lambda)}s\end{align*}<jupyter_code>def all_pass_analytical():
    """ Analytic Frequency Domain Response of an all pass filter """
    detected = jnp.zeros_like(wl)
    transmission = 1 - coupling
    neff_wl = neff + (wl0 - wl) * (ng - neff) / wl0  # we expect a linear behavior with respect to wavelength
    out = jnp.sqrt(transmission) - 10 ** (-loss * ring_length / 20.0) * jnp.exp(2j * jnp.pi * neff_wl * ring_length / wl)
    out /= 1 - jnp.sqrt(transmission) * 10 ** (-loss * ring_length / 20.0) * jnp.exp(2j * jnp.pi * neff_wl * ring_length / wl)
    detected = abs(out) ** 2
    return detected
%time detected = all_pass_analytical() # non-jitted evaluation time
all_pass_analytical_jitted = jax.jit(all_pass_analytical)
%time detected = all_pass_analytical_jitted() # time to jit
%time detected = all_pass_analytical_jitted() # evaluation time after jitting

plt.plot(wl * 1e3, detected)
plt.xlabel("λ [nm]")
plt.ylabel("T")
plt.show()<jupyter_output><empty_output><jupyter_text>Scatter Dictionaries<jupyter_code>all_pass_sax = sax.circuit(
    instances={
        "dc": sax.partial(sax.models.coupler, coupling=coupling),
        "top": sax.partial(sax.models.straight, length=ring_length, loss=loss, neff=neff, ng=ng, wl0=wl0, wl=wl),
    },
    connections={
        "dc,out1": "top,in0",
        "top,out0": "dc,in1",
    },
    ports={
        "in0": "dc,in0",
        "out0": "dc,out0",
    },
)
%time detected_sax = all_pass_sax() # non-jitted evaluation time
all_pass_sax_jitted = jax.jit(all_pass_analytical)
%time detected_sax = all_pass_sax_jitted() # time to jit
%time detected_sax = all_pass_sax_jitted() # time after jitting

plt.plot(wl * 1e3, detected, label="analytical")
plt.plot(wl * 1e3, detected_sax, label="sax", ls="--", lw=3)
plt.xlabel("λ [nm]")
plt.ylabel("T")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1352324819908317, 'fraction_numerical': 0.02455795677799607, 'mean_word_length': 3.8262243285939967, 'pattern_counts': {'":': 6, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '315906', 'license': 'Apache-2.0', 'n_tokens_mistral': 1180, 'n_tokens_neox': 1107, 'n_words': 273, 'path': 'examples/02_all_pass_filter.ipynb', 'repo_name': 'joamatab/sax', 'size': '3054'}