Source code for supervillain.observable.wrapping

from supervillain.observable import Scalar, Observable
import numpy as np

[docs]class TorusWrapping(Observable): r''' Both the :class:`~.Villain` and :class:`~.Worldline` formulations have integer-valued numbers that wrap the spatial torus. .. warning :: Unlike most observables these will NOT match${}^*$ between the different formulations. However, since they are both related to the global topology, we expect them to evolve quite slowly and suffer the longest autocorrelation times. ${}^*$They both have 0 expectation value by the discrete rotational lattice symmetries, but they don't have related physical motivation. '''
[docs] @staticmethod def Villain(S, phi, n): r''' The total wrapping in direction $\mu$ is given by the gauge holonomy .. math :: \texttt{TorusWrapping}_{\mu} = \sum n_\mu ''' return n.sum(axis=tuple(range(1, n.ndim)))
[docs] @staticmethod def Worldline(S, m): r''' The total wrapping in direction $\mu$ is given by the net particle flux in that direction .. math :: \texttt{TorusWrapping}_{\mu} = \frac{1}{N} \sum m_\mu where we divide by $N$ (the linear lattice size) because a single torus-wrapping worldline contributes one unit for each of the $N$ positions along direction $\mu$. ''' return m.sum(axis=tuple(range(1, m.ndim))) / S.Lattice.N
[docs]class WrappingSquared(Scalar, Observable): r''' The sum of squared torus-wrapping numbers over all directions, .. math :: \texttt{WrappingSquared} = \sum_\mu \texttt{TorusWrapping}_\mu^2. Unlike :class:`~.TorusWrapping` itself (which vanishes in expectation by symmetry), this is positive semi-definite and carries information about the size of topological fluctuations. It is D-agnostic: in D=2 it reduces to $\texttt{TorusWrapping}[0]^2 + \texttt{TorusWrapping}[1]^2 + \ldots$. However, like :class:`~.TorusWrapping` it will not match between the different formulations---the physical content is different. '''
[docs] @staticmethod def default(S, TorusWrapping): return (TorusWrapping**2).sum()