Skip to content
Snippets Groups Projects
LinearExponential.py 2.24 KiB
Newer Older
from primo.reasoning.density import Density
import scipy.stats
import random
import math
from primo.reasoning import ContinuousNode

class LinearExponentialParameters(object):
        

class LinearExponential(Density):
    def __init__(self, node):
        self.b={}
        self.b0=0
        self.node=node
        
Manuel Baum's avatar
Manuel Baum committed
        self.input_scale=1.0
        self.output_scale=4.0
        
    def set_parameters(self,parameters):
        self.b=parameters.b
        self.b0=parameters.b0
        
    def add_variable(self, variable):
        '''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):
        
        #Compute the offset for the density and displace the value accordingly
Manuel Baum's avatar
Manuel Baum committed
        _lambda = self._compute_lambda_given_parents(dict(node_value_pairs))
        #Evaluate the displaced density at value
        return _lambda*math.exp(-_lambda*value)
    def _compute_lambda_given_parents(self, state):
        x = self.b0
        for node in self.b.keys():
            if node in state.keys():
                x = x + self.b[node]*state[node]
Manuel Baum's avatar
Manuel Baum committed
        _lambda=self.output_scale*1.0/(1.0+math.exp(-x*self.input_scale))
    def sample_global(self,state, lower_limit, upper_limit):
        _lambda=self._compute_lambda_given_parents(state)
        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)
Manuel Baum's avatar
Manuel Baum committed
        #print "EXPO-SAMPLE: "+str(sample)+" at lambda: "+str(_lambda)
        return sample