Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ The Simulated Bifurcation algorithm stops after a certain number of iterations,
At regular intervals, the energy of the agents is sampled and compared with its previous value to calculate their stability period. If an agent's stability period exceeds a convergence threshold, it is considered to have converged and its value is frozen. If all agents converge before the maximum number of iterations has been reached, the algorithm stops.

- The sampling period and the convergence threshold are respectively set using the `sampling_period` and `convergence_threshold` parameters of the `minimize` and `maximize` functions.
- To use early stopping in the SB algorithm, set the `use_window` parameter to `True`.
- To use early stopping in the SB algorithm, set the `early_stopping` parameter to `True`.
- If only some agents have converged when the maximum number of iterations is reached, the algorithm stops and only these agents are considered in the results.

```python
Expand All @@ -247,7 +247,7 @@ sb.minimize(
matrix,
sampling_period=30,
convergence_threshold=50,
use_window=True,
early_stopping=True,
)
```

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
project = "Simulated Bifurcation"
copyright = "2023, Romain Ageron, Thomas Bouquet and Lorenzo Pugliese"
author = "Romain Ageron, Thomas Bouquet and Lorenzo Pugliese"
release = "2.0.1"
release = "1.3.0.dev0"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
13 changes: 9 additions & 4 deletions docs/pages/general/background.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ The Simulated Bifurcation algorithm stops after a certain number of iterations o
computation timeout is reached. However, this implementation comes with the possibility to perform
early stopping and save computation time by defining convergence conditions.

At regular intervals, the state of the spins is sampled and compared with its previous value to calculate
their stability period. If an agent's stability period exceeds a convergence threshold, it is considered
to have converged and its value is frozen. If all agents converge before the maximum number of iterations
has been reached, the algorithm stops.
At regular intervals (this interval being called a sampling period), the agents (spin vectors) are
sampled and compared with their previous state by comparing their Ising energy. If the energy is the
same, the stability period of the agent is increased. If an agent's stability period exceeds a
convergence threshold, it is considered to have converged and its state is frozen. If all agents converge
before the maximum number of iterations has been reached, the algorithm then stops earlier.

The purpose of sampling the spins at regular intervals is to decorrelate them and make their stability more
informative about their convergence (because the evolution of the spins is *slow* it is expected that
most of the spins will not change from a time step to the following).

Notes
~~~~~
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/modules/optimizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ Optimizer
.. autoclass:: SymplecticIntegrator
:members:

