/usr/lib/python3/dist-packages/csb/statmech/ensembles.py is in python3-csb 1.2.3+dfsg-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | """
Statistical Ensembles
"""
from csb.numeric import log, exp
from abc import ABCMeta, abstractmethod
class StatisticalEnsemble(object):
__metaclass__ = ABCMeta
def __call__(self, raw_energies):
return exp(-self.energy(raw_energies))
def log_prob(self, raw_energies):
return -self.energy(raw_energies)
@abstractmethod
def energy(self, raw_energies):
"""
Transforms the raw energies as if they were observed
in this statistical ensemble
"""
pass
def gradient(self, raw_energies):
raise NotImplementedError()
class BoltzmannEnsemble(StatisticalEnsemble):
def __init__(self, beta=1.):
self._beta = float(beta)
@property
def beta(self):
"""
Inverse temperature
"""
return self._beta
@beta.setter
def beta(self, value):
value = float(value)
if value <= 0.:
raise ValueError("Inverse temperature {0} < 0".formate(value))
self._beta = value
def energy(self, raw_energies):
return raw_energies * self._beta
class FermiEnsemble(BoltzmannEnsemble):
def __init__(self, beta=1., e_max=0.):
super(FermiEnsemble, self).__init__(beta)
self._e_max = float(e_max)
@property
def e_max(self):
"""
Maximum energy
"""
return self._e_max
@e_max.setter
def e_max(self, value):
self._e_max = float(value)
def energy(self, raw_energies):
from numpy import isinf
if isinf(self.beta):
m = (raw_energies >= self.e_max).astype('f')
return - m * log(0.)
else:
x = 1 + exp(self.beta * (raw_energies - self.e_max))
return log(x)
class TsallisEnsemble(StatisticalEnsemble):
def __init__(self, q=1., e_min=0.):
self._q = q
self._e_min = e_min
@property
def q(self):
"""
q-analoge of the temperature
"""
return self._q
@q.setter
def q(self, value):
if value <= 0.:
raise ValueError("Inverse temperature {0} < 0".formate(value))
self._q = value
@property
def e_min(self):
"""
lower bound of the energy
"""
return self._e_min
@e_min.setter
def e_min(self, value):
self._e_min = value
def energy(self, raw_energies):
q = self.q
e_min = self.e_min
if (q < 1 + 1e-10):
return raw_energies * q
else:
return log(1 + (raw_energies - e_min) * (q - 1)) * q / (q - 1) + e_min
class CompositeEnsemble(StatisticalEnsemble):
def __init__(self, ensembles=[]):
self._ensembles = ensembles
@property
def ensembles(self):
"""
Collection of statistical ensembles
"""
return self._ensembles
@ensembles.setter
def ensembles(self, value):
if not isinstance(value, list):
if len(value) > 0:
if not isinstance(value[0], StatisticalEnsemble):
raise ValueError("Not a list of statistical ensembles")
else:
self._enesmbles = value
else:
self._enesmbles = value
def energy(self, raw_energies):
return sum([self._ensembles[i].energy(raw_energies[i])
for i in range(len(self.ensembles))], 0)
def gradient(self, raw_energies):
return sum([self._ensembles[i].gradient(raw_energies[i])
for i in range(len(self.ensembles))], 0)
|