Newer
Older
from primo.reasoning.density import Density
import scipy.stats
import random
import math
from primo.reasoning import ContinuousNode
class LinearExponentialParameters(object):
def __init__(self, b0, b):
self.b0=b0
self.b=b
class LinearExponential(Density):
def __init__(self, node):
self.b={}
self.b0=0
self.node=node
def set_parameters(self,parameters):
self.b=parameters.b
self.b0=parameters.b0
def add_variable(self, variable):

Manuel Baum
committed
'''This method needs some serious reworking: Variables should not be denied
to be parents because of their value range. Instead it should be evaluated
if they can yield parameters for this distribution that are permitted. This
can in any case happen under bad influence coefficients'''
if( not isinstance(variable,ContinuousNode.ContinuousNode)):
raise Exception("Tried to add Variable as parent, but is not a ContinuousNode")
self.b[variable]=0.0
def get_probability(self,value, node_value_pairs):

Manuel Baum
committed
#Compute the offset for the density and displace the value accordingly
_lambda = self._compute_lambda_given_parents(dict(node_value_pairs))

Manuel Baum
committed
#Evaluate the displaced density at value
return _lambda*math.exp(-_lambda*value)
def _compute_lambda_given_parents(self, state):

Manuel Baum
committed
x = self.b0
for node in self.b.keys():
if node in state.keys():
x = x + self.b[node]*state[node]
_lambda=self.output_scale*1.0/(1.0+math.exp(-x*self.input_scale))
return _lambda

Manuel Baum
committed
def sample_global(self,state, lower_limit, upper_limit):
_lambda=self._compute_lambda_given_parents(state)

Manuel Baum
committed
distribution=scipy.stats.expon(loc=0,scale=1.0/_lambda)
lower_cdf=distribution.cdf(lower_limit)
upper_cdf=distribution.cdf(upper_limit)
sample_in_integral=random.uniform(lower_cdf, upper_cdf)
sample=distribution.ppf(sample_in_integral)
#sample=random.expovariate(_lambda)
#print "EXPO-SAMPLE: "+str(sample)+" at lambda: "+str(_lambda)
return sample