def build(*clauses,**kwargs): priorLea = kwargs.get('priorLea',None) # TODO: check no other args !! # PY3: def build(*clauses,priorLea=None): elseClauseResults = tuple(result for (cond,result) in clauses if cond is None) if len(elseClauseResults) > 1: raise Lea.Error("impossible to define more than one 'other' clause") if len(elseClauseResults) == 1: if priorLea is not None: raise Lea.Error("impossible to define together prior probabilities and 'other' clause") elseClauseResult = elseClauseResults[0] else: elseClauseResult = None normClauseLeas = tuple((Lea.coerce(cond),Lea.coerce(result)) for (cond,result) in clauses if cond is not None) condLeas = tuple(condLea for (condLea,resultLea) in normClauseLeas) # check that conditions are disjoint for (condLea1,condLea2) in genPairs(condLeas): if (condLea1&condLea2).isFeasible(): raise Lea.Error("clause conditions are not disjoint") # build the OR of all given conditions orCondsLea = Lea.reduce(or_,condLeas) isClauseSetComplete = orCondsLea.isTrue() if priorLea is not None: # prior distribution: determine elseClauseResult if isClauseSetComplete: # TODO check priorLea equivalent to self raise Lea.Error("forbidden to define prior probabilities for complete clause set") (pTrue,count) = orCondsLea._p(True) pFalse = count - pTrue priorAleaDict = dict(priorLea.getAlea().genVPs()) priorAleaCount = sum(priorAleaDict.values()) normAleaDict = dict(Mlea(*(resultLea for (condLea,resultLea) in normClauseLeas)).getAlea().genVPs()) normAleaCount = sum(normAleaDict.values()) valuesSet = frozenset(chain(priorAleaDict.keys(),normAleaDict.keys())) vps = [] for value in valuesSet: priorP = priorAleaDict.get(value,0) condP = normAleaDict.get(value,0) p = priorP*count*normAleaCount - condP*pTrue*priorAleaCount if not(0 <= p <= pFalse*normAleaCount*priorAleaCount): # Infeasible : probability represented by p goes outside range from 0 to 1 priorPFraction = ProbFraction(priorP,priorAleaCount) lowerPFraction = ProbFraction(condP*pTrue,count*normAleaCount) upperPFraction = ProbFraction(condP*pTrue+pFalse*normAleaCount,count*normAleaCount) raise Lea.Error("prior probability of '%s' is %s, outside the range [ %s , %s ]"%(value,priorPFraction,lowerPFraction,upperPFraction)) vps.append((value,p)) elseClauseResult = Lea.fromValFreqs(*vps) elif elseClauseResult is None: # check that clause set is complete if not isClauseSetComplete: # TODO? : assume a uniform prior distribution ? ... which values ? raise Lea.Error("incomplete clause set requires 'other' clause or prior probabilities") if elseClauseResult is not None: elseCondLea = ~orCondsLea normClauseLeas += ((elseCondLea,Lea.coerce(elseClauseResult)),) # note that orCondsLea is NOT extended with rCondsLea |= elseCondLea # so, in case of else clause (and only in this case), orCondsLea is NOT certainly true return Blea(*(Ilea(resultLea,condLea) for (condLea,resultLea) in normClauseLeas))
def __init__(self,nextStateLeaPerState): ''' initializes Chain instance's attributes; nextStateLeaPerState is a sequence of tuples (stateObj,nextStateLea) where stateObj is a state object (e.g. a string) and nextStateLea is a Lea instance giving probabilities of transition from stateObj to each state object ''' object.__init__(self) self._stateObjs = tuple(stateObj for (stateObj,nextStateLea) in nextStateLeaPerState) self._stateAleaDict = dict((stateObj,StateAlea(Lea.coerce(stateObj),self)) for stateObj in self._stateObjs) self._state = StateAlea(Lea.fromVals(*self._stateObjs),self) iterNextStateData = ((self._state==stateObj,nextStateLea) for (stateObj,nextStateLea) in nextStateLeaPerState) self._nextStateBlea = Blea.build(*iterNextStateData)
def nextState(self,fromState=None,n=1): ''' returns the StateAlea instance obtained after n transitions from initial state defined by the given fromState, instance of StateAlea if fromState is None, then the initial state is the uniform distribution of the declared states if n = 0, then this initial state is returned ''' if n < 0: raise Lea.Error("nextState method requires a positive value for argument 'n'") if fromState is None: fromState = self._state stateN = Lea.coerce(fromState).getAlea() while n > 0: n -= 1 stateN = self._nextStateBlea.given(self._state==stateN).getAlea() return StateAlea(stateN,self)
def __init__(self,*args): Lea.__init__(self) self._leaArgs = tuple(Lea.coerce(arg) for arg in args)
def __init__(self, *args): Lea.__init__(self) self._leaArgs = tuple(Lea.coerce(arg) for arg in args) counts = tuple(leaArg.getAlea()._count for leaArg in self._leaArgs) lcm = calcLCM(counts) self._factors = tuple(lcm // count for count in counts)