Beispiel #1
0
 def __mul__(self, right):
     """ A true multiplication of two potentials would be defined as X * Y = Z where the sets of variables z = x U y.  We would then identify the instantiations of x and y that are consistent with z and Z(z) = X(x)Y(y).  We are generally going to be multiplying sepset potentials by clique potentials where the variables of a setpset potential are a subset of the variables of the clique.  Therefore we are going to assume in this operation that right's variables are a subset of self's.
     """
     # right should only be a DiscreteDistribution or a ContinuousDistribution if it is a subset and it should be __imul__
     assert(not isinstance(right, DiscreteDistribution) and not isinstance(right, ConditionalDiscreteDistribution)), \
           "Attempt to Multiply Potential with incompatible type: Discrete or Conditional"
     if isinstance(right, (int, float, complex, long)):
         potential = copy.deepcopy(self)
         potential.table *= right
     else:
         nodeSet = self.__nodeSet_.union(right.__nodeSet_)
         potential = Potential(list(nodeSet))
         selfValues = [potential.nodes.index(node) for node in self.nodes]
         rightValues = [potential.nodes.index(node) for node in right.nodes]
         # Store the following lists so we don't have to recompute them on every iteration
         potAxes = range(potential.nDims)
         selfAxes = range(self.nDims)
         rightAxes = range(right.nDims)
         #OPTIMIZE: Should be able to do this without blindly iterating through dimensions.
         for seq in Utilities.sequence_generator(potential.dims):
             #OPTIMIZE: Could access the table directly, but would break down our abstraction
             potIndex = potential.generate_index(seq, potAxes)
             selfIndex = self.generate_index(seq[selfValues], selfAxes)
             rightIndex = right.generate_index(seq[rightValues], rightAxes)
             potential[potIndex] = self[selfIndex] * right[rightIndex]
     return potential
 def __mul__(self, right):
     """ A true multiplication of two potentials would be defined as X * Y = Z where the sets of variables z = x U y.  We would then identify the instantiations of x and y that are consistent with z and Z(z) = X(x)Y(y).  We are generally going to be multiplying sepset potentials by clique potentials where the variables of a setpset potential are a subset of the variables of the clique.  Therefore we are going to assume in this operation that right's variables are a subset of self's.
     """
     # right should only be a DiscreteDistribution or a ContinuousDistribution if it is a subset and it should be __imul__
     assert(not isinstance(right, DiscreteDistribution) and not isinstance(right, ConditionalDiscreteDistribution)), \
           "Attempt to Multiply Potential with incompatible type: Discrete or Conditional"
     if isinstance(right, (int, float, complex, long)):
         potential = copy.deepcopy(self)
         potential.table *= right
     else:
         nodeSet = self.__nodeSet_.union(right.__nodeSet_)
         potential = Potential(list(nodeSet))
         selfValues = [potential.nodes.index(node) for node in self.nodes]
         rightValues = [potential.nodes.index(node) for node in right.nodes]
         # Store the following lists so we don't have to recompute them on every iteration
         potAxes = range(potential.nDims)
         selfAxes = range(self.nDims)
         rightAxes = range(right.nDims)
         #OPTIMIZE: Should be able to do this without blindly iterating through dimensions.
         for seq in Utilities.sequence_generator(potential.dims):
             #OPTIMIZE: Could access the table directly, but would break down our abstraction
             potIndex = potential.generate_index(seq, potAxes)
             selfIndex = self.generate_index(seq[selfValues], selfAxes)
             rightIndex = right.generate_index(seq[rightValues], rightAxes)
             potential[potIndex] = self[selfIndex] * right[rightIndex]
     return potential
Beispiel #3
0
 def marginalize(self, other):
     """ Return a new potential that is the marginalization of this potential given other.  This identifies the instantiations of self (s1,s2,...,sn) that are consistent with other and sum self(s1) + self(s2) + ... + self(sn).
     """
     new = copy.deepcopy(other)
     intersect = self.__nodeSet_.intersection(new.__nodeSet_)
     newAxes = range(new.nDims)
     sequence = Utilities.sequence_generator(other.dims)
     for seq in sequence:
         index = self.generate_index_node(seq, intersect)
         newIndex = new.generate_index(seq, newAxes)
         val = self[index]
         if isinstance(val, ndarray):
             val = val.sum()
         new[newIndex] = val
     return new
 def marginalize(self, other):
     """ Return a new potential that is the marginalization of this potential given other.  This identifies the instantiations of self (s1,s2,...,sn) that are consistent with other and sum self(s1) + self(s2) + ... + self(sn).
     """
     new = copy.deepcopy(other)
     intersect = self.__nodeSet_.intersection(new.__nodeSet_)
     newAxes = range(new.nDims)
     sequence = Utilities.sequence_generator(other.dims)
     for seq in sequence:
         index = self.generate_index_node(seq, intersect)
         newIndex = new.generate_index(seq, newAxes)
         val = self[index]
         if isinstance(val, ndarray):
             val = val.sum()
         new[newIndex] = val
     return new
Beispiel #5
0
 def __imul__(self, right):
     """ This is the same operation as __mul__ except that if right.nodes is a subset of self.nodes, we do the multiplication in place, because there is no reason to make a copy, which wastes time and space.
     """
     if isinstance(right, (int, float, complex, long)):
         self.table *= right
     # FIXME: should be right.__nodeSet_ but doesn't work when right is DiscreteDistribution
     elif self.__nodeSet_.issuperset(right.nodes):
         #OPTIMIZE: There must be a way to do this without iterating over every value of table
         selfAxes = [self.nodes.index(node) for node in right.nodes]
         rightAxes = range(right.nDims)
         for seq in Utilities.sequence_generator(right.dims):
             selfIndex = self.generate_index(seq, selfAxes)
             #OPTIMIZE: Could index right.table directly, but this upholds our abstraction barrier
             rightIndex = right.generate_index(seq, rightAxes)
             self[selfIndex] *= right[rightIndex]
     else:
         """ If potential will be over a different set of variables after multiplication, might as well use full __mul__ version, which copies.
         """
         self = self.__mul__(right)
     return self
 def __imul__(self, right):
     """ This is the same operation as __mul__ except that if right.nodes is a subset of self.nodes, we do the multiplication in place, because there is no reason to make a copy, which wastes time and space.
     """
     if isinstance(right, (int, float, complex, long)):
         self.table *= right
     # FIXME: should be right.__nodeSet_ but doesn't work when right is DiscreteDistribution
     elif self.__nodeSet_.issuperset(right.nodes):
         #OPTIMIZE: There must be a way to do this without iterating over every value of table
         selfAxes = [self.nodes.index(node) for node in right.nodes]
         rightAxes = range(right.nDims)
         for seq in Utilities.sequence_generator(right.dims):
             selfIndex = self.generate_index(seq, selfAxes)
             #OPTIMIZE: Could index right.table directly, but this upholds our abstraction barrier
             rightIndex = right.generate_index(seq, rightAxes)
             self[selfIndex] *= right[rightIndex]
     else:
         """ If potential will be over a different set of variables after multiplication, might as well use full __mul__ version, which copies.
         """
         self = self.__mul__(right)
     return self