Source code for rfbp.MagP64

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

from __future__ import print_function
from __future__ import division

import numpy as np
from scipy.special import erf
from ReplicatedFocusingBeliefPropagation.rfbp.Mag import BaseMag

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


[docs]class MagP64 (BaseMag): def __init__ (self, x): ''' MagP64 specialization. The `MagP64` type allows fast executions with inexact outcomes by neglecting all `tanh` operations. Parameters ---------- x : float Value to magnetify Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation.rfbp.Mag import MagP64 >>> >>> x = np.random.uniform(low=0., high=1) >>> m = MagP64(x) ''' super(MagP64, self).__init__(x) @property def value (self): ''' Return the mag value Returns ------- x : float In MagP64 the value is equal to the magnetization since the tanh operation is neglected Example ------- >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> x = np.random.uniform(low=0, high=1.) >>> m = MagP64(x) >>> assert np.isclose(m.mag, x) >>> assert np.isclose(m.value, x) ''' return self.mag @property def magformat (self): ''' Return the mag description Returns ------- plain : str The MagP64 type corresponds to a plain operation Example ------- >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> m = MagP64(3.14) >>> m.magformat 'plain' ''' return 'plain'
[docs] @staticmethod def convert (x): ''' Convert a float to a mag value (as a constructor) Parameters ---------- x : float The number to convert Returns ------- m : MagP64 Convert any-number to a MagP64 type Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> >>> x = np.random.uniform(low=0., high=10) >>> m1 = MagP64.convert(x) >>> m2 = MagP64(x) >>> assert m1.mag == m2.mag >>> assert m1.value == m2.value ''' return MagP64(x)
[docs] @staticmethod def couple (x1, x2): ''' Combine two mags as diff / sum Parameters ---------- x1 : float The first element of the operation x2 : float The second element of the operation Returns ------- x : float In MagP64 the value is equal to the magnetization since the tanh operation is neglected Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=10) >>> mx = MagP64.couple(x, y) >>> my = MagP64.couple(y, x) >>> assert np.isclose(abs(mx.mag), abs(my.mag)) >>> assert np.isclose(abs(mx.value), abs(my.value)) ''' return MagP64( (x1 - x2)/(x1 + x2) )
[docs] @staticmethod def mtanh (x): ''' Perform tanh on magnetization value (MagP64(tanh(x)) in this case) Parameters ---------- x : float The input value Returns ------- m : MagP64 The MagP64 version of the tanh(x) Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> >>> x = np.random.uniform(low=0., high=10) >>> mx = MagP64.mtanh(x) >>> assert 0 <= mx.mag <= 1 >>> assert np.isclose(mx.mag, np.tanh(x)) ''' return MagP64(np.tanh(x))
[docs] @staticmethod def merf (x): ''' Perform erf on magnetization value (MagP64(erf(x)) in this case) Parameters ---------- x : float The input value Returns ------- m : MagP64 The MagP64 version of the erf(x) Example ------- >>> import numpy as np >>> from scipy.special import erf >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> >>> x = np.random.uniform(low=0., high=10) >>> mx = MagP64.merf(x) >>> assert 0 <= mx.mag <= 1 >>> assert np.isclose(mx.mag, erf(x)) ''' return MagP64(erf(x))
[docs] @BaseMag._require_mag def __mod__ (self, m): ''' Clip value in [-1, 1]. Parameters ---------- m : MagP64 The input value Returns ------- m : MagP64 The MagP64 of the operation between the two mags. The clip operation is computed as np.clip( (self.mag + m.mag) / (1. + self.mag * m.mag), -1., 1.) Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=10) >>> m1 = MagP64(x) >>> m2 = MagP64(y) >>> mx = m1 % m2 >>> my = m2 % m1 >>> assert np.isclose(mx.mag, my.mag) >>> assert np.isclose(mx.value, my.value) >>> assert -1. <= mx.mag <= 1. >>> assert -1. <= my.mag <= 1. >>> assert -1. <= mx.value <= 1. >>> assert -1. <= my.value <= 1. ''' return self.__class__(np.clip( (self.mag + m.mag) / (1. + self.mag * m.mag), -1., 1.))
[docs] @BaseMag._require_mag def __xor__ (self, m): ''' Mag product Parameters ---------- m : MagP64 The input value Returns ------- m : MagP64 The product of mags Example ------- >>> import numpy as np >>> from ReplicatedFocusingBeliefPropagation import MagP64 >>> x = np.random.uniform(low=0., high=10) >>> y = np.random.uniform(low=0., high=10) >>> m1 = MagP64(x) >>> m2 = MagP64(y) >>> mx = m1 ^ m2 >>> my = m2 ^ m1 >>> assert np.isclose(mx.mag, my.mag) >>> assert np.isclose(mx.value, my.value) ''' return self.__class__(self.mag * m.mag)