From 89b98f15fd36b6d5391b72bbc08e61c1a4b88188 Mon Sep 17 00:00:00 2001 From: Chaoming Wang Date: Fri, 10 Oct 2025 15:04:48 +0800 Subject: [PATCH 1/2] fix(docs): update references to brainpy.state in documentation and examples --- docs_state/api/index.rst | 26 +- docs_state/api/neurons.rst | 440 +------------- docs_state/api/projections.rst | 158 +---- docs_state/api/synapses.rst | 352 +---------- docs_state/core-concepts/architecture.rst | 40 +- docs_state/core-concepts/neurons.rst | 42 +- docs_state/core-concepts/projections.rst | 118 ++-- docs_state/core-concepts/state-management.rst | 16 +- docs_state/core-concepts/synapses.rst | 83 +-- docs_state/examples/gallery.rst | 42 +- .../how-to-guides/custom-components.rst | 30 +- .../how-to-guides/debugging-networks.rst | 60 +- docs_state/how-to-guides/gpu-tpu-usage.rst | 62 +- .../performance-optimization.rst | 24 +- docs_state/how-to-guides/save-load-models.rst | 4 +- docs_state/migration/migration-guide.rst | 567 ------------------ docs_state/quickstart/5min-tutorial.ipynb | 2 +- docs_state/snn_simulation-en.ipynb | 12 +- docs_state/snn_simulation-zh.ipynb | 12 +- docs_state/snn_training-en.ipynb | 6 +- docs_state/snn_training-zh.ipynb | 6 +- .../tutorials/advanced/05-snn-training.ipynb | 12 +- .../advanced/06-synaptic-plasticity.ipynb | 22 +- .../advanced/07-large-scale-simulations.ipynb | 86 +-- .../tutorials/basic/01-lif-neuron.ipynb | 14 +- .../tutorials/basic/02-synapse-models.ipynb | 22 +- .../basic/03-network-connections.ipynb | 56 +- .../tutorials/basic/04-input-output.ipynb | 10 +- 28 files changed, 436 insertions(+), 1888 deletions(-) delete mode 100644 docs_state/migration/migration-guide.rst diff --git a/docs_state/api/index.rst b/docs_state/api/index.rst index 01988647..03a7e5d0 100644 --- a/docs_state/api/index.rst +++ b/docs_state/api/index.rst @@ -54,16 +54,16 @@ Neurons .. code-block:: python - import brainpy.state_based as brainpy + import brainpy # Leaky Integrate-and-Fire - brainpy.LIF(size, V_rest, V_th, V_reset, tau, R, ...) + brainpy.state.LIF(size, V_rest, V_th, V_reset, tau, R, ...) # Adaptive LIF - brainpy.ALIF(size, V_rest, V_th, V_reset, tau, tau_w, a, b, ...) + brainpy.state.ALIF(size, V_rest, V_th, V_reset, tau, tau_w, a, b, ...) # Izhikevich - brainpy.Izhikevich(size, a, b, c, d, ...) + brainpy.state.Izhikevich(size, a, b, c, d, ...) Synapses ~~~~~~~~ @@ -71,16 +71,16 @@ Synapses .. code-block:: python # Exponential - brainpy.Expon.desc(size, tau) + brainpy.state.Expon.desc(size, tau) # Alpha - brainpy.Alpha.desc(size, tau) + brainpy.state.Alpha.desc(size, tau) # AMPA receptor - brainpy.AMPA.desc(size, tau) + brainpy.state.AMPA.desc(size, tau) # GABA_a receptor - brainpy.GABAa.desc(size, tau) + brainpy.state.GABAa.desc(size, tau) Projections ~~~~~~~~~~~ @@ -88,10 +88,10 @@ Projections .. code-block:: python # Standard projection - brainpy.AlignPostProj( + brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob, weight), - syn=brainpy.Expon.desc(n_post, tau), - out=brainpy.COBA.desc(E), + syn=brainpy.state.Expon.desc(n_post, tau), + out=brainpy.state.COBA.desc(E), post=post_neurons ) @@ -152,8 +152,8 @@ BrainPy uses a clear import hierarchy: import braintools # Training utilities # Neurons and synapses - neuron = brainpy.LIF(100, ...) - synapse = brainpy.Expon.desc(100, tau=5*u.ms) + neuron = brainpy.state.LIF(100, ...) + synapse = brainpy.state.Expon.desc(100, tau=5*u.ms) # State management state = brainstate.ShortTermState(...) diff --git a/docs_state/api/neurons.rst b/docs_state/api/neurons.rst index deceae0f..e9c95d6f 100644 --- a/docs_state/api/neurons.rst +++ b/docs_state/api/neurons.rst @@ -3,437 +3,15 @@ Neuron Models Spiking neuron models in BrainPy. -.. currentmodule:: brainpy +.. currentmodule:: brainpy.state -Base Class ----------- -Neuron -~~~~~~ +.. autosummary:: + :toctree: generated/ + :nosignatures: + :template: classtemplate.rst -.. class:: Neuron(size, **kwargs) - - Base class for all neuron models. - - All neuron models inherit from this class and implement the ``update()`` method - for their specific dynamics. - - **Parameters:** - - - ``size`` (int) - Number of neurons in the population - - ``**kwargs`` - Additional keyword arguments - - **Key Methods:** - - .. method:: update(x) - - Update neuron dynamics for one time step. - - :param x: Input current with units (e.g., ``2.0 * u.nA``) - :type x: Array with brainunit - :returns: Updated state (typically membrane potential) - - .. method:: get_spike() - - Get current spike state. - - :returns: Binary spike indicator (1 = spike, 0 = no spike) - :rtype: Array of shape ``(size,)`` or ``(batch_size, size)`` - - .. method:: reset_state(batch_size=None) - - Reset neuron state for new trial. - - :param batch_size: Optional batch dimension - :type batch_size: int or None - - **Common Attributes:** - - - ``V`` (ShortTermState) - Membrane potential - - ``spike`` (ShortTermState) - Spike indicator - - ``size`` (int) - Number of neurons - - **Example:** - - .. code-block:: python - - # Subclass to create custom neuron - class CustomNeuron(bp.Neuron): - def __init__(self, size, tau=10*u.ms): - super().__init__(size) - self.tau = tau - self.V = brainstate.ShortTermState(jnp.zeros(size)) - - def update(self, x): - # Custom dynamics - pass - -Integrate-and-Fire Models --------------------------- - -IF -~~ - -.. class:: IF(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, **kwargs) - - Basic Integrate-and-Fire neuron. - - **Model:** - - .. math:: - - \\frac{dV}{dt} = I_{ext} - - Spikes when :math:`V \\geq V_{th}`, then resets to :math:`V_{reset}`. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``V_rest`` (Quantity[mV]) - Resting potential (default: -65 mV) - - ``V_th`` (Quantity[mV]) - Spike threshold (default: -50 mV) - - ``V_reset`` (Quantity[mV]) - Reset potential (default: -65 mV) - - **States:** - - - ``V`` (ShortTermState) - Membrane potential [mV] - - ``spike`` (ShortTermState) - Spike indicator [0 or 1] - - **Example:** - - .. code-block:: python - - import brainpy as bp - import brainstate - import brainunit as u - - neuron = bp.IF(100, V_rest=-65*u.mV, V_th=-50*u.mV) - brainstate.nn.init_all_states(neuron) - - # Simulate - for t in range(1000): - inp = brainstate.random.rand(100) * 2.0 * u.nA - neuron(inp) - spikes = neuron.get_spike() - -LIF -~~~ - -.. class:: LIF(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, tau=10*u.ms, R=1*u.ohm, **kwargs) - - Leaky Integrate-and-Fire neuron. - - **Model:** - - .. math:: - - \\tau \\frac{dV}{dt} = -(V - V_{rest}) + R I_{ext} - - Most commonly used spiking neuron model. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``V_rest`` (Quantity[mV]) - Resting potential (default: -65 mV) - - ``V_th`` (Quantity[mV]) - Spike threshold (default: -50 mV) - - ``V_reset`` (Quantity[mV]) - Reset potential (default: -65 mV) - - ``tau`` (Quantity[ms]) - Membrane time constant (default: 10 ms) - - ``R`` (Quantity[ohm]) - Input resistance (default: 1 Ω) - - **States:** - - - ``V`` (ShortTermState) - Membrane potential [mV] - - ``spike`` (ShortTermState) - Spike indicator [0 or 1] - - **Example:** - - .. code-block:: python - - # Standard LIF - neuron = bp.LIF( - size=100, - V_rest=-65*u.mV, - V_th=-50*u.mV, - V_reset=-65*u.mV, - tau=10*u.ms - ) - - brainstate.nn.init_all_states(neuron) - - # Compute F-I curve - currents = u.math.linspace(0, 5, 20) * u.nA - rates = [] - - for I in currents: - brainstate.nn.init_all_states(neuron) - spike_count = 0 - for _ in range(1000): - neuron(jnp.ones(100) * I) - spike_count += jnp.sum(neuron.get_spike()) - rate = spike_count / (1000 * 0.1 * 1e-3) / 100 # Hz - rates.append(rate) - - **See Also:** - - - :doc:`../core-concepts/neurons` - Detailed LIF guide - - :doc:`../tutorials/basic/01-lif-neuron` - LIF tutorial - -LIFRef -~~~~~~ - -.. class:: LIFRef(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, tau=10*u.ms, tau_ref=2*u.ms, **kwargs) - - LIF with refractory period. - - **Model:** - - .. math:: - - \\tau \\frac{dV}{dt} = -(V - V_{rest}) + R I_{ext} \\quad \\text{(if not refractory)} - - After spike, neuron is unresponsive for ``tau_ref`` milliseconds. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``V_rest`` (Quantity[mV]) - Resting potential (default: -65 mV) - - ``V_th`` (Quantity[mV]) - Spike threshold (default: -50 mV) - - ``V_reset`` (Quantity[mV]) - Reset potential (default: -65 mV) - - ``tau`` (Quantity[ms]) - Membrane time constant (default: 10 ms) - - ``tau_ref`` (Quantity[ms]) - Refractory period (default: 2 ms) - - **States:** - - - ``V`` (ShortTermState) - Membrane potential [mV] - - ``spike`` (ShortTermState) - Spike indicator [0 or 1] - - ``t_last_spike`` (ShortTermState) - Time since last spike [ms] - - **Example:** - - .. code-block:: python - - neuron = bp.LIFRef( - size=100, - tau=10*u.ms, - tau_ref=2*u.ms # 2ms refractory period - ) - -Adaptive Models ---------------- - -ALIF -~~~~ - -.. class:: ALIF(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, tau=10*u.ms, tau_w=100*u.ms, a=0*u.nA, b=0.5*u.nA, **kwargs) - - Adaptive Leaky Integrate-and-Fire neuron. - - **Model:** - - .. math:: - - \\tau \\frac{dV}{dt} &= -(V - V_{rest}) + R I_{ext} - R w \\\\ - \\tau_w \\frac{dw}{dt} &= a(V - V_{rest}) - w - - After spike: :math:`w \\rightarrow w + b` - - Implements spike-frequency adaptation through adaptation current :math:`w`. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``V_rest`` (Quantity[mV]) - Resting potential (default: -65 mV) - - ``V_th`` (Quantity[mV]) - Spike threshold (default: -50 mV) - - ``V_reset`` (Quantity[mV]) - Reset potential (default: -65 mV) - - ``tau`` (Quantity[ms]) - Membrane time constant (default: 10 ms) - - ``tau_w`` (Quantity[ms]) - Adaptation time constant (default: 100 ms) - - ``a`` (Quantity[nA]) - Subthreshold adaptation (default: 0 nA) - - ``b`` (Quantity[nA]) - Spike-triggered adaptation (default: 0.5 nA) - - **States:** - - - ``V`` (ShortTermState) - Membrane potential [mV] - - ``w`` (ShortTermState) - Adaptation current [nA] - - ``spike`` (ShortTermState) - Spike indicator [0 or 1] - - **Example:** - - .. code-block:: python - - # Adapting neuron - neuron = bp.ALIF( - size=100, - tau=10*u.ms, - tau_w=100*u.ms, # Slow adaptation - a=0.1*u.nA, # Subthreshold coupling - b=0.5*u.nA # Spike-triggered jump - ) - - # Constant input → decreasing firing rate - brainstate.nn.init_all_states(neuron) - rates = [] - - for t in range(2000): - neuron(jnp.ones(100) * 5.0 * u.nA) - if t % 100 == 0: - rate = jnp.mean(neuron.get_spike()) - rates.append(rate) - # rates will decrease over time due to adaptation - -Izhikevich -~~~~~~~~~~ - -.. class:: Izhikevich(size, a=0.02, b=0.2, c=-65*u.mV, d=8*u.mV, **kwargs) - - Izhikevich neuron model. - - **Model:** - - .. math:: - - \\frac{dV}{dt} &= 0.04 V^2 + 5V + 140 - u + I \\\\ - \\frac{du}{dt} &= a(bV - u) - - If :math:`V \\geq 30`, then :math:`V \\rightarrow c, u \\rightarrow u + d` - - Can reproduce many different firing patterns by varying parameters. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``a`` (float) - Time scale of recovery variable (default: 0.02) - - ``b`` (float) - Sensitivity of recovery to V (default: 0.2) - - ``c`` (Quantity[mV]) - After-spike reset value of V (default: -65 mV) - - ``d`` (Quantity[mV]) - After-spike increment of u (default: 8 mV) - - **States:** - - - ``V`` (ShortTermState) - Membrane potential [mV] - - ``u`` (ShortTermState) - Recovery variable [mV] - - ``spike`` (ShortTermState) - Spike indicator [0 or 1] - - **Common Parameter Sets:** - - .. code-block:: python - - # Regular spiking - neuron_rs = bp.Izhikevich(100, a=0.02, b=0.2, c=-65*u.mV, d=8*u.mV) - - # Intrinsically bursting - neuron_ib = bp.Izhikevich(100, a=0.02, b=0.2, c=-55*u.mV, d=4*u.mV) - - # Chattering - neuron_ch = bp.Izhikevich(100, a=0.02, b=0.2, c=-50*u.mV, d=2*u.mV) - - # Fast spiking - neuron_fs = bp.Izhikevich(100, a=0.1, b=0.2, c=-65*u.mV, d=2*u.mV) - - **Example:** - - .. code-block:: python - - neuron = bp.Izhikevich(100, a=0.02, b=0.2, c=-65*u.mV, d=8*u.mV) - brainstate.nn.init_all_states(neuron) - - for t in range(1000): - inp = brainstate.random.rand(100) * 15.0 * u.nA - neuron(inp) - -Exponential Models ------------------- - -ExpIF -~~~~~ - -.. class:: ExpIF(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, tau=10*u.ms, delta_T=2*u.mV, **kwargs) - - Exponential Integrate-and-Fire neuron. - - **Model:** - - .. math:: - - \\tau \\frac{dV}{dt} = -(V - V_{rest}) + \\Delta_T e^{\\frac{V - V_{th}}{\\Delta_T}} + R I_{ext} - - Features exponential spike generation. - - **Parameters:** - - - ``size`` (int) - Number of neurons - - ``V_rest`` (Quantity[mV]) - Resting potential (default: -65 mV) - - ``V_th`` (Quantity[mV]) - Spike threshold (default: -50 mV) - - ``V_reset`` (Quantity[mV]) - Reset potential (default: -65 mV) - - ``tau`` (Quantity[ms]) - Membrane time constant (default: 10 ms) - - ``delta_T`` (Quantity[mV]) - Spike slope factor (default: 2 mV) - -AdExIF -~~~~~~ - -.. class:: AdExIF(size, V_rest=-65*u.mV, V_th=-50*u.mV, V_reset=-65*u.mV, tau=10*u.ms, tau_w=100*u.ms, delta_T=2*u.mV, a=0*u.nA, b=0.5*u.nA, **kwargs) - - Adaptive Exponential Integrate-and-Fire neuron. - - Combines exponential spike generation with adaptation. - - **Parameters:** - - Similar to ExpIF plus ALIF adaptation parameters (``tau_w``, ``a``, ``b``). - -Usage Patterns --------------- - -**Creating Neuron Populations:** - -.. code-block:: python - - # Single population - neurons = bp.LIF(1000, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - - # Multiple populations with different parameters - E_neurons = bp.LIF(800, tau=15*u.ms) # Excitatory: slower - I_neurons = bp.LIF(200, tau=10*u.ms) # Inhibitory: faster - -**Batched Simulation:** - -.. code-block:: python - - neuron = bp.LIF(100, ...) - brainstate.nn.init_all_states(neuron, batch_size=32) - - # Input shape: (32, 100) - inp = brainstate.random.rand(32, 100) * 2.0 * u.nA - neuron(inp) - - # Output shape: (32, 100) - spikes = neuron.get_spike() - -**Custom Neurons:** - -.. code-block:: python - - class CustomLIF(bp.Neuron): - def __init__(self, size, tau=10*u.ms): - super().__init__(size) - self.tau = tau - self.V = brainstate.ShortTermState(jnp.zeros(size)) - self.spike = brainstate.ShortTermState(jnp.zeros(size)) - - def reset_state(self, batch_size=None): - shape = self.size if batch_size is None else (batch_size, self.size) - self.V.value = jnp.zeros(shape) - self.spike.value = jnp.zeros(shape) - - def update(self, I): - # Custom dynamics - pass - - def get_spike(self): - return self.spike.value - -See Also --------- - -- :doc:`../core-concepts/neurons` - Detailed neuron model guide -- :doc:`../tutorials/basic/01-lif-neuron` - LIF neuron tutorial -- :doc:`../how-to-guides/custom-components` - Creating custom neurons -- :doc:`synapses` - Synaptic models -- :doc:`projections` - Connecting neurons + IF + LIF + LIFRef + ALIF \ No newline at end of file diff --git a/docs_state/api/projections.rst b/docs_state/api/projections.rst index 31a84382..7cc2aa6f 100644 --- a/docs_state/api/projections.rst +++ b/docs_state/api/projections.rst @@ -3,155 +3,19 @@ Projections Connect neural populations with the Comm-Syn-Out architecture. -.. currentmodule:: brainpy.state_based +.. currentmodule:: brainpy.state -Projection Classes ------------------- -AlignPostProj -~~~~~~~~~~~~~ -.. class:: AlignPostProj(comm, syn, out, post, **kwargs) +.. autosummary:: + :toctree: generated/ + :nosignatures: + :template: classtemplate.rst - Standard projection aligning synaptic states with postsynaptic neurons. + Projection + AlignPostProj + DeltaProj + CurrentProj + align_pre_projection + align_post_projection - **Parameters:** - - - ``comm`` - Communication layer (connectivity) - - ``syn`` - Synapse dynamics - - ``out`` - Output computation - - ``post`` - Postsynaptic neuron population - - **Example:** - - .. code-block:: python - - proj = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(100, 50, prob=0.1, weight=0.5*u.mS), - syn=bp.Expon.desc(50, tau=5*u.ms), - out=bp.COBA.desc(E=0*u.mV), - post=post_neurons - ) - - # Usage - pre_spikes = pre_neurons.get_spike() - proj(pre_spikes) - -AlignPreProj -~~~~~~~~~~~~ - -.. class:: AlignPreProj(comm, syn, out, post, **kwargs) - - Projection aligning synaptic states with presynaptic neurons. - - Used for certain learning rules that require presynaptic alignment. - -Communication Layers --------------------- - -From ``brainstate.nn``: - -EventFixedProb -~~~~~~~~~~~~~~ - -.. code-block:: python - - comm = brainstate.nn.EventFixedProb( - pre_size, - post_size, - prob=0.1, # Connection probability - weight=0.5*u.mS # Synaptic weight - ) - -Sparse connectivity with fixed connection probability. - -EventAll2All -~~~~~~~~~~~~ - -.. code-block:: python - - comm = brainstate.nn.EventAll2All( - pre_size, - post_size, - weight=0.5*u.mS - ) - -All-to-all connectivity (event-driven). - -EventOne2One -~~~~~~~~~~~~ - -.. code-block:: python - - comm = brainstate.nn.EventOne2One( - size, - weight=0.5*u.mS - ) - -One-to-one connections (same size populations). - -Linear -~~~~~~ - -.. code-block:: python - - comm = brainstate.nn.Linear( - in_size, - out_size, - w_init=brainstate.init.KaimingNormal() - ) - -Dense linear transformation (for small networks). - -Complete Examples ------------------ - -**E → E Excitatory:** - -.. code-block:: python - - E2E = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=0.02, weight=0.6*u.mS), - syn=bp.AMPA.desc(n_exc, tau=2*u.ms), - out=bp.COBA.desc(E=0*u.mV), - post=E_neurons - ) - -**I → E Inhibitory:** - -.. code-block:: python - - I2E = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(n_inh, n_exc, prob=0.02, weight=6.7*u.mS), - syn=bp.GABAa.desc(n_exc, tau=6*u.ms), - out=bp.COBA.desc(E=-80*u.mV), - post=E_neurons - ) - -**Multi-timescale (AMPA + NMDA):** - -.. code-block:: python - - # Fast AMPA - ampa_proj = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.3*u.mS), - syn=bp.AMPA.desc(n_post, tau=2*u.ms), - out=bp.COBA.desc(E=0*u.mV), - post=post_neurons - ) - - # Slow NMDA - nmda_proj = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.3*u.mS), - syn=bp.NMDA.desc(n_post, tau_decay=100*u.ms), - out=bp.MgBlock.desc(E=0*u.mV), - post=post_neurons - ) - -See Also --------- - -- :doc:`../core-concepts/projections` - Complete projection guide -- :doc:`../tutorials/basic/03-network-connections` - Network tutorial -- :doc:`neurons` - Neuron models -- :doc:`synapses` - Synapse models diff --git a/docs_state/api/synapses.rst b/docs_state/api/synapses.rst index 46a920cd..676e51a2 100644 --- a/docs_state/api/synapses.rst +++ b/docs_state/api/synapses.rst @@ -3,350 +3,18 @@ Synapse Models Synaptic dynamics models in BrainPy. -.. currentmodule:: brainpy.state_based +.. currentmodule:: brainpy.state -Base Class ----------- -Synapse -~~~~~~~ -.. class:: Synapse(size, **kwargs) +.. autosummary:: + :toctree: generated/ + :nosignatures: + :template: classtemplate.rst - Base class for all synapse models. + Expon + DualExpon + Alpha + AMPA + GABAa - **Parameters:** - - - ``size`` (int) - Number of post-synaptic neurons - - ``**kwargs`` - Additional keyword arguments - - **Key Methods:** - - .. method:: update(x) - - Update synaptic dynamics. - - :param x: Pre-synaptic input (typically spike indicator) - :returns: Synaptic conductance/current - - .. method:: reset_state(batch_size=None) - - Reset synaptic state. - - **Descriptor Pattern:** - - Synapses use the ``.desc()`` class method for use in projections: - - .. code-block:: python - - syn = bp.Expon.desc(size=100, tau=5*u.ms) - -Simple Synapses ---------------- - -Delta -~~~~~ - -.. class:: Delta - - Instantaneous synaptic transmission (no dynamics). - - .. math:: - - g(t) = \\sum_k \\delta(t - t_k) - - **Usage:** - - .. code-block:: python - - syn = bp.Delta.desc(100) - -Expon -~~~~~ - -.. class:: Expon - - Exponential synapse (single time constant). - - .. math:: - - \\tau \\frac{dg}{dt} = -g + \\sum_k \\delta(t - t_k) - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Time constant (default: 5 ms) - - **Example:** - - .. code-block:: python - - syn = bp.Expon.desc(size=100, tau=5*u.ms) - -Alpha -~~~~~ - -.. class:: Alpha - - Alpha function synapse (rise + decay). - - .. math:: - - \\tau \\frac{dg}{dt} &= -g + h \\\\ - \\tau \\frac{dh}{dt} &= -h + \\sum_k \\delta(t - t_k) - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Characteristic time (default: 10 ms) - - **Example:** - - .. code-block:: python - - syn = bp.Alpha.desc(size=100, tau=10*u.ms) - -DualExponential -~~~~~~~~~~~~~~~ - -.. class:: DualExponential - - Biexponential synapse with separate rise/decay. - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau_rise`` (Quantity[ms]) - Rise time constant - - ``tau_decay`` (Quantity[ms]) - Decay time constant - -Receptor Models ---------------- - -AMPA -~~~~ - -.. class:: AMPA - - AMPA receptor (fast excitatory). - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Time constant (default: 2 ms) - - **Example:** - - .. code-block:: python - - syn = bp.AMPA.desc(size=100, tau=2*u.ms) - -NMDA -~~~~ - -.. class:: NMDA - - NMDA receptor (slow excitatory, voltage-dependent). - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau_rise`` (Quantity[ms]) - Rise time (default: 2 ms) - - ``tau_decay`` (Quantity[ms]) - Decay time (default: 100 ms) - - ``a`` (Quantity[1/mM]) - Mg²⁺ sensitivity (default: 0.5/mM) - - ``cc_Mg`` (Quantity[mM]) - Mg²⁺ concentration (default: 1.2 mM) - - **Example:** - - .. code-block:: python - - syn = bp.NMDA.desc( - size=100, - tau_rise=2*u.ms, - tau_decay=100*u.ms - ) - -GABAa -~~~~~ - -.. class:: GABAa - - GABA_A receptor (fast inhibitory). - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Time constant (default: 6 ms) - - **Example:** - - .. code-block:: python - - syn = bp.GABAa.desc(size=100, tau=6*u.ms) - -GABAb -~~~~~ - -.. class:: GABAb - - GABA_B receptor (slow inhibitory). - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau_rise`` (Quantity[ms]) - Rise time (default: 3.5 ms) - - ``tau_decay`` (Quantity[ms]) - Decay time (default: 150 ms) - -Short-Term Plasticity ---------------------- - -STD -~~~ - -.. class:: STD - - Short-term depression. - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Synaptic time constant - - ``tau_d`` (Quantity[ms]) - Depression recovery time - - ``U`` (float) - Utilization fraction (0-1) - -STF -~~~ - -.. class:: STF - - Short-term facilitation. - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Synaptic time constant - - ``tau_f`` (Quantity[ms]) - Facilitation time constant - - ``U`` (float) - Baseline utilization - -STP -~~~ - -.. class:: STP - - Combined short-term plasticity (depression + facilitation). - - **Parameters:** - - - ``size`` (int) - Population size - - ``tau`` (Quantity[ms]) - Synaptic time constant - - ``tau_d`` (Quantity[ms]) - Depression time constant - - ``tau_f`` (Quantity[ms]) - Facilitation time constant - - ``U`` (float) - Baseline utilization - -Output Models -------------- - -CUBA -~~~~ - -.. class:: CUBA - - Current-based synaptic output. - - .. math:: - - I_{syn} = g_{syn} - - **Usage:** - - .. code-block:: python - - out = bp.CUBA.desc() - -COBA -~~~~ - -.. class:: COBA - - Conductance-based synaptic output. - - .. math:: - - I_{syn} = g_{syn} (E_{syn} - V_{post}) - - **Parameters:** - - - ``E`` (Quantity[mV]) - Reversal potential - - **Example:** - - .. code-block:: python - - # Excitatory - out_exc = bp.COBA.desc(E=0*u.mV) - - # Inhibitory - out_inh = bp.COBA.desc(E=-80*u.mV) - -MgBlock -~~~~~~~ - -.. class:: MgBlock - - Voltage-dependent magnesium block (for NMDA). - - **Parameters:** - - - ``E`` (Quantity[mV]) - Reversal potential - - ``cc_Mg`` (Quantity[mM]) - Mg²⁺ concentration - - ``alpha`` (Quantity[1/mV]) - Voltage sensitivity - - ``beta`` (float) - Voltage offset - -Usage in Projections ---------------------- - -**Standard pattern:** - -.. code-block:: python - - proj = bp.AlignPostProj( - comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.5*u.mS), - syn=bp.Expon.desc(n_post, tau=5*u.ms), # Synapse - out=bp.COBA.desc(E=0*u.mV), # Output - post=post_neurons - ) - -**Receptor-specific:** - -.. code-block:: python - - # Fast excitation (AMPA) - ampa_proj = bp.AlignPostProj( - comm=..., - syn=bp.AMPA.desc(n_post, tau=2*u.ms), - out=bp.COBA.desc(E=0*u.mV), - post=post_neurons - ) - - # Slow excitation (NMDA) - nmda_proj = bp.AlignPostProj( - comm=..., - syn=bp.NMDA.desc(n_post, tau_decay=100*u.ms), - out=bp.MgBlock.desc(E=0*u.mV), - post=post_neurons - ) - - # Fast inhibition (GABA_A) - gaba_proj = bp.AlignPostProj( - comm=..., - syn=bp.GABAa.desc(n_post, tau=6*u.ms), - out=bp.COBA.desc(E=-80*u.mV), - post=post_neurons - ) - -See Also --------- - -- :doc:`../core-concepts/synapses` - Detailed synapse guide -- :doc:`../tutorials/basic/02-synapse-models` - Synapse tutorial -- :doc:`../tutorials/advanced/06-synaptic-plasticity` - Plasticity tutorial -- :doc:`projections` - Projection API diff --git a/docs_state/core-concepts/architecture.rst b/docs_state/core-concepts/architecture.rst index 9b6f8108..4b6df834 100644 --- a/docs_state/core-concepts/architecture.rst +++ b/docs_state/core-concepts/architecture.rst @@ -1,12 +1,12 @@ Architecture Overview ==================== -BrainPy 3.0 represents a complete architectural redesign built on top of the ``brainstate`` framework. This document explains the design principles and architectural components that make BrainPy 3.0 powerful and flexible. +``brainpy.state`` represents a complete architectural redesign built on top of the ``brainstate`` framework. This document explains the design principles and architectural components that make BrainPy 3.0 powerful and flexible. Design Philosophy ----------------- -BrainPy 3.0 is built around several core principles: +``brainpy.state`` is built around several core principles: **State-Based Programming** All dynamical variables are managed as explicit states, enabling automatic differentiation, efficient compilation, and clear data flow. @@ -81,7 +81,7 @@ State Management System The Foundation: brainstate.State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Everything in BrainPy 3.0 revolves around **states**: +Everything in ``brainpy.state`` revolves around **states**: .. code-block:: python @@ -286,15 +286,15 @@ Projections connect populations using a three-stage architecture: .. code-block:: python - out = brainpy.CUBA.desc() # Current-based + out = brainpy.state.CUBA.desc() # Current-based # or - out = brainpy.COBA.desc() # Conductance-based + out = brainpy.state.COBA.desc() # Conductance-based **Complete Projection** .. code-block:: python - projection = brainpy.AlignPostProj( + projection = brainpy.state.AlignPostProj( comm=comm, syn=syn, out=out, @@ -340,7 +340,7 @@ Functions are compiled for performance: .. code-block:: python - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(input): return network.update(input) @@ -384,7 +384,7 @@ Physical Units System Integration with brainunit ~~~~~~~~~~~~~~~~~~~~~~~~~~ -BrainPy 3.0 integrates ``brainunit`` for scientific accuracy: +``brainpy.state`` integrates ``brainunit`` for scientific accuracy: .. code-block:: python @@ -396,7 +396,7 @@ BrainPy 3.0 integrates ``brainunit`` for scientific accuracy: current = 5 * u.nA # Units are checked automatically - neuron = brainpy.LIF(100, tau=tau, V_th=threshold) + neuron = brainpy.state.LIF(100, tau=tau, V_th=threshold) Benefits: @@ -424,7 +424,7 @@ Unit Operations Ecosystem Integration --------------------- -BrainPy 3.0 integrates tightly with its ecosystem: +``brainpy.state`` integrates tightly with its ecosystem: braintools ~~~~~~~~~~ @@ -474,7 +474,7 @@ Core framework (used automatically): class Net(brainstate.nn.Module): ... # Compilation - @brainstate.compile.jit + @brainstate.transform.jit def fn(): ... # Transformations @@ -483,7 +483,7 @@ Core framework (used automatically): Data Flow Example ----------------- -Here's how data flows through a typical BrainPy 3.0 simulation: +Here's how data flows through a typical ``brainpy.state`` simulation: .. code-block:: python @@ -491,12 +491,12 @@ Here's how data flows through a typical BrainPy 3.0 simulation: class EINetwork(brainstate.nn.Module): def __init__(self): super().__init__() - self.E = brainpy.LIF(800) # States: V, spike - self.I = brainpy.LIF(200) # States: V, spike - self.E2E = brainpy.AlignPostProj(...) # States: g (in synapse) - self.E2I = brainpy.AlignPostProj(...) - self.I2E = brainpy.AlignPostProj(...) - self.I2I = brainpy.AlignPostProj(...) + self.E = brainpy.state.LIF(800) # States: V, spike + self.I = brainpy.state.LIF(200) # States: V, spike + self.E2E = brainpy.state.AlignPostProj(...) # States: g (in synapse) + self.E2I = brainpy.state.AlignPostProj(...) + self.I2E = brainpy.state.AlignPostProj(...) + self.I2I = brainpy.state.AlignPostProj(...) def update(self, input): # Get spikes from last time step @@ -520,7 +520,7 @@ Here's how data flows through a typical BrainPy 3.0 simulation: brainstate.nn.init_all_states(net) # 3. Compile - @brainstate.compile.jit + @brainstate.transform.jit def step(input): return net.update(input) @@ -584,7 +584,7 @@ Hardware Acceleration Summary ------- -BrainPy 3.0's architecture provides: +``brainpy.state`` 's architecture provides: ✅ **Clear Abstractions**: Neurons, synapses, and projections with well-defined roles diff --git a/docs_state/core-concepts/neurons.rst b/docs_state/core-concepts/neurons.rst index 952f3492..9aa84460 100644 --- a/docs_state/core-concepts/neurons.rst +++ b/docs_state/core-concepts/neurons.rst @@ -1,12 +1,12 @@ Neurons ======= -Neurons are the fundamental computational units in BrainPy 3.0. This document explains how neurons work, what models are available, and how to use and create them. +Neurons are the fundamental computational units in ``brainpy.state``. This document explains how neurons work, what models are available, and how to use and create them. Overview -------- -In BrainPy 3.0, neurons model the dynamics of neural populations. Each neuron model: +In ``brainpy.state``, neurons model the dynamics of neural populations. Each neuron model: - Maintains **membrane potential** (voltage) - Integrates **input currents** @@ -27,7 +27,7 @@ Creating Neurons import brainunit as u # Create a population of 100 LIF neurons - neurons = brainpy.LIF( + neurons = brainpy.state.LIF( size=100, V_rest=-65. * u.mV, V_th=-50. * u.mV, @@ -85,7 +85,7 @@ The simplest spiking neuron model. .. code-block:: python - neuron = brainpy.IF( + neuron = brainpy.state.IF( size=100, V_rest=0. * u.mV, V_th=1. * u.mV, @@ -126,7 +126,7 @@ The most commonly used spiking neuron model. .. code-block:: python - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=100, V_rest=-65. * u.mV, V_th=-50. * u.mV, @@ -171,7 +171,7 @@ Same as LIF, but after spiking: .. code-block:: python - neuron = brainpy.LIFRef( + neuron = brainpy.state.LIFRef( size=100, V_rest=-65. * u.mV, V_th=-50. * u.mV, @@ -216,7 +216,7 @@ When spike occurs: :math:`w \\leftarrow w + \\beta` .. code-block:: python - neuron = brainpy.ALIF( + neuron = brainpy.state.ALIF( size=100, V_rest=-65. * u.mV, V_th=-50. * u.mV, @@ -260,7 +260,7 @@ Subtract threshold from membrane potential: .. code-block:: python - neuron = brainpy.LIF(..., spk_reset='soft') + neuron = brainpy.state.LIF(..., spk_reset='soft') **Properties:** @@ -279,7 +279,7 @@ Reset to fixed potential: .. code-block:: python - neuron = brainpy.LIF(..., spk_reset='hard') + neuron = brainpy.state.LIF(..., spk_reset='hard') **Properties:** @@ -302,7 +302,7 @@ For training spiking neural networks, use surrogate gradients: import braintools - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=100, ..., spk_fun=braintools.surrogate.ReluGrad() @@ -330,19 +330,19 @@ Different ways to initialize membrane potential: import braintools # Constant initialization - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=100, V_initializer=braintools.init.Constant(-65., unit=u.mV) ) # Normal distribution - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=100, V_initializer=braintools.init.Normal(-65., 5., unit=u.mV) ) # Uniform distribution - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=100, V_initializer=braintools.init.Uniform(-70., -60., unit=u.mV) ) @@ -385,7 +385,7 @@ Here's a complete example simulating a LIF neuron: .. code-block:: python - import brainpy as bp + import brainpy import brainstate import brainunit as u import matplotlib.pyplot as plt @@ -394,7 +394,7 @@ Here's a complete example simulating a LIF neuron: brainstate.environ.set(dt=0.1 * u.ms) # Create neuron - neuron = brainpy.LIF( + neuron = brainpy.state.LIF( size=1, V_rest=-65. * u.mV, V_th=-50. * u.mV, @@ -447,7 +447,7 @@ You can create custom neuron models by inheriting from ``Neuron``: .. code-block:: python import brainstate - from brainpy._base import Neuron + from brainpy.state import Neuron class MyNeuron(Neuron): def __init__(self, size, tau, V_th, **kwargs): @@ -503,7 +503,7 @@ Performance Tips .. code-block:: python - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(input): neuron(input) return neuron.V.value @@ -538,7 +538,7 @@ Neurons encoding information in firing rate: .. code-block:: python - neuron = brainpy.LIF(100, tau=10*u.ms, spk_reset='soft') + neuron = brainpy.state.LIF(100, tau=10*u.ms, spk_reset='soft') # Use soft reset for higher firing rates Temporal Coding @@ -548,7 +548,7 @@ Neurons encoding information in spike timing: .. code-block:: python - neuron = brainpy.LIFRef( + neuron = brainpy.state.LIFRef( 100, tau=10*u.ms, tau_ref=2*u.ms, @@ -563,7 +563,7 @@ Neurons with bursting behavior: .. code-block:: python - neuron = brainpy.ALIF( + neuron = brainpy.state.ALIF( 100, tau=10*u.ms, tau_w=200*u.ms, @@ -575,7 +575,7 @@ Neurons with bursting behavior: Summary ------- -Neurons in BrainPy 3.0: +Neurons in ``brainpy.state``: ✅ **Multiple models**: IF, LIF, LIFRef, ALIF diff --git a/docs_state/core-concepts/projections.rst b/docs_state/core-concepts/projections.rst index a367da04..c68960f3 100644 --- a/docs_state/core-concepts/projections.rst +++ b/docs_state/core-concepts/projections.rst @@ -1,9 +1,11 @@ Projections: Connecting Neural Populations ========================================== -Projections are BrainPy's mechanism for connecting neural populations. They implement the **Communication-Synapse-Output (Comm-Syn-Out)** architecture, which separates connectivity, synaptic dynamics, and output computation into modular components. +Projections are ``brainpy.state`` 's mechanism for connecting neural populations. +They implement the **Communication-Synapse-Output (Comm-Syn-Out)** architecture, +which separates connectivity, synaptic dynamics, and output computation into modular components. -This guide provides a comprehensive understanding of projections in BrainPy 3.0. +This guide provides a comprehensive understanding of projections in ``brainpy.state``. .. contents:: Table of Contents :local: @@ -78,7 +80,7 @@ All neurons potentially connected (though weights may be zero). .. code-block:: python - import brainpy as bp + import brainpy import brainstate import brainunit as u @@ -207,7 +209,7 @@ Single exponential decay (most common). .. code-block:: python # Exponential synapse with 5ms time constant - syn = bp.Expon.desc( + syn = brainpy.state.Expon.desc( size=100, # Postsynaptic population size tau=5.0 * u.ms # Decay time constant ) @@ -238,7 +240,7 @@ Dual exponential with rise and decay. .. code-block:: python # Alpha synapse - syn = bp.Alpha.desc( + syn = brainpy.state.Alpha.desc( size=100, tau=10.0 * u.ms # Characteristic time ) @@ -267,7 +269,7 @@ Voltage-dependent NMDA receptors. .. code-block:: python # NMDA receptor - syn = bp.NMDA.desc( + syn = brainpy.state.NMDA.desc( size=100, tau_decay=100.0 * u.ms, # Slow decay tau_rise=2.0 * u.ms, # Fast rise @@ -291,7 +293,7 @@ Fast glutamatergic transmission. .. code-block:: python # AMPA receptor (fast excitation) - syn = bp.AMPA.desc( + syn = brainpy.state.AMPA.desc( size=100, tau=2.0 * u.ms # Fast decay (~2ms) ) @@ -308,7 +310,7 @@ Inhibitory transmission. .. code-block:: python # GABAa receptor (fast inhibition) - syn = bp.GABAa.desc( + syn = brainpy.state.GABAa.desc( size=100, tau=6.0 * u.ms # ~6ms decay ) @@ -318,7 +320,7 @@ Inhibitory transmission. .. code-block:: python # GABAb receptor (slow inhibition) - syn = bp.GABAb.desc( + syn = brainpy.state.GABAb.desc( size=100, tau_decay=150.0 * u.ms, # Very slow tau_rise=3.5 * u.ms @@ -335,7 +337,7 @@ Create custom synaptic dynamics by subclassing ``Synapse``. .. code-block:: python - class DoubleExpSynapse(bp.Synapse): + class DoubleExpSynapse(brainpy.state.Synapse): """Custom synapse with two time constants.""" def __init__(self, size, tau_fast=2*u.ms, tau_slow=10*u.ms, **kwargs): @@ -386,7 +388,7 @@ Synaptic conductance directly becomes current. .. code-block:: python # Current-based output - out = bp.CUBA.desc() + out = brainpy.state.CUBA.desc() **Characteristics:** @@ -415,10 +417,10 @@ Synaptic conductance with reversal potential. .. code-block:: python # Excitatory conductance-based - out_exc = bp.COBA.desc(E=0.0 * u.mV) + out_exc = brainpy.state.COBA.desc(E=0.0 * u.mV) # Inhibitory conductance-based - out_inh = bp.COBA.desc(E=-80.0 * u.mV) + out_inh = brainpy.state.COBA.desc(E=-80.0 * u.mV) **Characteristics:** @@ -439,7 +441,7 @@ Voltage-dependent magnesium block for NMDA. .. code-block:: python # NMDA with Mg²⁺ block - out_nmda = bp.MgBlock.desc( + out_nmda = brainpy.state.MgBlock.desc( E=0.0 * u.mV, cc_Mg=1.2 * u.mM, alpha=0.062 / u.mV, @@ -461,22 +463,22 @@ Example 1: Simple Feedforward import brainunit as u # Create populations - pre = bp.LIF(100, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - post = bp.LIF(50, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + pre = brainpy.state.LIF(100, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + post = brainpy.state.LIF(50, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # Create projection: 100 → 50 neurons - proj = bp.AlignPostProj( + proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb( pre_size=100, post_size=50, prob=0.1, # 10% connectivity weight=0.5 * u.mS ), - syn=bp.Expon.desc( + syn=brainpy.state.Expon.desc( size=50, # Postsynaptic size tau=5.0 * u.ms ), - out=bp.CUBA.desc(), + out=brainpy.state.CUBA.desc(), post=post # Postsynaptic population ) @@ -507,38 +509,38 @@ Example 2: Excitatory-Inhibitory Network super().__init__() # Populations - self.E = bp.LIF(n_exc, V_rest=-65*u.mV, V_th=-50*u.mV, tau=15*u.ms) - self.I = bp.LIF(n_inh, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.E = brainpy.state.LIF(n_exc, V_rest=-65*u.mV, V_th=-50*u.mV, tau=15*u.ms) + self.I = brainpy.state.LIF(n_inh, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # E → E projection (AMPA, excitatory) - self.E2E = bp.AlignPostProj( + self.E2E = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=0.02, weight=0.6*u.mS), - syn=bp.AMPA.desc(n_exc, tau=2.0*u.ms), - out=bp.COBA.desc(E=0.0*u.mV), + syn=brainpy.state.AMPA.desc(n_exc, tau=2.0*u.ms), + out=brainpy.state.COBA.desc(E=0.0*u.mV), post=self.E ) # E → I projection (AMPA, excitatory) - self.E2I = bp.AlignPostProj( + self.E2I = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_exc, n_inh, prob=0.02, weight=0.6*u.mS), - syn=bp.AMPA.desc(n_inh, tau=2.0*u.ms), - out=bp.COBA.desc(E=0.0*u.mV), + syn=brainpy.state.AMPA.desc(n_inh, tau=2.0*u.ms), + out=brainpy.state.COBA.desc(E=0.0*u.mV), post=self.I ) # I → E projection (GABAa, inhibitory) - self.I2E = bp.AlignPostProj( + self.I2E = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_inh, n_exc, prob=0.02, weight=6.7*u.mS), - syn=bp.GABAa.desc(n_exc, tau=6.0*u.ms), - out=bp.COBA.desc(E=-80.0*u.mV), + syn=brainpy.state.GABAa.desc(n_exc, tau=6.0*u.ms), + out=brainpy.state.COBA.desc(E=-80.0*u.mV), post=self.E ) # I → I projection (GABAa, inhibitory) - self.I2I = bp.AlignPostProj( + self.I2I = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_inh, n_inh, prob=0.02, weight=6.7*u.mS), - syn=bp.GABAa.desc(n_inh, tau=6.0*u.ms), - out=bp.COBA.desc(E=-80.0*u.mV), + syn=brainpy.state.GABAa.desc(n_inh, tau=6.0*u.ms), + out=brainpy.state.COBA.desc(E=-80.0*u.mV), post=self.I ) @@ -572,21 +574,21 @@ Combine AMPA (fast) and NMDA (slow) for realistic excitation. def __init__(self, n_pre=100, n_post=100): super().__init__() - self.post = bp.LIF(n_post, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.post = brainpy.state.LIF(n_post, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # Fast AMPA component - self.ampa_proj = bp.AlignPostProj( + self.ampa_proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.3*u.mS), - syn=bp.AMPA.desc(n_post, tau=2.0*u.ms), - out=bp.COBA.desc(E=0.0*u.mV), + syn=brainpy.state.AMPA.desc(n_post, tau=2.0*u.ms), + out=brainpy.state.COBA.desc(E=0.0*u.mV), post=self.post ) # Slow NMDA component - self.nmda_proj = bp.AlignPostProj( + self.nmda_proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.3*u.mS), - syn=bp.NMDA.desc(n_post, tau_decay=100.0*u.ms, tau_rise=2.0*u.ms), - out=bp.MgBlock.desc(E=0.0*u.mV, cc_Mg=1.2*u.mM), + syn=brainpy.state.NMDA.desc(n_post, tau_decay=100.0*u.ms, tau_rise=2.0*u.ms), + out=brainpy.state.MgBlock.desc(E=0.0*u.mV, cc_Mg=1.2*u.mM), post=self.post ) @@ -611,10 +613,10 @@ Add synaptic delays to projections. .. code-block:: python # Projection with 5ms synaptic delay - proj_delayed = bp.AlignPostProj( + proj_delayed = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(100, 100, prob=0.1, weight=0.5*u.mS), - syn=bp.Expon.desc(100, tau=5.0*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(100, tau=5.0*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons, delay=5.0 * u.ms # Synaptic delay ) @@ -662,10 +664,10 @@ Combine with plasticity (see :doc:`../tutorials/advanced/06-synaptic-plasticity` jnp.ones((n_pre, n_post)) * 0.5 * u.mS ) - self.proj = bp.AlignPostProj( + self.proj = brainpy.state.AlignPostProj( comm=CustomComm(self.weights), # Use learnable weights - syn=bp.Expon.desc(n_post, tau=5.0*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(n_post, tau=5.0*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons ) @@ -730,7 +732,7 @@ Performance Tips 1. **Sparse over Dense:** Use sparse connectivity for large networks 2. **Batch initialization:** Initialize all modules together -3. **JIT compile:** Wrap simulation loop with ``@brainstate.compile.jit`` +3. **JIT compile:** Wrap simulation loop with ``@brainstate.transform.jit`` 4. **Appropriate precision:** Use float32 unless high precision needed 5. **Minimize communication:** Group projections with same connectivity @@ -744,8 +746,8 @@ Neurons are either excitatory OR inhibitory (not both). .. code-block:: python # Separate excitatory and inhibitory populations - E = bp.LIF(800, ...) # Excitatory - I = bp.LIF(200, ...) # Inhibitory + E = brainpy.state.LIF(800, ...) # Excitatory + I = brainpy.state.LIF(200, ...) # Inhibitory # E always excitatory (E=0mV) # I always inhibitory (E=-80mV) @@ -771,10 +773,10 @@ Self-connections for persistent activity. .. code-block:: python # Excitatory recurrence (working memory) - E2E = bp.AlignPostProj( + E2E = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=0.02, weight=0.5*u.mS), - syn=bp.Expon.desc(n_exc, tau=5*u.ms), - out=bp.COBA.desc(E=0*u.mV), + syn=brainpy.state.Expon.desc(n_exc, tau=5*u.ms), + out=brainpy.state.COBA.desc(E=0*u.mV), post=E ) @@ -823,8 +825,8 @@ Issue: Network silent or exploding w_inh = 5.0 * u.mS # Strong inhibition # Proper reversal potentials - out_exc = bp.COBA.desc(E=0.0 * u.mV) - out_inh = bp.COBA.desc(E=-80.0 * u.mV) + out_exc = brainpy.state.COBA.desc(E=0.0 * u.mV) + out_inh = brainpy.state.COBA.desc(E=-80.0 * u.mV) Issue: Slow simulation ~~~~~~~~~~~~~~~~~~~~~~ @@ -839,7 +841,7 @@ Issue: Slow simulation .. code-block:: python # Fast configuration - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(net, inp): return net(inp) @@ -879,10 +881,10 @@ Summary .. code-block:: python # Standard projection template - proj = bp.AlignPostProj( + proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_pre, n_post, prob=0.1, weight=0.5*u.mS), - syn=bp.Expon.desc(n_post, tau=5.0*u.ms), - out=bp.COBA.desc(E=0.0*u.mV), + syn=brainpy.state.Expon.desc(n_post, tau=5.0*u.ms), + out=brainpy.state.COBA.desc(E=0.0*u.mV), post=post_neurons ) diff --git a/docs_state/core-concepts/state-management.rst b/docs_state/core-concepts/state-management.rst index 32385351..7583189a 100644 --- a/docs_state/core-concepts/state-management.rst +++ b/docs_state/core-concepts/state-management.rst @@ -1,7 +1,9 @@ -State Management: The Foundation of BrainPy 3.0 -=============================================== +State Management: The Foundation of ``brainpy.state`` +===================================================== -State management is the core architectural change in BrainPy 3.0. Understanding states is essential for using BrainPy effectively. This guide provides comprehensive coverage of the state system built on ``brainstate``. +State management is the core architectural change in ``brainpy.state``. Understanding states is +essential for using BrainPy effectively. This guide provides comprehensive coverage of the state +system built on ``brainstate``. .. contents:: Table of Contents :local: @@ -21,7 +23,7 @@ What is State? - Learnable weights - Temporary buffers -**Key insight:** BrainPy 3.0 makes states **explicit** rather than implicit. Every stateful variable is declared and tracked. +**Key insight:** ``brainpy.state`` makes states **explicit** rather than implicit. Every stateful variable is declared and tracked. Why Explicit State Management? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -33,7 +35,7 @@ Why Explicit State Management? - Unclear initialization procedures - Conflicts with JAX functional programming -**Benefits of explicit state (BrainPy 3.0):** +**Benefits of explicit state (``brainpy.state``):** ✅ Clear variable lifecycle @@ -308,11 +310,11 @@ For custom initialization, override ``reset_state()``. Initializers for Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use ``brainstate.init`` for parameter initialization. +Use ``braintools.init`` for parameter initialization. .. code-block:: python - import brainstate.init as init + import braintools.init as init class Network(brainstate.nn.Module): def __init__(self, in_size, out_size): diff --git a/docs_state/core-concepts/synapses.rst b/docs_state/core-concepts/synapses.rst index 9f36d4d2..378a9880 100644 --- a/docs_state/core-concepts/synapses.rst +++ b/docs_state/core-concepts/synapses.rst @@ -1,7 +1,8 @@ Synapses ======== -Synapses model the temporal dynamics of neural connections in BrainPy 3.0. This document explains how synapses work, what models are available, and how to use them effectively. +Synapses model the temporal dynamics of neural connections in ``brainpy.state``. This document explains +how synapses work, what models are available, and how to use them effectively. Overview -------- @@ -34,13 +35,13 @@ Synapses are typically created as part of projections: import brainunit as u # Create synapse descriptor - syn = brainpy.Expon.desc( + syn = brainpy.state.Expon.desc( size=100, # Number of synapses tau=5. * u.ms # Time constant ) # Use in projection - projection = brainpy.AlignPostProj( + projection = brainpy.state.AlignPostProj( comm=..., syn=syn, # Synapse here out=..., @@ -89,7 +90,7 @@ When spike arrives: :math:`g \\leftarrow g + 1` .. code-block:: python - syn = brainpy.Expon.desc( + syn = brainpy.state.Expon.desc( size=100, tau=5. * u.ms, g_initializer=braintools.init.Constant(0. * u.mS) @@ -146,7 +147,7 @@ When spike arrives: :math:`h \\leftarrow h + 1` .. code-block:: python - syn = brainpy.Alpha.desc( + syn = brainpy.state.Alpha.desc( size=100, tau=5. * u.ms, g_initializer=braintools.init.Constant(0. * u.mS) @@ -189,7 +190,7 @@ Similar to Alpha, but with parameters tuned for AMPA receptors. .. code-block:: python - syn = brainpy.AMPA.desc( + syn = brainpy.state.AMPA.desc( size=100, tau=2. * u.ms, # Fast AMPA kinetics g_initializer=braintools.init.Constant(0. * u.mS) @@ -220,7 +221,7 @@ Similar to Alpha, but with parameters tuned for GABAa receptors. .. code-block:: python - syn = brainpy.GABAa.desc( + syn = brainpy.state.GABAa.desc( size=100, tau=10. * u.ms, # Slower GABAa kinetics g_initializer=braintools.init.Constant(0. * u.mS) @@ -249,10 +250,10 @@ BrainPy synapses use a descriptor pattern: .. code-block:: python # Create descriptor (not yet instantiated) - syn_desc = brainpy.Expon.desc(size=100, tau=5*u.ms) + syn_desc = brainpy.state.Expon.desc(size=100, tau=5*u.ms) # Instantiated within projection - projection = brainpy.AlignPostProj(..., syn=syn_desc, ...) + projection = brainpy.state.AlignPostProj(..., syn=syn_desc, ...) # Access instantiated synapse actual_synapse = projection.syn @@ -271,9 +272,9 @@ Accessing Synaptic State .. code-block:: python # Within projection - projection = brainpy.AlignPostProj( + projection = brainpy.state.AlignPostProj( comm=..., - syn=brainpy.Expon.desc(100, tau=5*u.ms), + syn=brainpy.state.Expon.desc(100, tau=5*u.ms), out=..., post=neurons ) @@ -301,10 +302,10 @@ Comparing Different Models brainstate.environ.set(dt=0.1 * u.ms) # Create different synapses - expon = brainpy.Expon(100, tau=5*u.ms) - alpha = brainpy.Alpha(100, tau=5*u.ms) - ampa = brainpy.AMPA(100, tau=2*u.ms) - gaba = brainpy.GABAa(100, tau=10*u.ms) + expon = brainpy.state.Expon(100, tau=5*u.ms) + alpha = brainpy.state.Alpha(100, tau=5*u.ms) + ampa = brainpy.state.AMPA(100, tau=2*u.ms) + gaba = brainpy.state.GABAa(100, tau=10*u.ms) # Initialize for syn in [expon, alpha, ampa, gaba]: @@ -361,16 +362,16 @@ Complete Example import brainunit as u # Create neurons - pre_neurons = brainpy.LIF(80, V_th=-50*u.mV, tau=10*u.ms) - post_neurons = brainpy.LIF(100, V_th=-50*u.mV, tau=10*u.ms) + pre_neurons = brainpy.state.LIF(80, V_th=-50*u.mV, tau=10*u.ms) + post_neurons = brainpy.state.LIF(100, V_th=-50*u.mV, tau=10*u.ms) # Create projection with exponential synapse - projection = brainpy.AlignPostProj( + projection = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb( 80, 100, prob=0.1, weight=0.5*u.mS ), - syn=brainpy.Expon.desc(100, tau=5*u.ms), - out=brainpy.CUBA.desc(), + syn=brainpy.state.Expon.desc(100, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons ) @@ -407,15 +408,15 @@ Synapses can be combined with short-term plasticity (STP): .. code-block:: python # Create projection with STP - projection = brainpy.AlignPostProj( + projection = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(80, 100, prob=0.1, weight=0.5*u.mS), - syn=brainpy.STP.desc( - brainpy.Expon.desc(100, tau=5*u.ms), # Underlying synapse + syn=brainpy.state.STP.desc( + brainpy.state.Expon.desc(100, tau=5*u.ms), # Underlying synapse tau_f=200*u.ms, # Facilitation time constant tau_d=150*u.ms, # Depression time constant U=0.2 # Utilization of synaptic efficacy ), - out=brainpy.CUBA.desc(), + out=brainpy.state.CUBA.desc(), post=post_neurons ) @@ -432,7 +433,7 @@ You can create custom synapse models by inheriting from ``Synapse``: .. code-block:: python import brainstate - from brainpy._base import Synapse + from brainpy.state import Synapse class MyCustomSynapse(Synapse): def __init__(self, size, tau1, tau2, **kwargs): @@ -475,7 +476,7 @@ Usage: ) # Use in projection - projection = brainpy.AlignPostProj(..., syn=syn_desc, ...) + projection = brainpy.state.AlignPostProj(..., syn=syn_desc, ...) Choosing the Right Synapse --------------------------- @@ -557,17 +558,17 @@ Optimization Tips .. code-block:: python # Good: Single projection with 1000 synapses - proj = brainpy.AlignPostProj(..., syn=brainpy.Expon.desc(1000, ...)) + proj = brainpy.state.AlignPostProj(..., syn=brainpy.state.Expon.desc(1000, ...)) # Bad: 1000 separate projections - projs = [brainpy.AlignPostProj(..., syn=brainpy.Expon.desc(1, ...)) + projs = [brainpy.state.AlignPostProj(..., syn=brainpy.state.Expon.desc(1, ...)) for _ in range(1000)] 3. **JIT compilation**: Always use for simulations .. code-block:: python - @brainstate.compile.jit + @brainstate.transform.jit def step(): projection(spikes) neurons(0*u.nA) @@ -581,18 +582,18 @@ Excitatory-Inhibitory Balance .. code-block:: python # Excitatory projection (fast) - E_proj = brainpy.AlignPostProj( + E_proj = brainpy.state.AlignPostProj( comm=..., - syn=brainpy.Expon.desc(post_size, tau=2*u.ms), - out=brainpy.CUBA.desc(), + syn=brainpy.state.Expon.desc(post_size, tau=2*u.ms), + out=brainpy.state.CUBA.desc(), post=neurons ) # Inhibitory projection (slow) - I_proj = brainpy.AlignPostProj( + I_proj = brainpy.state.AlignPostProj( comm=..., - syn=brainpy.Expon.desc(post_size, tau=10*u.ms), - out=brainpy.CUBA.desc(), + syn=brainpy.state.Expon.desc(post_size, tau=10*u.ms), + out=brainpy.state.CUBA.desc(), post=neurons ) @@ -602,24 +603,24 @@ Multiple Receptor Types .. code-block:: python # AMPA (fast excitatory) - ampa_proj = brainpy.AlignPostProj( - ..., syn=brainpy.AMPA.desc(size, tau=2*u.ms), ... + ampa_proj = brainpy.state.AlignPostProj( + ..., syn=brainpy.state.AMPA.desc(size, tau=2*u.ms), ... ) # NMDA (slow excitatory) - custom - nmda_proj = brainpy.AlignPostProj( + nmda_proj = brainpy.state.AlignPostProj( ..., syn=CustomNMDA.desc(size, tau=100*u.ms), ... ) # GABAa (fast inhibitory) - gaba_proj = brainpy.AlignPostProj( - ..., syn=brainpy.GABAa.desc(size, tau=10*u.ms), ... + gaba_proj = brainpy.state.AlignPostProj( + ..., syn=brainpy.state.GABAa.desc(size, tau=10*u.ms), ... ) Summary ------- -Synapses in BrainPy 3.0: +Synapses in ``brainpy.state``: ✅ **Multiple models**: Expon, Alpha, AMPA, GABAa diff --git a/docs_state/examples/gallery.rst b/docs_state/examples/gallery.rst index 3affb2b7..3898f300 100644 --- a/docs_state/examples/gallery.rst +++ b/docs_state/examples/gallery.rst @@ -3,7 +3,7 @@ Examples Gallery Welcome to the BrainPy 3.0 examples gallery! Here you'll find complete, runnable examples demonstrating various aspects of computational neuroscience modeling. -All examples are available in the `examples_version3/ `_ directory of the BrainPy repository. +All examples are available in the `examples_state/ `_ directory of the BrainPy repository. Classical Network Models ------------------------- @@ -25,7 +25,7 @@ Implements the classic excitatory-inhibitory balanced network showing chaotic dy - Balanced excitation and inhibition - Asynchronous irregular firing -:download:`Download <../../examples_version3/102_EI_net_1996.py>` +:download:`Download <../../examples_state/102_EI_net_1996.py>` **Key Concepts**: E-I balance, network dynamics, sparse connectivity @@ -46,7 +46,7 @@ Conductance-based synaptic integration in balanced networks. - More biologically realistic - Stable asynchronous activity -:download:`Download <../../examples_version3/103_COBA_2005.py>` +:download:`Download <../../examples_state/103_COBA_2005.py>` **Key Concepts**: COBA synapses, conductance-based models, reversal potentials @@ -66,9 +66,9 @@ Current-based synaptic integration (simpler, faster variant). - Faster computation - Widely used for large-scale simulations -:download:`Download <../../examples_version3/104_CUBA_2005.py>` +:download:`Download <../../examples_state/104_CUBA_2005.py>` -**Alternative**: `104_CUBA_2005_version2.py <../../examples_version3/104_CUBA_2005_version2.py>`_ - Different parameterization +**Alternative**: `104_CUBA_2005_version2.py <../../examples_state/104_CUBA_2005_version2.py>`_ - Different parameterization **Key Concepts**: CUBA synapses, current-based models @@ -89,7 +89,7 @@ More detailed neuron model with sodium and potassium channels. - Biophysically detailed - Computationally intensive -:download:`Download <../../examples_version3/106_COBA_HH_2007.py>` +:download:`Download <../../examples_state/106_COBA_HH_2007.py>` **Key Concepts**: Hodgkin-Huxley model, ion channels, biophysical detail @@ -111,7 +111,7 @@ Interneuron network generating gamma oscillations (30-80 Hz). - Physiologically relevant frequency - Network oscillations -:download:`Download <../../examples_version3/107_gamma_oscillation_1996.py>` +:download:`Download <../../examples_state/107_gamma_oscillation_1996.py>` **Key Concepts**: Gamma oscillations, network synchrony, inhibitory networks @@ -132,7 +132,7 @@ Demonstrates reliable spike sequence propagation. - Wave propagation - Temporal coding -:download:`Download <../../examples_version3/108_synfire_chains_199.py>` +:download:`Download <../../examples_state/108_synfire_chains_199.py>` **Key Concepts**: Synfire chains, feedforward networks, spike timing @@ -153,7 +153,7 @@ High-frequency oscillations (>100 Hz) in inhibitory networks. - Inhibitory synchrony - Pathological rhythms -:download:`Download <../../examples_version3/109_fast_global_oscillation.py>` +:download:`Download <../../examples_state/109_fast_global_oscillation.py>` **Key Concepts**: Fast oscillations, gap junctions, pathological rhythms @@ -171,7 +171,7 @@ Series of models exploring different gamma generation mechanisms: - Asynchronous firing - No clear rhythm -:download:`Download <../../examples_version3/110_Susin_Destexhe_2021_gamma_oscillation_AI.py>` +:download:`Download <../../examples_state/110_Susin_Destexhe_2021_gamma_oscillation_AI.py>` --- @@ -184,7 +184,7 @@ Series of models exploring different gamma generation mechanisms: - High-frequency gamma - Interneuron synchrony -:download:`Download <../../examples_version3/111_Susin_Destexhe_2021_gamma_oscillation_CHING.py>` +:download:`Download <../../examples_state/111_Susin_Destexhe_2021_gamma_oscillation_CHING.py>` --- @@ -197,7 +197,7 @@ Series of models exploring different gamma generation mechanisms: - Gamma through inhibition - Fast synaptic kinetics -:download:`Download <../../examples_version3/112_Susin_Destexhe_2021_gamma_oscillation_ING.py>` +:download:`Download <../../examples_state/112_Susin_Destexhe_2021_gamma_oscillation_ING.py>` --- @@ -210,9 +210,9 @@ Series of models exploring different gamma generation mechanisms: - Most common mechanism - Excitatory-inhibitory interaction -:download:`Download <../../examples_version3/113_Susin_Destexhe_2021_gamma_oscillation_PING.py>` +:download:`Download <../../examples_state/113_Susin_Destexhe_2021_gamma_oscillation_PING.py>` -**Combined**: `Susin_Destexhe_2021_gamma_oscillation.py <../../examples_version3/Susin_Destexhe_2021_gamma_oscillation.py>`_ - All mechanisms +**Combined**: `Susin_Destexhe_2021_gamma_oscillation.py <../../examples_state/Susin_Destexhe_2021_gamma_oscillation.py>`_ - All mechanisms **Key Concepts**: Gamma mechanisms, network states, oscillation generation @@ -234,7 +234,7 @@ Trains a simple spiking network using surrogate gradients. - Simple classification task - Gradient-based learning -:download:`Download <../../examples_version3/200_surrogate_grad_lif.py>` +:download:`Download <../../examples_state/200_surrogate_grad_lif.py>` **Key Concepts**: Surrogate gradients, SNN training, backpropagation through time @@ -255,7 +255,7 @@ Trains a spiking network on Fashion-MNIST dataset. - Spike-based processing - Real-world classification -:download:`Download <../../examples_version3/201_surrogate_grad_lif_fashion_mnist.py>` +:download:`Download <../../examples_state/201_surrogate_grad_lif_fashion_mnist.py>` **Key Concepts**: Image classification, multi-layer SNNs, practical applications @@ -276,7 +276,7 @@ Uses readout layer for classification. - Spike counting - Classification from spike rates -:download:`Download <../../examples_version3/202_mnist_lif_readout.py>` +:download:`Download <../../examples_state/202_mnist_lif_readout.py>` **Key Concepts**: Readout layers, spike-based classification, MNIST @@ -336,14 +336,14 @@ All examples can be run directly: cd BrainPy # Run an example - python examples_version3/102_EI_net_1996.py + python examples_state/102_EI_net_1996.py Or in Jupyter: .. code-block:: python # In Jupyter notebook - %run examples_version3/102_EI_net_1996.py + %run examples_state/102_EI_net_1996.py Requirements ~~~~~~~~~~~~ @@ -397,7 +397,7 @@ Contributing Examples We welcome new examples! To contribute: 1. Fork the BrainPy repository -2. Add your example to ``examples_version3/`` +2. Add your example to ``examples_state/`` 3. Follow naming convention: ``NNN_descriptive_name.py`` 4. Include documentation at the top 5. Submit a pull request @@ -442,7 +442,7 @@ Browse All Examples View all examples on GitHub: -`BrainPy Examples (Version 3.0) `_ +`BrainPy Examples (Version 3.0) `_ For more extensive examples and notebooks: diff --git a/docs_state/how-to-guides/custom-components.rst b/docs_state/how-to-guides/custom-components.rst index c4a1297e..2f2adc6c 100644 --- a/docs_state/how-to-guides/custom-components.rst +++ b/docs_state/how-to-guides/custom-components.rst @@ -14,12 +14,12 @@ Quick Start .. code-block:: python - import brainpy as bp + import brainpy import brainstate import brainunit as u import jax.numpy as jnp - class CustomNeuron(bp.Neuron): + class CustomNeuron(brainpy.state.Neuron): def __init__(self, size, **kwargs): super().__init__(size, **kwargs) @@ -68,7 +68,7 @@ Example 1: Adaptive LIF .. code-block:: python - class AdaptiveLIF(bp.Neuron): + class AdaptiveLIF(brainpy.state.Neuron): """LIF neuron with adaptation current.""" def __init__(self, size, tau=10*u.ms, tau_w=100*u.ms, @@ -126,7 +126,7 @@ Example 2: Izhikevich Neuron .. code-block:: python - class Izhikevich(bp.Neuron): + class Izhikevich(brainpy.state.Neuron): """Izhikevich neuron model.""" def __init__(self, size, a=0.02, b=0.2, c=-65*u.mV, d=8*u.mV, **kwargs): @@ -176,7 +176,7 @@ Example: Biexponential Synapse .. code-block:: python - class BiexponentialSynapse(bp.Synapse): + class BiexponentialSynapse(brainpy.state.Synapse): """Synapse with separate rise and decay.""" def __init__(self, size, tau_rise=1*u.ms, tau_decay=5*u.ms, **kwargs): @@ -211,7 +211,7 @@ Example: NMDA Synapse .. code-block:: python - class NMDASynapse(bp.Synapse): + class NMDASynapse(brainpy.state.Synapse): """NMDA receptor with voltage dependence.""" def __init__(self, size, tau=100*u.ms, a=0.5/u.mM, Mg=1.0*u.mM, **kwargs): @@ -314,7 +314,7 @@ Example: Liquid State Machine ) # Reservoir (fixed random recurrent network) - self.reservoir = bp.LIF(n_reservoir, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.reservoir = brainpy.state.LIF(n_reservoir, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # Fixed random recurrent weights w_reservoir = brainstate.random.randn(n_reservoir, n_reservoir) * 0.01 @@ -322,7 +322,7 @@ Example: Liquid State Machine self.reservoir_weights = w_reservoir * mask # Not a ParamState (fixed) # Readout (trainable) - self.readout = bp.Readout(n_reservoir, n_output) + self.readout = brainpy.state.Readout(n_reservoir, n_output) def update(self, x): # Input to reservoir @@ -384,8 +384,8 @@ Best Practices -------------- ✅ **Inherit from base classes** - - ``bp.Neuron`` for neurons - - ``bp.Synapse`` for synapses + - ``brainpy.state.Neuron`` for neurons + - ``brainpy.state.Synapse`` for synapses - ``brainstate.nn.Module`` for general components ✅ **Use ShortTermState for dynamics** @@ -449,11 +449,11 @@ Complete Example .. code-block:: python # Custom components - class MyNeuron(bp.Neuron): + class MyNeuron(brainpy.state.Neuron): # ... (see examples above) pass - class MySynapse(bp.Synapse): + class MySynapse(brainpy.state.Synapse): # ... (see examples above) pass @@ -465,10 +465,10 @@ Complete Example self.pre = MyNeuron(size=100) self.post = MyNeuron(size=50) - self.projection = bp.AlignPostProj( + self.projection = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(100, 50, prob=0.1, weight=0.5*u.mS), syn=MySynapse.desc(50), # Use custom synapse - out=bp.CUBA.desc(), + out=brainpy.state.CUBA.desc(), post=self.post ) @@ -493,7 +493,7 @@ Summary .. code-block:: python - ✅ Inherit from bp.Neuron, bp.Synapse, or brainstate.nn.Module + ✅ Inherit from brainpy.state.Neuron, brainpy.state.Synapse, or brainstate.nn.Module ✅ Define __init__ with parameters ✅ Create states (ShortTermState or ParamState) ✅ Implement reset_state(batch_size=None) diff --git a/docs_state/how-to-guides/debugging-networks.rst b/docs_state/how-to-guides/debugging-networks.rst index 2b8624af..eaa434eb 100644 --- a/docs_state/how-to-guides/debugging-networks.rst +++ b/docs_state/how-to-guides/debugging-networks.rst @@ -45,11 +45,11 @@ Issue 1: No Spikes / Silent Network .. code-block:: python - import brainpy as bp + import brainpy import brainstate import brainunit as u - neuron = bp.LIF(100, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + neuron = brainpy.state.LIF(100, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) brainstate.nn.init_all_states(neuron) # Check 1: Is input being provided? @@ -90,24 +90,24 @@ Issue 1: No Spikes / Silent Network .. code-block:: python # Check threshold - neuron = bp.LIF(100, V_th=-40*u.mV, ...) # Harder to spike - neuron = bp.LIF(100, V_th=-50*u.mV, ...) # Easier to spike + neuron = brainpy.state.LIF(100, V_th=-40*u.mV, ...) # Harder to spike + neuron = brainpy.state.LIF(100, V_th=-50*u.mV, ...) # Easier to spike 3. **Time constant too large:** .. code-block:: python # Slow integration - neuron = bp.LIF(100, tau=100*u.ms, ...) # Very slow + neuron = brainpy.state.LIF(100, tau=100*u.ms, ...) # Very slow # Faster - neuron = bp.LIF(100, tau=10*u.ms, ...) # Normal speed + neuron = brainpy.state.LIF(100, tau=10*u.ms, ...) # Normal speed 4. **Missing initialization:** .. code-block:: python - neuron = bp.LIF(100, ...) + neuron = brainpy.state.LIF(100, ...) # MUST initialize! brainstate.nn.init_all_states(neuron) @@ -163,8 +163,8 @@ Issue 2: Runaway Activity / Explosion class BalancedNetwork(brainstate.nn.Module): def __init__(self): super().__init__() - self.E = bp.LIF(800, ...) - self.I = bp.LIF(200, ...) + self.E = brainpy.state.LIF(800, ...) + self.I = brainpy.state.LIF(200, ...) self.E2E = ... # Excitatory recurrence self.I2E = ... # MUST have inhibition! @@ -184,11 +184,11 @@ Issue 2: Runaway Activity / Explosion .. code-block:: python # WRONG: Inhibition with excitatory reversal - out_inh = bp.COBA.desc(E=0*u.mV) # Should be negative! + out_inh = brainpy.state.COBA.desc(E=0*u.mV) # Should be negative! # CORRECT - out_exc = bp.COBA.desc(E=0*u.mV) # Excitation - out_inh = bp.COBA.desc(E=-80*u.mV) # Inhibition + out_exc = brainpy.state.COBA.desc(E=0*u.mV) # Excitation + out_inh = brainpy.state.COBA.desc(E=-80*u.mV) # Inhibition Issue 3: Spikes Not Propagating ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -204,13 +204,13 @@ Issue 3: Spikes Not Propagating .. code-block:: python # Create simple network - pre = bp.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - post = bp.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + pre = brainpy.state.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + post = brainpy.state.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - proj = bp.AlignPostProj( + proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(10, 10, prob=0.5, weight=2.0*u.mS), - syn=bp.Expon.desc(10, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(10, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post ) @@ -281,10 +281,10 @@ Issue 3: Spikes Not Propagating .. code-block:: python # Wrong target - proj = bp.AlignPostProj(..., post=wrong_population) + proj = brainpy.state.AlignPostProj(..., post=wrong_population) # Correct target - proj = bp.AlignPostProj(..., post=correct_population) + proj = brainpy.state.AlignPostProj(..., post=correct_population) Issue 4: Shape Mismatch Errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -342,7 +342,7 @@ Print State Values .. code-block:: python # Inspect neuron states - neuron = bp.LIF(10, ...) + neuron = brainpy.state.LIF(10, ...) brainstate.nn.init_all_states(neuron) print("Membrane potentials:", neuron.V.value) @@ -407,10 +407,10 @@ Check Connectivity .. code-block:: python # For sparse projections - proj = bp.AlignPostProj( + proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(100, 50, prob=0.1, weight=0.5*u.mS), - syn=bp.Expon.desc(50, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(50, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons ) @@ -545,7 +545,7 @@ Assertion Checks def __init__(self, n_neurons=100): super().__init__() - self.neurons = bp.LIF(n_neurons, ...) + self.neurons = brainpy.state.LIF(n_neurons, ...) def update(self, inp): # Pre-checks @@ -570,7 +570,7 @@ Unit Testing def test_neuron_spikes(): """Test that neuron spikes with strong input.""" - neuron = bp.LIF(1, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + neuron = brainpy.state.LIF(1, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) brainstate.nn.init_all_states(neuron) # Strong constant input should cause spiking @@ -588,13 +588,13 @@ Unit Testing def test_projection(): """Test that projection propagates spikes.""" - pre = bp.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - post = bp.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + pre = brainpy.state.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + post = brainpy.state.LIF(10, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) - proj = bp.AlignPostProj( + proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(10, 10, prob=1.0, weight=5.0*u.mS), # 100% connectivity - syn=bp.Expon.desc(10, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(10, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post ) diff --git a/docs_state/how-to-guides/gpu-tpu-usage.rst b/docs_state/how-to-guides/gpu-tpu-usage.rst index 8de3cb5f..ad44e03d 100644 --- a/docs_state/how-to-guides/gpu-tpu-usage.rst +++ b/docs_state/how-to-guides/gpu-tpu-usage.rst @@ -22,11 +22,11 @@ Quick Start .. code-block:: python - import brainpy as bp + import brainpy import brainstate # This automatically runs on GPU if available - net = bp.LIF(10000, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + net = brainpy.state.LIF(10000, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) brainstate.nn.init_all_states(net) for _ in range(1000): @@ -116,7 +116,7 @@ Automatic Placement import brainstate # Automatically uses GPU if available - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net) # All operations run on GPU @@ -133,13 +133,13 @@ Force computation on specific device: # Run on specific GPU with jax.default_device(jax.devices('gpu')[0]): - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net) result = net(input_data) # Run on CPU with jax.default_device(jax.devices('cpu')[0]): - net_cpu = bp.LIF(1000, ...) + net_cpu = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net_cpu) result_cpu = net_cpu(input_data) @@ -149,7 +149,7 @@ Check Data Location .. code-block:: python # Check where data lives - neuron = bp.LIF(100, ...) + neuron = brainpy.state.LIF(100, ...) brainstate.nn.init_all_states(neuron) print("Voltage device:", neuron.V.value.device()) @@ -167,7 +167,7 @@ Use JIT Compilation import brainstate - net = bp.LIF(10000, ...) + net = brainpy.state.LIF(10000, ...) brainstate.nn.init_all_states(net) # WITHOUT JIT (slow on GPU) @@ -175,7 +175,7 @@ Use JIT Compilation net(input_data) # Many small kernel launches # WITH JIT (fast on GPU) - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(net, inp): return net(inp) @@ -196,11 +196,11 @@ Batch Operations .. code-block:: python # Single trial (underutilizes GPU) - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net) # Shape: (1000,) # Multiple trials in parallel (efficient GPU usage) - net_batched = bp.LIF(1000, ...) + net_batched = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net_batched, batch_size=64) # Shape: (64, 1000) # GPU processes all 64 trials simultaneously @@ -253,7 +253,7 @@ Minimize Data Transfer # CPU-GPU transfer dominates time! # GOOD: Keep data on GPU - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(net, key): inp = brainstate.random.uniform(key, (1000,)) * 2.0 # Generated on GPU return net(inp) # Stays on GPU @@ -270,23 +270,23 @@ Use Sparse Operations .. code-block:: python # Dense (memory intensive on GPU) - dense_proj = bp.AlignPostProj( + dense_proj = brainpy.state.AlignPostProj( comm=brainstate.nn.Linear(10000, 10000), # 400MB just for weights! - syn=bp.Expon.desc(10000, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(10000, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons ) # Sparse (memory efficient) - sparse_proj = bp.AlignPostProj( + sparse_proj = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb( pre_size=10000, post_size=10000, prob=0.01, # 1% connectivity weight=0.5*u.mS ), # Only 4MB for weights! - syn=bp.Expon.desc(10000, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(10000, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=post_neurons ) @@ -309,7 +309,7 @@ Data Parallelism # Split work across GPUs def run_on_gpu(gpu_id, n_trials): with jax.default_device(gpus[gpu_id]): - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net, batch_size=n_trials) results = [] @@ -340,7 +340,7 @@ Using JAX pmap import jax.numpy as jnp # Create model - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) @pmap def parallel_simulate(inputs): @@ -387,11 +387,11 @@ Optimal TPU Usage # Large batches for TPU batch_size = 256 # TPUs like large batches - net = bp.LIF(1000, ...) + net = brainpy.state.LIF(1000, ...) brainstate.nn.init_all_states(net, batch_size=batch_size) # JIT is essential - @brainstate.compile.jit + @brainstate.transform.jit def train_step(net, inputs, labels): # Dense operations work well # Avoid sparse operations on TPU @@ -448,10 +448,10 @@ Measure Speedup with jax.default_device(device): # Create network - net = bp.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + net = brainpy.state.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) brainstate.nn.init_all_states(net) - @brainstate.compile.jit + @brainstate.transform.jit def step(net, inp): return net(inp) @@ -626,7 +626,7 @@ Issue: Slow First Run .. code-block:: python - @brainstate.compile.jit + @brainstate.transform.jit def step(net, inp): return net(inp) @@ -729,14 +729,14 @@ Example: Complete GPU Workflow def __init__(self, n_exc=8000, n_inh=2000): super().__init__() - self.E = bp.LIF(n_exc, V_rest=-65*u.mV, V_th=-50*u.mV, tau=15*u.ms) - self.I = bp.LIF(n_inh, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.E = brainpy.state.LIF(n_exc, V_rest=-65*u.mV, V_th=-50*u.mV, tau=15*u.ms) + self.I = brainpy.state.LIF(n_inh, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # Sparse connectivity (GPU efficient) - self.E2E = bp.AlignPostProj( + self.E2E = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=0.02, weight=0.5*u.mS), - syn=bp.Expon.desc(n_exc, tau=5*u.ms), - out=bp.CUBA.desc(), + syn=brainpy.state.Expon.desc(n_exc, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), post=self.E ) # ... more projections @@ -759,7 +759,7 @@ Example: Complete GPU Workflow brainstate.nn.init_all_states(net, batch_size=batch_size) # 4. JIT compile - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(net, inp_e, inp_i): return net(inp_e, inp_i) @@ -808,7 +808,7 @@ Summary print(jax.devices()) # JIT for GPU - @brainstate.compile.jit + @brainstate.transform.jit def step(net, inp): return net(inp) diff --git a/docs_state/how-to-guides/performance-optimization.rst b/docs_state/how-to-guides/performance-optimization.rst index 0c1d4b8d..5691926b 100644 --- a/docs_state/how-to-guides/performance-optimization.rst +++ b/docs_state/how-to-guides/performance-optimization.rst @@ -32,7 +32,7 @@ JIT Compilation return net(inp) # Fast (with JIT) - @brainstate.compile.jit + @brainstate.transform.jit def fast_step(net, inp): return net(inp) @@ -98,7 +98,7 @@ GPU Usage print(jax.devices()) # Check for GPU # BrainPy automatically uses GPU - net = bp.LIF(10000, ...) + net = brainpy.state.LIF(10000, ...) # Runs on GPU if available **See:** :doc:`gpu-tpu-usage` for details @@ -160,20 +160,20 @@ Optimize Network Architecture .. code-block:: python # Complex (slow but realistic) - neuron = bp.HH(1000, ...) # Hodgkin-Huxley + neuron = brainpy.state.HH(1000, ...) # Hodgkin-Huxley # Simple (fast) - neuron = bp.LIF(1000, ...) # Leaky Integrate-and-Fire + neuron = brainpy.state.LIF(1000, ...) # Leaky Integrate-and-Fire **2. Use CUBA instead of COBA when possible:** .. code-block:: python # Slower (conductance-based) - out = bp.COBA.desc(E=0*u.mV) + out = brainpy.state.COBA.desc(E=0*u.mV) # Faster (current-based) - out = bp.CUBA.desc() + out = brainpy.state.CUBA.desc() **3. Reduce connectivity:** @@ -214,7 +214,7 @@ Performance Checklist .. code-block:: python - ✅ JIT compiled (@brainstate.compile.jit) + ✅ JIT compiled (@brainstate.transform.jit) ✅ Sparse connectivity (EventFixedProb with prob < 0.1) ✅ Batched (batch_size ≥ 32 on GPU) ✅ GPU enabled (check jax.devices()) @@ -257,17 +257,17 @@ Complete Optimization Example super().__init__() # Simple neuron model - self.neurons = bp.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.neurons = brainpy.state.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) # Sparse connectivity - self.recurrent = bp.AlignPostProj( + self.recurrent = brainpy.state.AlignPostProj( comm=brainstate.nn.EventFixedProb( n_neurons, n_neurons, prob=0.01, # Sparse! weight=0.5*u.mS ), - syn=bp.Expon.desc(n_neurons, tau=5*u.ms), - out=bp.CUBA.desc(), # Simple output + syn=brainpy.state.Expon.desc(n_neurons, tau=5*u.ms), + out=brainpy.state.CUBA.desc(), # Simple output post=self.neurons ) @@ -282,7 +282,7 @@ Complete Optimization Example brainstate.nn.init_all_states(net, batch_size=64) # Batched # JIT compile - @brainstate.compile.jit + @brainstate.transform.jit def simulate_step(net, inp): return net(inp) diff --git a/docs_state/how-to-guides/save-load-models.rst b/docs_state/how-to-guides/save-load-models.rst index 5666376c..6790e632 100644 --- a/docs_state/how-to-guides/save-load-models.rst +++ b/docs_state/how-to-guides/save-load-models.rst @@ -124,7 +124,7 @@ Using Pickle (Simple) class SimpleNet(brainstate.nn.Module): def __init__(self, n_neurons=100): super().__init__() - self.lif = bp.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) + self.lif = brainpy.state.LIF(n_neurons, V_rest=-65*u.mV, V_th=-50*u.mV, tau=10*u.ms) self.fc = brainstate.nn.Linear(n_neurons, 10) def update(self, x): @@ -492,7 +492,7 @@ Save hyperparameters to recreate model. config['n_input'], config['n_hidden'] ) - self.hidden = bp.LIF( + self.hidden = brainpy.state.LIF( config['n_hidden'], V_rest=config['V_rest'], V_th=config['V_th'], diff --git a/docs_state/migration/migration-guide.rst b/docs_state/migration/migration-guide.rst deleted file mode 100644 index 72c7abd3..00000000 --- a/docs_state/migration/migration-guide.rst +++ /dev/null @@ -1,567 +0,0 @@ -Migration Guide: BrainPy 2.x to 3.0 -==================================== - -This guide helps you migrate your code from BrainPy 2.x to BrainPy 3.0. BrainPy 3.0 represents a complete rewrite built on ``brainstate``, with significant architectural changes and API improvements. - -Overview of Changes -------------------- - -BrainPy 3.0 introduces several major changes: - -**Architecture** - - Built on ``brainstate`` framework - - State-based programming model - - Integrated physical units (``brainunit``) - - Modular projection architecture - -**API Changes** - - New neuron and synapse interfaces - - Projection system redesign - - Updated simulation APIs - - Training framework changes - -**Performance** - - Improved JIT compilation - - Better memory efficiency - - Enhanced GPU/TPU support - -Compatibility Layer -------------------- - -BrainPy 3.0 includes ``brainpy.version2`` for backward compatibility: - -.. code-block:: python - - # Old code (BrainPy 2.x) - still works with deprecation warning - import brainpy as bp - # bp.math, bp.layers, etc. redirect to bp.version2 - - # Explicit version2 usage (recommended during migration) - import brainpy.version2 as bp2 - - # New BrainPy 3.0 API - import brainpy # Use new 3.0 features - -Migration Strategy ------------------- - -Recommended Approach -~~~~~~~~~~~~~~~~~~~~ - -1. **Gradual Migration**: Use ``brainpy.version2`` for old code while writing new code with 3.0 API -2. **Test Thoroughly**: Ensure numerical equivalence between versions -3. **Update Incrementally**: Migrate module by module, not all at once -4. **Use Both**: Mix version2 and 3.0 code during transition - -.. code-block:: python - - # During migration - import brainpy # New 3.0 API - import brainpy.version2 as bp2 # Old 2.x API - - # Old model - old_network = bp2.dyn.Network(...) - - # New model - new_network = brainpy.LIF(...) - - # Can coexist in same codebase - -Key API Changes ---------------- - -Imports and Modules -~~~~~~~~~~~~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - import brainpy as bp - import brainpy.math as bm - import brainpy.layers as layers - import brainpy.dyn as dyn - from brainpy import neurons, synapses - -**BrainPy 3.0:** - -.. code-block:: python - - import brainpy as bp # Core neurons, synapses, projections - import brainstate # State management, modules - import brainunit as u # Physical units - import braintools # Utilities, optimizers, etc. - -Neuron Models -~~~~~~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - # Old API - neurons = bp.neurons.LIF( - size=100, - V_rest=-65., - V_th=-50., - V_reset=-60., - tau=10., - V_initializer=bp.init.Normal(-60., 5.) - ) - -**BrainPy 3.0:** - -.. code-block:: python - - # New API - with units! - import brainunit as u - import braintools - - neurons = brainpy.LIF( - size=100, - V_rest=-65. * u.mV, # Units required - V_th=-50. * u.mV, - V_reset=-60. * u.mV, - tau=10. * u.ms, - V_initializer=braintools.init.Normal(-60., 5., unit=u.mV) - ) - -**Key Changes:** - -- Simpler import: ``brainpy.LIF`` instead of ``bp.neurons.LIF`` -- Physical units are mandatory -- Initializers from ``braintools.init`` -- Must use ``brainstate.nn.init_all_states()`` before simulation - -Synapse Models -~~~~~~~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - # Old API - syn = bp.synapses.Exponential( - pre=pre_neurons, - post=post_neurons, - conn=bp.connect.FixedProb(0.1), - tau=5., - output=bp.synouts.CUBA() - ) - -**BrainPy 3.0:** - -.. code-block:: python - - # New API - using projection architecture - import brainstate - - projection = brainpy.AlignPostProj( - comm=brainstate.nn.EventFixedProb( - pre_size, post_size, prob=0.1, weight=0.5*u.mS - ), - syn=brainpy.Expon.desc(post_size, tau=5.*u.ms), - out=brainpy.CUBA.desc(), - post=post_neurons - ) - -**Key Changes:** - -- Synapse, connectivity, and output are separated -- Use descriptor pattern (``.desc()``) -- Projections handle the complete pathway -- Physical units throughout - -Network Definition -~~~~~~~~~~~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - # Old API - class EINet(bp.DynamicalSystem): - def __init__(self): - super().__init__() - self.E = bp.neurons.LIF(800) - self.I = bp.neurons.LIF(200) - self.E2E = bp.synapses.Exponential(...) - self.E2I = bp.synapses.Exponential(...) - # ... - - def update(self, tdi, x): - self.E(x) - self.I(x) - self.E2E() - # ... - -**BrainPy 3.0:** - -.. code-block:: python - - # New API - import brainstate - - class EINet(brainstate.nn.Module): - def __init__(self): - super().__init__() - self.E = brainpy.LIF(800, ...) - self.I = brainpy.LIF(200, ...) - self.E2E = brainpy.AlignPostProj(...) - self.E2I = brainpy.AlignPostProj(...) - # ... - - def update(self, x): - spikes_e = self.E.get_spike() - spikes_i = self.I.get_spike() - - self.E2E(spikes_e) - self.E2I(spikes_e) - # ... - - self.E(x) - self.I(x) - -**Key Changes:** - -- Inherit from ``brainstate.nn.Module`` instead of ``bp.DynamicalSystem`` -- No ``tdi`` argument (time info from ``brainstate.environ``) -- Explicit spike handling with ``get_spike()`` -- Update order: projections first, then neurons - -Running Simulations -~~~~~~~~~~~~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - # Old API - runner = bp.DSRunner(network, monitors=['E.spike']) - runner.run(duration=1000.) - - # Access results - spikes = runner.mon['E.spike'] - -**BrainPy 3.0:** - -.. code-block:: python - - # New API - import brainunit as u - - # Set time step - brainstate.environ.set(dt=0.1 * u.ms) - - # Initialize - brainstate.nn.init_all_states(network) - - # Run simulation - times = u.math.arange(0*u.ms, 1000*u.ms, brainstate.environ.get_dt()) - results = brainstate.transform.for_loop( - network.update, - times, - pbar=brainstate.transform.ProgressBar(10) - ) - -**Key Changes:** - -- No ``DSRunner`` class -- Use ``brainstate.transform.for_loop`` for simulation -- Must initialize states explicitly -- Manual recording of variables -- Physical units for time - -Training -~~~~~~~~ - -**BrainPy 2.x:** - -.. code-block:: python - - # Old API - trainer = bp.BPTT( - network, - loss_fun=loss_fn, - optimizer=bp.optim.Adam(lr=1e-3) - ) - trainer.fit(train_data, epochs=100) - -**BrainPy 3.0:** - -.. code-block:: python - - # New API - import braintools - - # Define optimizer - optimizer = braintools.optim.Adam(lr=1e-3) - optimizer.register_trainable_weights( - network.states(brainstate.ParamState) - ) - - # Training loop - @brainstate.compile.jit - def train_step(inputs, targets): - def loss_fn(): - predictions = brainstate.compile.for_loop(network.update, inputs) - return compute_loss(predictions, targets) - - grads, loss = brainstate.transform.grad( - loss_fn, - network.states(brainstate.ParamState), - return_value=True - )() - optimizer.update(grads) - return loss - - # Train - for epoch in range(100): - loss = train_step(train_inputs, train_targets) - -**Key Changes:** - -- No ``BPTT`` or ``Trainer`` classes -- Manual training loop implementation -- Explicit gradient computation -- More control, more flexibility - -Common Migration Patterns --------------------------- - -Pattern 1: Simple Neuron Population -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**2.x Code:** - -.. code-block:: python - - neurons = bp.neurons.LIF(100, V_rest=-65., V_th=-50., tau=10.) - runner = bp.DSRunner(neurons) - runner.run(100., inputs=2.0) - -**3.0 Code:** - -.. code-block:: python - - import brainunit as u - import brainstate - - brainstate.environ.set(dt=0.1*u.ms) - neurons = brainpy.LIF(100, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms) - brainstate.nn.init_all_states(neurons) - - times = u.math.arange(0*u.ms, 100*u.ms, brainstate.environ.get_dt()) - results = brainstate.transform.for_loop( - lambda t: neurons(2.0*u.nA), - times - ) - -Pattern 2: E-I Network -~~~~~~~~~~~~~~~~~~~~~~ - -**2.x Code:** - -.. code-block:: python - - E = bp.neurons.LIF(800) - I = bp.neurons.LIF(200) - E2E = bp.synapses.Exponential(E, E, bp.connect.FixedProb(0.02)) - E2I = bp.synapses.Exponential(E, I, bp.connect.FixedProb(0.02)) - I2E = bp.synapses.Exponential(I, E, bp.connect.FixedProb(0.02)) - I2I = bp.synapses.Exponential(I, I, bp.connect.FixedProb(0.02)) - - net = bp.Network(E, I, E2E, E2I, I2E, I2I) - runner = bp.DSRunner(net) - runner.run(1000.) - -**3.0 Code:** - -.. code-block:: python - - import brainpy as bp - import brainstate - import brainunit as u - - class EINet(brainstate.nn.Module): - def __init__(self): - super().__init__() - self.E = brainpy.LIF(800, V_th=-50.*u.mV, tau=10.*u.ms) - self.I = brainpy.LIF(200, V_th=-50.*u.mV, tau=10.*u.ms) - - self.E2E = brainpy.AlignPostProj( - comm=brainstate.nn.EventFixedProb(800, 800, 0.02, 0.1*u.mS), - syn=brainpy.Expon.desc(800, tau=5.*u.ms), - out=brainpy.CUBA.desc(), - post=self.E - ) - # ... similar for E2I, I2E, I2I - - def update(self, inp): - e_spk = self.E.get_spike() - i_spk = self.I.get_spike() - self.E2E(e_spk) - # ... other projections - self.E(inp) - self.I(inp) - - brainstate.environ.set(dt=0.1*u.ms) - net = EINet() - brainstate.nn.init_all_states(net) - - times = u.math.arange(0*u.ms, 1000*u.ms, 0.1*u.ms) - results = brainstate.transform.for_loop( - lambda t: net.update(1.*u.nA), - times - ) - -Troubleshooting ---------------- - -Common Issues -~~~~~~~~~~~~~ - -**Issue 1: ImportError** - -.. code-block:: python - - # Error: ModuleNotFoundError: No module named 'brainpy.math' - import brainpy.math as bm # Old import - - # Solution: Use version2 or update to new API - import brainpy.version2.math as bm # Temporary - # or - import brainunit as u # New API - -**Issue 2: Unit Errors** - -.. code-block:: python - - # Error: Units required but not provided - neuron = bp.LIF(100, tau=10.) # Missing units - - # Solution: Add units - import brainunit as u - neuron = bp.LIF(100, tau=10.*u.ms) - -**Issue 3: State Initialization** - -.. code-block:: python - - # Error: States not initialized - neuron = brainpy.LIF(100, ...) - neuron(input) # May fail or give wrong results - - # Solution: Initialize states - import brainstate - neuron = brainpy.LIF(100, ...) - brainstate.nn.init_all_states(neuron) - neuron(input) # Now works correctly - -**Issue 4: Projection Update Order** - -.. code-block:: python - - # Wrong: Neurons before projections - def update(self, inp): - self.neurons(inp) - self.projection(self.neurons.get_spike()) # Uses current spikes - - # Correct: Projections before neurons - def update(self, inp): - spikes = self.neurons.get_spike() # Get previous spikes - self.projection(spikes) # Update synapses - self.neurons(inp) # Update neurons - -Testing Migration ------------------ - -Numerical Equivalence -~~~~~~~~~~~~~~~~~~~~~ - -When migrating, verify that new code produces equivalent results: - -.. code-block:: python - - # Old code results - import brainpy.version2 as bp2 - old_network = bp2.neurons.LIF(100, ...) - old_runner = bp2.DSRunner(old_network) - old_runner.run(100.) - old_voltages = old_runner.mon['V'] - - # New code results - import brainpy as bp - import brainstate - new_network = brainpy.LIF(100, ...) - brainstate.nn.init_all_states(new_network) - # ... run simulation ... - # new_voltages = ... - - # Compare - import numpy as np - np.allclose(old_voltages, new_voltages, rtol=1e-5) - -Feature Parity Checklist -------------------------- - -Before completing migration, verify: - -☐ All neuron models migrated -☐ All synapse models migrated -☐ Network structure preserved -☐ Simulation produces equivalent results -☐ Training works (if applicable) -☐ Visualization updated -☐ Unit tests pass -☐ Documentation updated - -Getting Help ------------- - -If you encounter issues during migration: - -- Check the `API documentation <../api/index.html>`_ -- Review `examples <../examples/gallery.html>`_ -- Search `GitHub issues `_ -- Ask on GitHub Discussions -- Read the `brainstate documentation `_ - -Benefits of Migration ---------------------- - -Migrating to BrainPy 3.0 provides: - -✅ **Better Performance**: Optimized compilation and execution - -✅ **Physical Units**: Automatic unit checking prevents errors - -✅ **Cleaner API**: More intuitive and consistent interfaces - -✅ **Modularity**: Easier to compose and reuse components - -✅ **Modern Architecture**: Built on proven frameworks - -✅ **Better Tooling**: Improved ecosystem integration - -Summary -------- - -Migration from BrainPy 2.x to 3.0 requires: - -1. Understanding new architecture (state-based, modular) -2. Adding physical units to all parameters -3. Updating import statements -4. Refactoring network definitions -5. Changing simulation and training code -6. Testing for numerical equivalence - -The ``brainpy.version2`` compatibility layer enables gradual migration, allowing you to update your codebase incrementally. - -Next Steps ----------- - -- Start with the :doc:`../quickstart/5min-tutorial` to learn 3.0 basics -- Review :doc:`../core-concepts/architecture` for design understanding -- Follow :doc:`../tutorials/basic/01-lif-neuron` for hands-on practice -- Study :doc:`../examples/gallery` for complete migration examples diff --git a/docs_state/quickstart/5min-tutorial.ipynb b/docs_state/quickstart/5min-tutorial.ipynb index 25177711..9439a659 100644 --- a/docs_state/quickstart/5min-tutorial.ipynb +++ b/docs_state/quickstart/5min-tutorial.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# 5-Minute Tutorial: Getting Started with ``brainpy.state``\n", + "# 5-Minute Tutorial: Getting Started\n", "\n", "Welcome to ``brainpy.state``! This quick tutorial will get you up and running with your first neural simulation in just a few minutes.\n", "\n", diff --git a/docs_state/snn_simulation-en.ipynb b/docs_state/snn_simulation-en.ipynb index ec0d5559..244e07ae 100644 --- a/docs_state/snn_simulation-en.ipynb +++ b/docs_state/snn_simulation-en.ipynb @@ -278,15 +278,15 @@ "# Define the simulation times, from 0 to 100 ms with a time step of 'dt'\n", "times = u.math.arange(0. * u.ms, 100. * u.ms, dt)\n", "\n", - "# Run the simulation using `brainstate.compile.for_loop`:\n", + "# Run the simulation using `brainstate.transform.for_loop`:\n", "# - `run` function is called iteratively with each time step and random input current\n", "# - Random input current between 1 and 10 uA/cm² is generated at each time step\n", "# - `pbar` is used to show a progress bar during the simulation\n", - "vs = brainstate.compile.for_loop(\n", + "vs = brainstate.transform.for_loop(\n", " run,\n", " times, # Time steps as input\n", " brainstate.random.uniform(1., 10., times.shape) * u.uA / u.cm ** 2, # Random input current (1 to 10 uA/cm²)\n", - " pbar=brainstate.compile.ProgressBar(count=10)\n", + " pbar=brainstate.transform.ProgressBar(count=10)\n", ") # Show progress bar with 10 steps\n", "\n", "# Plot the membrane potential over time\n", @@ -618,13 +618,13 @@ "# Define the time array from 0 to 1000 ms with a step size of dt\n", "times = u.math.arange(0. * u.ms, 1000. * u.ms, brainstate.environ.get_dt())\n", "\n", - "# Run the simulation using `brainstate.compile.for_loop`, iterating over each time step\n", + "# Run the simulation using `brainstate.transform.for_loop`, iterating over each time step\n", "# The `lambda t: net.update(Ib)` applies the `update` method of the network `net`\n", "# for each time step, with `Ib` as the input current at each time step.\n", - "spikes = brainstate.compile.for_loop(\n", + "spikes = brainstate.transform.for_loop(\n", " lambda t: net.update(Ib), # Call net.update with input current Ib\n", " times, # Time steps\n", - " pbar=brainstate.compile.ProgressBar(10) # Show a progress bar with 10 steps\n", + " pbar=brainstate.transform.ProgressBar(10) # Show a progress bar with 10 steps\n", ")" ] }, diff --git a/docs_state/snn_simulation-zh.ipynb b/docs_state/snn_simulation-zh.ipynb index 212ad1b2..c5141c9d 100644 --- a/docs_state/snn_simulation-zh.ipynb +++ b/docs_state/snn_simulation-zh.ipynb @@ -271,14 +271,14 @@ "# Define the simulation times, from 0 to 100 ms with a time step of 'dt'\n", "times = u.math.arange(0. * u.ms, 100. * u.ms, dt)\n", "\n", - "# Run the simulation using `brainstate.compile.for_loop`:\n", + "# Run the simulation using `brainstate.transform.for_loop`:\n", "# - `run` function is called iteratively with each time step and random input current\n", "# - Random input current between 1 and 10 uA/cm² is generated at each time step\n", "# - `pbar` is used to show a progress bar during the simulation\n", - "vs = brainstate.compile.for_loop(run,\n", + "vs = brainstate.transform.for_loop(run,\n", " times, # Time steps as input\n", " brainstate.random.uniform(1., 10., times.shape) * u.uA / u.cm ** 2, # Random input current (1 to 10 uA/cm²)\n", - " pbar=brainstate.compile.ProgressBar(count=10)) # Show progress bar with 10 steps\n", + " pbar=brainstate.transform.ProgressBar(count=10)) # Show progress bar with 10 steps\n", "\n", "# Plot the membrane potential over time\n", "plt.plot(times, vs)\n", @@ -639,13 +639,13 @@ "# Define the time array from 0 to 1000 ms with a step size of dt\n", "times = u.math.arange(0. * u.ms, 1000. * u.ms, brainstate.environ.get_dt())\n", "\n", - "# Run the simulation using `brainstate.compile.for_loop`, iterating over each time step\n", + "# Run the simulation using `brainstate.transform.for_loop`, iterating over each time step\n", "# The `lambda t: net.update(Ib)` applies the `update` method of the network `net`\n", "# for each time step, with `Ib` as the input current at each time step.\n", - "spikes = brainstate.compile.for_loop(\n", + "spikes = brainstate.transform.for_loop(\n", " lambda t: net.update(Ib), # Call net.update with input current Ib\n", " times, # Time steps\n", - " pbar=brainstate.compile.ProgressBar(10) # Show a progress bar with 10 steps\n", + " pbar=brainstate.transform.ProgressBar(10) # Show a progress bar with 10 steps\n", ")" ], "outputs": [ diff --git a/docs_state/snn_training-en.ipynb b/docs_state/snn_training-en.ipynb index 03d7a214..c21f22ed 100644 --- a/docs_state/snn_training-en.ipynb +++ b/docs_state/snn_training-en.ipynb @@ -430,7 +430,7 @@ "\n", "def predict_and_visualize_net_activity(net):\n", " brainstate.nn.init_all_states(net, batch_size=batch_size)\n", - " vs, spikes, outs = brainstate.compile.for_loop(net.predict, x_data, pbar=brainstate.compile.ProgressBar(10))\n", + " vs, spikes, outs = brainstate.transform.for_loop(net.predict, x_data, pbar=brainstate.transform.ProgressBar(10))\n", " plot_voltage_traces(vs, spikes, spike_height=5 * u.mV, show=False)\n", " plot_voltage_traces(outs)\n", " print_classification_accuracy(outs, y_data)" @@ -517,7 +517,7 @@ "optimizer.register_trainable_weights(net.states(brainstate.ParamState))\n", "\n", "def loss_fn():\n", - " predictions = brainstate.compile.for_loop(net.update, x_data)\n", + " predictions = brainstate.transform.for_loop(net.update, x_data)\n", " predictions = u.math.mean(predictions, axis=0)\n", " return bts.metric.softmax_cross_entropy_with_integer_labels(predictions, y_data).mean()" ] @@ -576,7 +576,7 @@ } ], "source": [ - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def train_fn():\n", " brainstate.nn.init_all_states(net, batch_size=batch_size)\n", " grads, l = brainstate.augment.grad(loss_fn, net.states(brainstate.ParamState), return_value=True)()\n", diff --git a/docs_state/snn_training-zh.ipynb b/docs_state/snn_training-zh.ipynb index 37f60222..0c03cc46 100644 --- a/docs_state/snn_training-zh.ipynb +++ b/docs_state/snn_training-zh.ipynb @@ -430,7 +430,7 @@ "\n", "def predict_and_visualize_net_activity(net):\n", " brainstate.nn.init_all_states(net, batch_size=batch_size)\n", - " vs, spikes, outs = brainstate.compile.for_loop(net.predict, x_data, pbar=brainstate.compile.ProgressBar(10))\n", + " vs, spikes, outs = brainstate.transform.for_loop(net.predict, x_data, pbar=brainstate.transform.ProgressBar(10))\n", " plot_voltage_traces(vs, spikes, spike_height=5 * u.mV, show=False)\n", " plot_voltage_traces(outs)\n", " print_classification_accuracy(outs, y_data)" @@ -517,7 +517,7 @@ "optimizer.register_trainable_weights(net.states(brainstate.ParamState))\n", "\n", "def loss_fn():\n", - " predictions = brainstate.compile.for_loop(net.update, x_data)\n", + " predictions = brainstate.transform.for_loop(net.update, x_data)\n", " predictions = u.math.mean(predictions, axis=0)\n", " return bts.metric.softmax_cross_entropy_with_integer_labels(predictions, y_data).mean()" ] @@ -576,7 +576,7 @@ } ], "source": [ - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def train_fn():\n", " brainstate.nn.init_all_states(net, batch_size=batch_size)\n", " grads, l = brainstate.augment.grad(loss_fn, net.states(brainstate.ParamState), return_value=True)()\n", diff --git a/docs_state/tutorials/advanced/05-snn-training.ipynb b/docs_state/tutorials/advanced/05-snn-training.ipynb index fdd21cc5..c9612a8f 100644 --- a/docs_state/tutorials/advanced/05-snn-training.ipynb +++ b/docs_state/tutorials/advanced/05-snn-training.ipynb @@ -39,7 +39,7 @@ "metadata": {}, "outputs": [], "source": [ - "import brainpy as bp\n", + "import brainpy\n", "import brainstate\n", "import brainunit as u\n", "import braintools\n", @@ -219,7 +219,7 @@ "\n", "**Key for training:**\n", "- Use LIF neurons with surrogate gradient spike functions\n", - "- Use `bp.Readout` to convert spikes to logits" + "- Use `brainpy.state.Readout` to convert spikes to logits" ] }, { @@ -238,7 +238,7 @@ " self.fc1 = brainstate.nn.Linear(n_input, n_hidden, w_init=brainstate.init.KaimingNormal())\n", " \n", " # Hidden LIF neurons with surrogate gradient\n", - " self.lif1 = bp.LIF(\n", + " self.lif1 = brainpy.state.LIF(\n", " n_hidden,\n", " V_rest=-65.0 * u.mV,\n", " V_th=-50.0 * u.mV,\n", @@ -251,7 +251,7 @@ " self.fc2 = brainstate.nn.Linear(n_hidden, n_output, w_init=brainstate.init.KaimingNormal())\n", " \n", " # Output LIF neurons with surrogate gradient\n", - " self.lif2 = bp.LIF(\n", + " self.lif2 = brainpy.state.LIF(\n", " n_output,\n", " V_rest=-65.0 * u.mV,\n", " V_th=-50.0 * u.mV,\n", @@ -261,7 +261,7 @@ " )\n", " \n", " # Readout layer to convert spikes to logits\n", - " self.readout = bp.Readout(n_output, n_output)\n", + " self.readout = brainpy.state.Readout(n_output, n_output)\n", " \n", " def update(self, x):\n", " \"\"\"Forward pass for one time step.\n", @@ -848,7 +848,7 @@ "**Key code pattern:**\n", "```python\n", "# 1. Create network with surrogate gradients\n", - "lif = bp.LIF(..., spike_fun=braintools.surrogate.ReluGrad())\n", + "lif = brainpy.state.LIF(..., spike_fun=braintools.surrogate.ReluGrad())\n", "\n", "# 2. Define loss over time\n", "def loss_fn(net, X, y, n_steps):\n", diff --git a/docs_state/tutorials/advanced/06-synaptic-plasticity.ipynb b/docs_state/tutorials/advanced/06-synaptic-plasticity.ipynb index 59cec8d7..5667f0e9 100644 --- a/docs_state/tutorials/advanced/06-synaptic-plasticity.ipynb +++ b/docs_state/tutorials/advanced/06-synaptic-plasticity.ipynb @@ -40,7 +40,7 @@ "metadata": {}, "outputs": [], "source": [ - "import brainpy as bp\n", + "import brainpy\n", "import brainstate\n", "import brainunit as u\n", "import braintools\n", @@ -83,7 +83,7 @@ "outputs": [], "source": [ "# Create synapse with short-term depression\n", - "class STDSynapse(bp.Synapse):\n", + "class STDSynapse(brainpy.state.Synapse):\n", " \"\"\"Synapse with short-term depression.\"\"\"\n", " \n", " def __init__(self, size, tau=5.0*u.ms, tau_d=200.0*u.ms, U=0.5, **kwargs):\n", @@ -199,7 +199,7 @@ "metadata": {}, "outputs": [], "source": [ - "class STFSynapse(bp.Synapse):\n", + "class STFSynapse(brainpy.state.Synapse):\n", " \"\"\"Synapse with short-term facilitation.\"\"\"\n", " \n", " def __init__(self, size, tau=5.0*u.ms, tau_f=200.0*u.ms, U=0.15, **kwargs):\n", @@ -317,7 +317,7 @@ "def simulate_stp(tau_f, tau_d, U, spike_indices, n_steps, label):\n", " \"\"\"Simulate STP synapse and return conductance history.\"\"\"\n", " \n", - " class STPSynapse(bp.Synapse):\n", + " class STPSynapse(brainpy.state.Synapse):\n", " def __init__(self, size, **kwargs):\n", " super().__init__(size, **kwargs)\n", " self.tau = 5.0 * u.ms\n", @@ -502,7 +502,7 @@ "metadata": {}, "outputs": [], "source": [ - "class STDPSynapse(bp.Synapse):\n", + "class STDPSynapse(brainpy.state.Synapse):\n", " \"\"\"Synapse with STDP learning.\"\"\"\n", " \n", " def __init__(self, size, tau=5.0*u.ms, A_plus=0.01, A_minus=0.01, \n", @@ -636,7 +636,7 @@ " self.n_neurons = n_neurons\n", " \n", " # LIF neurons\n", - " self.neurons = bp.LIF(\n", + " self.neurons = brainpy.state.LIF(\n", " n_neurons,\n", " V_rest=-65.0 * u.mV,\n", " V_th=-50.0 * u.mV,\n", @@ -770,7 +770,7 @@ " \n", " # Feedforward layers (trained with gradients)\n", " self.fc1 = brainstate.nn.Linear(n_input, n_hidden)\n", - " self.hidden = bp.LIF(\n", + " self.hidden = brainpy.state.LIF(\n", " n_hidden,\n", " V_rest=-65.0*u.mV, V_th=-50.0*u.mV, tau=10.0*u.ms,\n", " spike_fun=braintools.surrogate.ReluGrad()\n", @@ -780,13 +780,13 @@ " # Would use STDPSynapse in practice\n", " \n", " self.fc2 = brainstate.nn.Linear(n_hidden, n_output)\n", - " self.output = bp.LIF(\n", + " self.output = brainpy.state.LIF(\n", " n_output,\n", " V_rest=-65.0*u.mV, V_th=-50.0*u.mV, tau=10.0*u.ms,\n", " spike_fun=braintools.surrogate.ReluGrad()\n", " )\n", " \n", - " self.readout = bp.Readout(n_output, n_output)\n", + " self.readout = brainpy.state.Readout(n_output, n_output)\n", " \n", " def update(self, x):\n", " # Feedforward path (gradient-trained)\n", @@ -857,7 +857,7 @@ "\n", "```python\n", "# Short-term depression\n", - "class STDSynapse(bp.Synapse):\n", + "class STDSynapse(brainpy.state.Synapse):\n", " def update(self, pre_spike):\n", " # Deplete resources on spike\n", " self.x.value -= pre_spike * U * self.x.value\n", @@ -867,7 +867,7 @@ " self.g.value += pre_spike * U * self.x.value\n", "\n", "# STDP learning\n", - "class STDPSynapse(bp.Synapse):\n", + "class STDPSynapse(brainpy.state.Synapse):\n", " def update(self, pre_spike, post_spike):\n", " # Update traces\n", " self.pre_trace.value += pre_spike\n", diff --git a/docs_state/tutorials/advanced/07-large-scale-simulations.ipynb b/docs_state/tutorials/advanced/07-large-scale-simulations.ipynb index b7d0f478..e5f98c44 100644 --- a/docs_state/tutorials/advanced/07-large-scale-simulations.ipynb +++ b/docs_state/tutorials/advanced/07-large-scale-simulations.ipynb @@ -39,7 +39,7 @@ "metadata": {}, "outputs": [], "source": [ - "import brainpy as bp\n", + "import brainpy\n", "import brainstate\n", "import brainunit as u\n", "import braintools\n", @@ -92,7 +92,7 @@ "class SimpleNetwork(brainstate.nn.Module):\n", " def __init__(self, n_neurons=1000):\n", " super().__init__()\n", - " self.neurons = bp.LIF(\n", + " self.neurons = brainpy.state.LIF(\n", " n_neurons,\n", " V_rest=-65.0*u.mV, V_th=-50.0*u.mV, tau=10.0*u.ms\n", " )\n", @@ -132,7 +132,7 @@ "brainstate.nn.init_all_states(net_jit)\n", "\n", "# Apply JIT compilation\n", - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def run_step_jit(net, inp):\n", " return net(inp)\n", "\n", @@ -283,35 +283,35 @@ " super().__init__()\n", " \n", " # Neurons\n", - " self.E = bp.LIF(n_exc, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=15.*u.ms)\n", - " self.I = bp.LIF(n_inh, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + " self.E = brainpy.state.LIF(n_exc, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=15.*u.ms)\n", + " self.I = brainpy.state.LIF(n_inh, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", " \n", " # Sparse projections with EventFixedProb\n", - " self.E2E = bp.AlignPostProj(\n", + " self.E2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=p_conn, weight=0.6*u.mS),\n", - " syn=bp.Expon.desc(n_exc, tau=5.*u.ms),\n", - " out=bp.COBA.desc(E=0.*u.mV),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=5.*u.ms),\n", + " out=brainpy.state.COBA.desc(E=0.*u.mV),\n", " post=self.E\n", " )\n", " \n", - " self.E2I = bp.AlignPostProj(\n", + " self.E2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_inh, prob=p_conn, weight=0.6*u.mS),\n", - " syn=bp.Expon.desc(n_inh, tau=5.*u.ms),\n", - " out=bp.COBA.desc(E=0.*u.mV),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=5.*u.ms),\n", + " out=brainpy.state.COBA.desc(E=0.*u.mV),\n", " post=self.I\n", " )\n", " \n", - " self.I2E = bp.AlignPostProj(\n", + " self.I2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_exc, prob=p_conn, weight=6.7*u.mS),\n", - " syn=bp.Expon.desc(n_exc, tau=10.*u.ms),\n", - " out=bp.COBA.desc(E=-80.*u.mV),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=10.*u.ms),\n", + " out=brainpy.state.COBA.desc(E=-80.*u.mV),\n", " post=self.E\n", " )\n", " \n", - " self.I2I = bp.AlignPostProj(\n", + " self.I2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_inh, prob=p_conn, weight=6.7*u.mS),\n", - " syn=bp.Expon.desc(n_inh, tau=10.*u.ms),\n", - " out=bp.COBA.desc(E=-80.*u.mV),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=10.*u.ms),\n", + " out=brainpy.state.COBA.desc(E=-80.*u.mV),\n", " post=self.I\n", " )\n", " \n", @@ -373,7 +373,7 @@ " net = SimpleNetwork(n_neurons=1000)\n", " brainstate.nn.init_all_states(net)\n", " \n", - " @brainstate.compile.jit\n", + " @brainstate.transform.jit\n", " def step(net, inp):\n", " return net(inp)\n", " \n", @@ -386,7 +386,7 @@ " net = SimpleNetwork(n_neurons=1000)\n", " brainstate.nn.init_all_states(net, batch_size=n_trials)\n", " \n", - " @brainstate.compile.jit\n", + " @brainstate.transform.jit\n", " def step(net, inp):\n", " return net(inp)\n", " \n", @@ -507,11 +507,11 @@ "class ProfilingNetwork(brainstate.nn.Module):\n", " def __init__(self, n_neurons=5000):\n", " super().__init__()\n", - " self.lif = bp.LIF(n_neurons, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", - " self.proj = bp.AlignPostProj(\n", + " self.lif = brainpy.state.LIF(n_neurons, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + " self.proj = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_neurons, n_neurons, prob=0.01, weight=0.5*u.mS),\n", - " syn=bp.Expon.desc(n_neurons, tau=5.*u.ms),\n", - " out=bp.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_neurons, tau=5.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.lif\n", " )\n", " \n", @@ -525,7 +525,7 @@ "net = ProfilingNetwork(n_neurons=5000)\n", "brainstate.nn.init_all_states(net)\n", "\n", - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def run_step(net, inp):\n", " return net(inp)\n", "\n", @@ -594,7 +594,7 @@ "3. **Baseline**: Measure current performance\n", "\n", "### Code Optimizations\n", - "- ✅ Use JIT compilation (`@brainstate.compile.jit`)\n", + "- ✅ Use JIT compilation (`@brainstate.transform.jit`)\n", "- ✅ Use sparse connectivity (`EventFixedProb`)\n", "- ✅ Use float32 instead of float64\n", "- ✅ Batch multiple trials together\n", @@ -645,7 +645,7 @@ " net2 = SimpleNetwork(n_neurons)\n", " brainstate.nn.init_all_states(net2)\n", " \n", - " @brainstate.compile.jit\n", + " @brainstate.transform.jit\n", " def step_jit(net, inp):\n", " return net(inp)\n", " \n", @@ -735,37 +735,37 @@ " self.n_inh = n_inh\n", " \n", " # LIF neurons (using default float32)\n", - " self.E = bp.LIF(n_exc, V_rest=-65.*u.mV, V_th=-50.*u.mV, \n", + " self.E = brainpy.state.LIF(n_exc, V_rest=-65.*u.mV, V_th=-50.*u.mV, \n", " V_reset=-65.*u.mV, tau=15.*u.ms)\n", - " self.I = bp.LIF(n_inh, V_rest=-65.*u.mV, V_th=-50.*u.mV,\n", + " self.I = brainpy.state.LIF(n_inh, V_rest=-65.*u.mV, V_th=-50.*u.mV,\n", " V_reset=-65.*u.mV, tau=10.*u.ms)\n", " \n", " # Sparse connectivity\n", - " self.E2E = bp.AlignPostProj(\n", + " self.E2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=p_conn, weight=0.05*u.mS),\n", - " syn=bp.Expon.desc(n_exc, tau=5.*u.ms),\n", - " out=bp.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=5.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.E\n", " )\n", " \n", - " self.E2I = bp.AlignPostProj(\n", + " self.E2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_inh, prob=p_conn, weight=0.05*u.mS),\n", - " syn=bp.Expon.desc(n_inh, tau=5.*u.ms),\n", - " out=bp.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=5.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.I\n", " )\n", " \n", - " self.I2E = bp.AlignPostProj(\n", + " self.I2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_exc, prob=p_conn, weight=0.4*u.mS),\n", - " syn=bp.Expon.desc(n_exc, tau=10.*u.ms),\n", - " out=bp.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=10.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.E\n", " )\n", " \n", - " self.I2I = bp.AlignPostProj(\n", + " self.I2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_inh, prob=p_conn, weight=0.4*u.mS),\n", - " syn=bp.Expon.desc(n_inh, tau=10.*u.ms),\n", - " out=bp.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=10.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.I\n", " )\n", " \n", @@ -800,7 +800,7 @@ "print(f\" Estimated memory: ~50 MB\")\n", "\n", "# JIT-compiled simulation\n", - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def simulate_step(net, inp_e, inp_i):\n", " return net(inp_e, inp_i)\n", "\n", @@ -881,7 +881,7 @@ "In this tutorial, you learned:\n", "\n", "✅ **JIT compilation**\n", - " - Use `@brainstate.compile.jit` for 10-100× speedup\n", + " - Use `@brainstate.transform.jit` for 10-100× speedup\n", " - Functions must be pure and have static shapes\n", " - Essential for large-scale simulations\n", "\n", @@ -923,7 +923,7 @@ "brainstate.nn.init_all_states(net, batch_size=10)\n", "\n", "# 3. JIT compile simulation loop\n", - "@brainstate.compile.jit\n", + "@brainstate.transform.jit\n", "def simulate_step(net, inp):\n", " return net(inp)\n", "\n", diff --git a/docs_state/tutorials/basic/01-lif-neuron.ipynb b/docs_state/tutorials/basic/01-lif-neuron.ipynb index ec1edf2c..2b1c6dbf 100644 --- a/docs_state/tutorials/basic/01-lif-neuron.ipynb +++ b/docs_state/tutorials/basic/01-lif-neuron.ipynb @@ -68,7 +68,7 @@ "brainstate.environ.set(dt=0.1 * u.ms)\n", "\n", "# Create a single LIF neuron\n", - "neuron = brainpy.LIF(\n", + "neuron = brainpy.state.LIF(\n", " size=1,\n", " V_rest=-65. * u.mV, # Resting potential\n", " V_th=-50. * u.mV, # Spike threshold\n", @@ -255,7 +255,7 @@ "outputs": [], "source": [ "# Create two neurons with different reset modes\n", - "neuron_hard = brainpy.LIF(\n", + "neuron_hard = brainpy.state.LIF(\n", " size=1,\n", " V_rest=-65. * u.mV,\n", " V_th=-50. * u.mV,\n", @@ -264,7 +264,7 @@ " spk_reset='hard'\n", ")\n", "\n", - "neuron_soft = brainpy.LIF(\n", + "neuron_soft = brainpy.state.LIF(\n", " size=1,\n", " V_rest=-65. * u.mV,\n", " V_th=-50. * u.mV,\n", @@ -361,7 +361,7 @@ "source": [ "# Create population with varied initial conditions\n", "pop_size = 50\n", - "neuron_pop = brainpy.LIF(\n", + "neuron_pop = brainpy.state.LIF(\n", " size=pop_size,\n", " V_rest=-65. * u.mV,\n", " V_th=-50. * u.mV,\n", @@ -445,7 +445,7 @@ "source": [ "# Different time constants\n", "taus = [5*u.ms, 10*u.ms, 20*u.ms]\n", - "neurons = [brainpy.LIF(1, V_rest=-65.*u.mV, V_th=-50.*u.mV, \n", + "neurons = [brainpy.state.LIF(1, V_rest=-65.*u.mV, V_th=-50.*u.mV,\n", " V_reset=-65.*u.mV, tau=tau, spk_reset='hard') \n", " for tau in taus]\n", "\n", @@ -514,8 +514,8 @@ "\n", "Try these on your own:\n", "\n", - "1. Create a neuron with refractory period using `brainpy.LIFRef`\n", - "2. Implement adaptive neuron using `brainpy.ALIF` and observe spike-frequency adaptation\n", + "1. Create a neuron with refractory period using `brainpy.state.LIFRef`\n", + "2. Implement adaptive neuron using `brainpy.state.ALIF` and observe spike-frequency adaptation\n", "3. Generate an F-I curve for different values of τ\n", "4. Create a population with heterogeneous time constants (use different τ for each neuron)" ] diff --git a/docs_state/tutorials/basic/02-synapse-models.ipynb b/docs_state/tutorials/basic/02-synapse-models.ipynb index 4002f4d5..f65fd281 100644 --- a/docs_state/tutorials/basic/02-synapse-models.ipynb +++ b/docs_state/tutorials/basic/02-synapse-models.ipynb @@ -71,7 +71,7 @@ "brainstate.environ.set(dt=0.1 * u.ms)\n", "\n", "# Create exponential synapse\n", - "expon_syn = brainpy.Expon(\n", + "expon_syn = brainpy.state.Expon(\n", " size=1,\n", " tau=5. * u.ms,\n", " g_initializer=braintools.init.Constant(0. * u.mS)\n", @@ -148,7 +148,7 @@ "outputs": [], "source": [ "# Create alpha synapse\n", - "alpha_syn = brainpy.Alpha(\n", + "alpha_syn = brainpy.state.Alpha(\n", " size=1,\n", " tau=5. * u.ms,\n", " g_initializer=braintools.init.Constant(0. * u.mS)\n", @@ -209,14 +209,14 @@ "outputs": [], "source": [ "# Create AMPA synapse (fast excitatory)\n", - "ampa_syn = brainpy.AMPA(\n", + "ampa_syn = brainpy.state.AMPA(\n", " size=1,\n", " tau=2. * u.ms,\n", " g_initializer=braintools.init.Constant(0. * u.mS)\n", ")\n", "\n", "# Create GABAa synapse (slower inhibitory)\n", - "gaba_syn = brainpy.GABAa(\n", + "gaba_syn = brainpy.state.GABAa(\n", " size=1,\n", " tau=10. * u.ms,\n", " g_initializer=braintools.init.Constant(0. * u.mS)\n", @@ -376,7 +376,7 @@ "source": [ "# Compare different time constants\n", "taus = [2*u.ms, 5*u.ms, 10*u.ms, 20*u.ms]\n", - "synapses = [brainpy.Expon(1, tau=tau) for tau in taus]\n", + "synapses = [brainpy.state.Expon(1, tau=tau) for tau in taus]\n", "\n", "for syn in synapses:\n", " brainstate.nn.init_all_states(syn)\n", @@ -440,16 +440,16 @@ "outputs": [], "source": [ "# Create neurons\n", - "pre_neurons = brainpy.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", - "post_neurons = brainpy.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "pre_neurons = brainpy.state.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "post_neurons = brainpy.state.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", "\n", "# Create projection with exponential synapse\n", - "projection = brainpy.AlignPostProj(\n", + "projection = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(\n", " 10, 5, prob=0.5, weight=0.5*u.mS\n", " ),\n", - " syn=brainpy.Expon.desc(5, tau=5.*u.ms), # Synapse descriptor\n", - " out=brainpy.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(5, tau=5.*u.ms), # Synapse descriptor\n", + " out=brainpy.state.CUBA.desc(),\n", " post=post_neurons\n", ")\n", "\n", @@ -505,7 +505,7 @@ "metadata": {}, "outputs": [], "source": [ - "from brainpy._base import Synapse\n", + "from brainpy.state import Synapse\n", "\n", "class DoubleExpSynapse(Synapse):\n", " \"\"\"Synapse with different rise and decay time constants.\"\"\"\n", diff --git a/docs_state/tutorials/basic/03-network-connections.ipynb b/docs_state/tutorials/basic/03-network-connections.ipynb index dbb93eae..de27debd 100644 --- a/docs_state/tutorials/basic/03-network-connections.ipynb +++ b/docs_state/tutorials/basic/03-network-connections.ipynb @@ -68,11 +68,11 @@ "brainstate.environ.set(dt=0.1 * u.ms)\n", "\n", "# Create pre and post neurons\n", - "pre_neurons = brainpy.LIF(20, V_rest=-65.*u.mV, V_th=-50.*u.mV, V_reset=-65.*u.mV, tau=10.*u.ms)\n", - "post_neurons = brainpy.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, V_reset=-65.*u.mV, tau=10.*u.ms)\n", + "pre_neurons = brainpy.state.LIF(20, V_rest=-65.*u.mV, V_th=-50.*u.mV, V_reset=-65.*u.mV, tau=10.*u.ms)\n", + "post_neurons = brainpy.state.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, V_reset=-65.*u.mV, tau=10.*u.ms)\n", "\n", "# Create projection with all three stages\n", - "projection = brainpy.AlignPostProj(\n", + "projection = brainpy.state.AlignPostProj(\n", " # Stage 1: Communication (connectivity + weights)\n", " comm=brainstate.nn.EventFixedProb(\n", " pre_num=20, \n", @@ -82,10 +82,10 @@ " ),\n", " \n", " # Stage 2: Synapse (temporal dynamics)\n", - " syn=brainpy.Expon.desc(10, tau=5.*u.ms),\n", + " syn=brainpy.state.Expon.desc(10, tau=5.*u.ms),\n", " \n", " # Stage 3: Output (how to affect post neurons)\n", - " out=brainpy.CUBA.desc(),\n", + " out=brainpy.state.CUBA.desc(),\n", " \n", " # Target neurons\n", " post=post_neurons\n", @@ -165,23 +165,23 @@ "outputs": [], "source": [ "# Create neurons\n", - "neurons_cuba = brainpy.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", - "neurons_coba = brainpy.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", - "pre = brainpy.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "neurons_cuba = brainpy.state.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "neurons_coba = brainpy.state.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "pre = brainpy.state.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", "\n", "# CUBA projection\n", - "proj_cuba = brainpy.AlignPostProj(\n", + "proj_cuba = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(10, 5, prob=0.5, weight=1.0*u.mS),\n", - " syn=brainpy.Expon.desc(5, tau=5.*u.ms),\n", - " out=brainpy.CUBA.desc(), # Current-based\n", + " syn=brainpy.state.Expon.desc(5, tau=5.*u.ms),\n", + " out=brainpy.state.CUBA.desc(), # Current-based\n", " post=neurons_cuba\n", ")\n", "\n", "# COBA projection (excitatory reversal potential at 0 mV)\n", - "proj_coba = brainpy.AlignPostProj(\n", + "proj_coba = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(10, 5, prob=0.5, weight=1.0*u.mS),\n", - " syn=brainpy.Expon.desc(5, tau=5.*u.ms),\n", - " out=brainpy.COBA.desc(E=0.*u.mV), # Conductance-based\n", + " syn=brainpy.state.Expon.desc(5, tau=5.*u.ms),\n", + " out=brainpy.state.COBA.desc(E=0.*u.mV), # Conductance-based\n", " post=neurons_coba\n", ")\n", "\n", @@ -279,7 +279,7 @@ " self.n_inh = n_inh\n", " \n", " # Create neuron populations\n", - " self.E = brainpy.LIF(\n", + " self.E = brainpy.state.LIF(\n", " n_exc, \n", " V_rest=-65.*u.mV, \n", " V_th=-50.*u.mV, \n", @@ -288,7 +288,7 @@ " V_initializer=braintools.init.Normal(-65., 5., unit=u.mV)\n", " )\n", " \n", - " self.I = brainpy.LIF(\n", + " self.I = brainpy.state.LIF(\n", " n_inh,\n", " V_rest=-65.*u.mV,\n", " V_th=-50.*u.mV,\n", @@ -298,32 +298,32 @@ " )\n", " \n", " # Excitatory projections (fast, AMPA-like)\n", - " self.E2E = brainpy.AlignPostProj(\n", + " self.E2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_exc, prob=prob, weight=0.3*u.mS),\n", - " syn=brainpy.Expon.desc(n_exc, tau=2.*u.ms), # Fast excitation\n", - " out=brainpy.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=2.*u.ms), # Fast excitation\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.E\n", " )\n", " \n", - " self.E2I = brainpy.AlignPostProj(\n", + " self.E2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_exc, n_inh, prob=prob, weight=0.3*u.mS),\n", - " syn=brainpy.Expon.desc(n_inh, tau=2.*u.ms),\n", - " out=brainpy.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=2.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.I\n", " )\n", " \n", " # Inhibitory projections (slower, GABAa-like)\n", - " self.I2E = brainpy.AlignPostProj(\n", + " self.I2E = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_exc, prob=prob, weight=-2.0*u.mS),\n", - " syn=brainpy.Expon.desc(n_exc, tau=10.*u.ms), # Slower inhibition\n", - " out=brainpy.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_exc, tau=10.*u.ms), # Slower inhibition\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.E\n", " )\n", " \n", - " self.I2I = brainpy.AlignPostProj(\n", + " self.I2I = brainpy.state.AlignPostProj(\n", " comm=brainstate.nn.EventFixedProb(n_inh, n_inh, prob=prob, weight=-2.0*u.mS),\n", - " syn=brainpy.Expon.desc(n_inh, tau=10.*u.ms),\n", - " out=brainpy.CUBA.desc(),\n", + " syn=brainpy.state.Expon.desc(n_inh, tau=10.*u.ms),\n", + " out=brainpy.state.CUBA.desc(),\n", " post=self.I\n", " )\n", " \n", diff --git a/docs_state/tutorials/basic/04-input-output.ipynb b/docs_state/tutorials/basic/04-input-output.ipynb index edc510a8..8277bf6c 100644 --- a/docs_state/tutorials/basic/04-input-output.ipynb +++ b/docs_state/tutorials/basic/04-input-output.ipynb @@ -21,7 +21,7 @@ "metadata": {}, "outputs": [], "source": [ - "import brainpy as bp\n", + "import brainpy\n", "import brainstate\n", "import brainunit as u\n", "import braintools\n", @@ -67,7 +67,7 @@ "brainstate.environ.set(dt=0.1 * u.ms)\n", "\n", "# Create neuron\n", - "neuron = bp.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "neuron = brainpy.state.LIF(10, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", "brainstate.nn.init_all_states(neuron)\n", "\n", "# Simulate with constant input\n", @@ -530,10 +530,10 @@ " super().__init__()\n", " \n", " # Hidden layer (recurrent LIF neurons)\n", - " self.hidden = bp.LIF(n_hidden, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + " self.hidden = brainpy.state.LIF(n_hidden, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", " \n", " # Readout layer\n", - " self.readout = bp.Readout(\n", + " self.readout = brainpy.state.Readout(\n", " n_hidden, n_output,\n", " weight_initializer=braintools.init.KaimingNormal()\n", " )\n", @@ -635,7 +635,7 @@ "outputs": [], "source": [ "# Manual recording example\n", - "neuron = bp.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", + "neuron = brainpy.state.LIF(5, V_rest=-65.*u.mV, V_th=-50.*u.mV, tau=10.*u.ms)\n", "brainstate.nn.init_all_states(neuron)\n", "\n", "duration = 100. * u.ms\n", From 18e755c53c15dba99404fafe9680e6f935939735 Mon Sep 17 00:00:00 2001 From: Chaoming Wang Date: Fri, 10 Oct 2025 15:06:14 +0800 Subject: [PATCH 2/2] fix(docs): update card links and descriptions for brainpy.state APIs --- docs_classic/index.rst | 3 +-- docs_state/index.rst | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs_classic/index.rst b/docs_classic/index.rst index 8876d297..1be78370 100644 --- a/docs_classic/index.rst +++ b/docs_classic/index.rst @@ -113,11 +113,10 @@ Learn more :class-card: sd-text-black sd-bg-light :link: https://brainmodeling.readthedocs.io - .. grid-item:: :columns: 6 6 6 4 - .. card:: :material-regular:`settings;2em` ``brainpy.state`` module + .. card:: :material-regular:`data_exploration;2em` ``brainpy.state`` APIs :class-card: sd-text-black sd-bg-light :link: https://brainpy-state.readthedocs.io/ diff --git a/docs_state/index.rst b/docs_state/index.rst index ef2611f4..4801fba3 100644 --- a/docs_state/index.rst +++ b/docs_state/index.rst @@ -116,6 +116,13 @@ Learn more :class-card: sd-text-black sd-bg-light :link: changelog.html + .. grid-item:: + :columns: 6 6 6 4 + + .. card:: :material-regular:`data_exploration;2em` Classical APIs + :class-card: sd-text-black sd-bg-light + :link: https://brainpy.readthedocs.io/ + ----