.. autoclass:: StopWindow
.. autoclass:: ConvergenceChecker
:members:
28 changes: 14 additions & 14 deletions src/simulated_bifurcation/core/ising.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def minimize(
heated: bool = False,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None,
Expand Down Expand Up @@ -274,17 +274,17 @@ def minimize(
verbose : bool, default=True
Whether to display a progress bar to monitor the progress of
the algorithm.
use_window : bool, default=True
Whether to use the window as a stopping criterion: an agent is
said to have converged if its energy has not changed over the
last `convergence_threshold` energy samplings (done every
`sampling_period` steps).
sampling_period : int, default=50
Number of iterations between two consecutive energy samplings
by the window.
convergence_threshold : int, default=50
Number of consecutive identical energy samplings considered as
a proof of convergence by the window.
early_stopping : bool, default=True, keyword-only
Whether to use early stopping or not, making agents' convergence a
stopping criterion. An agent is said to have converged if its energy
has not changed over the last `convergence_threshold` energy samplings
(done every `sampling_period` steps).
sampling_period : int, default=50, keyword-only
Number of iterations between two consecutive spins samplings used for
early stopping.
convergence_threshold : int, default=50, keyword-only
Number of consecutive identical energy samplings considered as a
proof of convergence of an agent.
timeout : float | None, default=None
Time in seconds after which the simulation is stopped.
None means no timeout.
Expand All @@ -306,7 +306,7 @@ def minimize(

Warns
-----
If `use_window` is True and no agent has reached the convergence
If `early_stopping` is True and no agent has reached the convergence
criterion defined by `sampling_period` and `convergence_threshold`
within `max_steps` iterations, a warning is logged in the console.
This is just an indication however; the returned vectors may still
Expand Down Expand Up @@ -401,7 +401,7 @@ def minimize(
convergence_threshold,
)
tensor = self.as_simulated_bifurcation_tensor()
spins = optimizer.run_integrator(tensor, use_window)
spins = optimizer.run_integrator(tensor, early_stopping)
if self.linear_term:
self.computed_spins = spins[-1] * spins[:-1]
else:
Expand Down
84 changes: 45 additions & 39 deletions src/simulated_bifurcation/core/quadratic_polynomial.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def optimize(
minimize: bool = True,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None,
Expand All @@ -344,13 +344,15 @@ def optimize(
algorithm with a supplementary non-symplectic term to refine the model

To stop the iterations of the symplectic integrator, a number of maximum
steps needs to be specified. However, a refined way to stop is also possible
using a window that checks that the spins have not changed among a set
number of previous steps. In practice, a every fixed number of steps
(called a sampling period) the current spins will be compared to the
previous ones. If they remain constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are
considered to have bifurcated and the algorithm stops.
steps and/or a timeout need(s) to be specified. However, a refined way to stop
is also possible using a convergence checker that asserts that the energy
of the agents has not changed during a fixed number of steps. If so, the computation
stops earlier than expected. In practice, every fixed number of steps (called a
sampling period) the current spins will be compared to the previous
ones (energy-wise). If the energy remains constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are considered
to have bifurcated andthe algorithm stops. These spaced samplings make it possible
to decorrelate the spins and make their stability more informative.

Finally, it is possible to make several particle vectors at the same
time (each one being called an agent). As the vectors are randomly
Expand All @@ -364,7 +366,7 @@ def optimize(
----------
*
convergence_threshold : int, optional
number of consecutive identical spin sampling considered as a proof
number of consecutive identical spins samplings considered as a proof
of convergence (default is 50)
sampling_period : int, optional
number of time steps between two spin sampling (default is 50)
Expand All @@ -373,9 +375,9 @@ def optimize(
(default is 10000)
agents : int, optional
number of vectors to make evolve at the same time (default is 128)
use_window : bool, optional
indicates whether to use the window as a stopping criterion or not
(default is True)
early_stopping : bool, optional
indicates whether to use the early stopping or not, thus making agents'
convergence a stopping criterion (default is True)
timeout : float | None, default=None
Time in seconds after which the simulation is stopped.
None means no timeout.
Expand Down Expand Up @@ -410,7 +412,7 @@ def optimize(
ballistic,
heated,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand All @@ -434,7 +436,7 @@ def minimize(
heated: bool = False,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None,
Expand All @@ -460,13 +462,15 @@ def minimize(
algorithm with a supplementary non-symplectic term to refine the model

To stop the iterations of the symplectic integrator, a number of maximum
steps needs to be specified. However, a refined way to stop is also possible
using a window that checks that the spins have not changed among a set
number of previous steps. In practice, a every fixed number of steps
(called a sampling period) the current spins will be compared to the
previous ones. If they remain constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are
considered to have bifurcated and the algorithm stops.
steps and/or a timeout need(s) to be specified. However, a refined way to stop
is also possible using a convergence checker that asserts that the energy
of the agents has not changed during a fixed number of steps. If so, the computation
stops earlier than expected. In practice, every fixed number of steps (called a
sampling period) the current spins will be compared to the previous
ones (energy-wise). If the energy remains constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are considered
to have bifurcated andthe algorithm stops. These spaced samplings make it possible
to decorrelate the spins and make their stability more informative.

Finally, it is possible to make several particle vectors at the same
time (each one being called an agent). As the vectors are randomly
Expand All @@ -480,7 +484,7 @@ def minimize(
----------
*
convergence_threshold : int, optional
number of consecutive identical spin sampling considered as a proof
number of consecutive identical spins samplings considered as a proof
of convergence (default is 50)
sampling_period : int, optional
number of time steps between two spin sampling (default is 50)
Expand All @@ -489,9 +493,9 @@ def minimize(
(default is 10000)
agents : int, optional
number of vectors to make evolve at the same time (default is 128)
use_window : bool, optional
indicates whether to use the window as a stopping criterion or not
(default is True)
early_stopping : bool, optional
indicates whether to use the early stopping or not, thus making agents'
convergence a stopping criterion (default is True)
timeout : float | None, default=None
Time in seconds after which the simulation is stopped.
None means no timeout.
Expand Down Expand Up @@ -522,7 +526,7 @@ def minimize(
heated,
True,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand All @@ -538,7 +542,7 @@ def maximize(
heated: bool = False,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None,
Expand All @@ -564,13 +568,15 @@ def maximize(
algorithm with a supplementary non-symplectic term to refine the model

To stop the iterations of the symplectic integrator, a number of maximum
steps needs to be specified. However, a refined way to stop is also possible
using a window that checks that the spins have not changed among a set
number of previous steps. In practice, a every fixed number of steps
(called a sampling period) the current spins will be compared to the
previous ones. If they remain constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are
considered to have bifurcated and the algorithm stops.
steps and/or a timeout need(s) to be specified. However, a refined way to stop
is also possible using a convergence checker that asserts that the energy
of the agents has not changed during a fixed number of steps. If so, the computation
stops earlier than expected. In practice, every fixed number of steps (called a
sampling period) the current spins will be compared to the previous
ones (energy-wise). If the energy remains constant throughout a certain number of
consecutive samplings (called the convergence threshold), the spins are considered
to have bifurcated andthe algorithm stops. These spaced samplings make it possible
to decorrelate the spins and make their stability more informative.

Finally, it is possible to make several particle vectors at the same
time (each one being called an agent). As the vectors are randomly
Expand All @@ -583,7 +589,7 @@ def maximize(
Parameters
----------
convergence_threshold : int, optional
number of consecutive identical spin sampling considered as a proof
number of consecutive identical spins samplings considered as a proof
of convergence (default is 50)
sampling_period : int, optional
number of time steps between two spin sampling (default is 50)
Expand All @@ -592,9 +598,9 @@ def maximize(
(default is 10000)
agents : int, optional
number of vectors to make evolve at the same time (default is 128)
use_window : bool, optional
indicates whether to use the window as a stopping criterion or not
(default is True)
early_stopping : bool, optional
indicates whether to use the early stopping or not, thus making agents'
convergence a stopping criterion (default is True)
timeout : float | None, default=None
Time in seconds after which the simulation is stopped.
None means no timeout.
Expand Down Expand Up @@ -625,7 +631,7 @@ def maximize(
heated,
False,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand Down
12 changes: 6 additions & 6 deletions src/simulated_bifurcation/models/abc_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def optimize(
minimize: bool = True,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None
Expand All @@ -45,7 +45,7 @@ def optimize(
heated,
minimize,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand All @@ -60,7 +60,7 @@ def minimize(
heated: bool = False,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None
Expand All @@ -73,7 +73,7 @@ def minimize(
heated,
True,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand All @@ -88,7 +88,7 @@ def maximize(
heated: bool = False,
verbose: bool = True,
*,
use_window: bool = True,
early_stopping: bool = True,
sampling_period: int = 50,
convergence_threshold: int = 50,
timeout: Optional[float] = None
Expand All @@ -101,7 +101,7 @@ def maximize(
heated,
False,
verbose,
use_window=use_window,
early_stopping=early_stopping,
sampling_period=sampling_period,
convergence_threshold=convergence_threshold,
timeout=timeout,
Expand Down
2 changes: 1 addition & 1 deletion src/simulated_bifurcation/optimizer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

"""

from .convergence_checker import ConvergenceChecker
from .environment import get_env, reset_env, set_env
from .simulated_bifurcation_engine import SimulatedBifurcationEngine
from .simulated_bifurcation_optimizer import (
ConvergenceWarning,
SimulatedBifurcationOptimizer,
)
from .stop_window import StopWindow
from .symplectic_integrator import SymplecticIntegrator
Loading