Source code for rfbp.MagT64

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
from __future__ import division

import numpy as np
from ReplicatedFocusingBeliefPropagation.rfbp.Mag import BaseMag
from ReplicatedFocusingBeliefPropagation.rfbp.atanherf import atanherf

__author__  = ['Nico Curti', "Daniele Dall'Olio"]
__email__   = ['nico.curti2@unibo.it', 'daniele.dallolio@studio.unibo.it']


[docs]class MagT64 (BaseMag): def __init__ (self, x, mInf=30.): ''' MagP64 specialization. The `MagT64` exactly follows all theoretical equations with no further approximation, which necessarily causes slower executions. In practice it computes the tanh of each numerical value. Parameters ---------- x : float Value to magnetify mInf : float (default = 30.) Clip value Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation.rfbp.Mag import MagT64 >>> >>> x = np.random.uniform(low=0., high=1) >>> m = MagT64(x) ''' super(MagT64, self).__init__(x) self.mInf = mInf @property def value(self): ''' Return the mag value Returns ------- x : float In MagT64 the value is equal to the tanh(x) Example ------- >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> x = np.random.uniform(low=0, high=1.) >>> m = MagT64(x) >>> assert np.isclose(m.mag, x) >>> assert np.isclose(m.value, np.tanh(x)) ''' return np.tanh(self.mag) @property def magformat (self): ''' Return the mag description Returns ------- tanh : str The MagT64 type corresponds to a tanh operation Example ------- >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> m = MagT64(3.14) >>> m.magformat 'tanh' ''' return 'tanh'
[docs] @staticmethod def convert (x): ''' Convert a float to a mag value (as a constructor) Parameters ---------- x : float The number to convert Returns ------- m : MagT64 Convert any-number to a MagT64 type Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> mx = MagT64.convert(x) >>> assert -30. <= mx.mag <= 30. >>> assert np.isclose(mx.mag, np.arctanh(x)) >>> assert np.isclose(mx.value, x) ''' return MagT64(np.clip(np.arctanh(x), -30., 30.))
[docs] @staticmethod def couple (x1, x2): ''' Combine two mags Parameters ---------- x1 : float The first element of the operation x2 : float The second element of the operation Returns ------- x : float Mags combination as np.log(x1 / x2) * .5 Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=10) >>> mx = MagT64.couple(x, y) >>> my = MagT64.couple(y, x) >>> assert np.isclose(abs(mx.mag), abs(my.mag)) >>> assert np.isclose(abs(mx.value), abs(my.value)) ''' return MagT64.convert(np.log(x1 / x2) * .5)
[docs] @staticmethod def mtanh (x): ''' Perform tanh on magnetization value (MagT64(x) in this case) Parameters ---------- x : float The input value Returns ------- m : MagT64 The MagT64 version of the tanh(x) Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> mx = MagT64.mtanh(x) >>> assert np.isclose(mx.mag, x) >>> assert np.isclose(mx.value, np.tanh(x)) ''' return MagT64(x)
[docs] @staticmethod def merf (x): ''' Perform erf on magnetization value (MagT64(erf(x)) in this case) Parameters ---------- x : float The input value Returns ------- m : MagT64 The MagT64 version of the erf(x) Example ------- >>> import numpy as np >>> from scipy.special import erf >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> mx = MagT64.merf(x) >>> assert np.isclose(mx.mag, np.arctanh(erf(x))) ''' return MagT64( atanherf(x) )
[docs] @BaseMag._require_mag def __mod__ (self, m): ''' In this case the mod operation corresponds to a sum of mags Parameters ---------- m : MagT64 The input value Returns ------- m : MagT64 The MagT64 of the operation between the two mags. The mod operation corresponds to self.mag + m.mag Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=1) >>> m1 = MagT64(x) >>> m2 = MagT64(y) >>> >>> mx = m1 % m2 >>> my = m2 % m1 >>> assert np.isclose(mx.mag, my.mag) >>> assert np.isclose(mx.value, my.value) >>> >>> null = MagT64(0.) >>> mx = m1 % null >>> assert np.isclose(mx.mag, m1.mag) >>> assert np.isclose(mx.value, m1.value) ''' return self.__class__(self.mag + m.mag)
[docs] @BaseMag._require_mag def __xor__ (self, m): ''' Mag product Parameters ---------- m : MagT64 The input value Returns ------- m : MagT64 The product of mags Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagT64 >>> >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=1) >>> m1 = MagT64(x) >>> m2 = MagT64(y) >>> >>> >>> mx = m1 ^ m2 >>> my = m2 ^ m1 >>> assert np.isclose(mx.mag, my.mag) >>> assert np.isclose(mx.value, my.value) >>> >>> mx = (-m1) ^ (-m2) >>> my = (-m2) ^ (-m1) >>> assert not np.isclose(mx.mag, my.mag) >>> assert not np.isclose(mx.value, my.value) >>> >>> null = MagT64(0.) >>> mx = m1 ^ null >>> assert np.isclose(mx.mag, 0.) >>> assert np.isclose(mx.value, 0.) >>> >>> mx = m1 ^ MagT64(float('inf')) >>> assert np.isclose(mx.mag, m1.mag) >>> assert np.isclose(mx.value, m1.value) ''' ax, ay = (self.mag, m.mag) if ax >= ay and ax >= -ay: t1 = 2. * ay elif ax >= ay and ax < -ay: t1 = -2. * ay elif ax < ay and ax >= -ay: t1 = 2. * ax else: t1 = -2. * ay if np.isinf(ax) or np.isinf(ay): t2 = 0. else: t2 = np.log((np.exp(2 * np.abs(ax + ay)) + 1) / (np.exp(2 * np.abs(ax - ay)) + 1)) + 2 * np.abs(ax - ay) - 2 * np.abs(ax + ay) return self.__class__(np.mean((t1, t2)))