# visualize/ising.py
"""Visualize the Ising model."""
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sb
from pyphi.substrate_generator import utils
from pyphi.substrate_generator.ising import energy
from pyphi.utils import all_states
[docs]
def plot_sigmoid(x, temperature=1.0, field=0.0, ax=None):
"""Plot the Ising activation probability against the input energy.
Parameters
----------
x : array_like
Input energies.
temperature : float, optional
Temperature of the logistic activation.
field : float, optional
External field (threshold) of the activation.
ax : matplotlib.axes.Axes, optional
Axes to draw into; the current axes by default.
Returns
-------
tuple
The Matplotlib figure and axes.
"""
y = utils.sigmoid(x, temperature=temperature, field=field)
ax = sb.lineplot(x=x, y=y, linewidth=3, ax=ax)
ax.set_title(f"T = {temperature}")
ax.vlines(x=0, ymin=0, ymax=1, color="grey", linewidth=1)
return ax.figure, ax
def _state_energies(weights, temperature, field, N=None, spin=0):
"""Energy and activation probability of one spin across all states."""
if N is None:
N = weights.shape[0]
else:
weights = weights[:N, :N]
rows = []
for state in all_states(N):
spin_state = utils.binary2spin(state)
# Probability that the spin is "on" in the next micro-timestep.
e = energy(spin, weights, spin_state)
rows.append(
{
"energy": e,
"probability": utils.sigmoid(e, temperature=temperature, field=field),
"state": "".join(map(str, state)),
}
)
return pd.DataFrame(rows)
[docs]
def plot(weights, temperature, field, N=None, spin=0):
"""Plot one spin's activation sigmoid with every state's input energy.
Parameters
----------
weights : numpy.ndarray
Coupling matrix.
temperature : float
Temperature of the logistic activation.
field : float
External field (threshold) of the activation.
N : int, optional
Use only the first ``N`` units of ``weights``.
spin : int, optional
The spin whose activation is plotted.
Returns
-------
tuple
The Matplotlib figure and axes.
"""
data = _state_energies(weights, temperature, field, N=N, spin=spin)
limit = np.max(np.abs(data["energy"]))
x = np.linspace(-limit, limit, num=200)
fig, ax = plt.subplots(figsize=(15, 6))
plot_sigmoid(x, temperature=temperature, field=field, ax=ax)
plot_inputs(data=data, x="energy", y="probability", label="state", ax=ax, sep=0.05)
return fig, ax