maxkw / evolution

0 stars 0 forks source link

Vectorization #17

Closed polyguo closed 7 years ago

polyguo commented 8 years ago

It might be a good idea to vectorize our model, most of our computation is extremely amenable to being expressed as matrix operations.

polyguo commented 8 years ago

prototype of vectorized observe_k: currently doesn't capture belief-dependent utility, such as ReciprocalAgent's

the following are matrices with the given dimensions

Utilities : Types x Position every type basically values some positions more than others, selfish like the firt position, for example Payoffs : Position x Actions Beta : Agents, must be col vector Likelihoods : RationalAgents x Agents x Types for those in world.models, but Agents x Agents x Types for agent.models Beliefs: RationalAgents x Agents x Types for those in world.models, but Agents x Agents x Types for agent.models Priors : Agents x Types rational_agents, list of world_id of agents that are of a rational type world_ids_2_rational_ids is a mapping from world_ids to the place in the canonical ordering of rational agents, returns a vector

first call is observe_k(world.models,observations,K,first_call = True)

from numpy import exp
def observe_k(models,observations,K, all_observers = []):
if K<0: return
Beliefs, Likelihoods, Priors = models

    for Payoffs, order, observers, action in observations:
        if not all_observers:
            #this only happens on the first call, when all_observers is []
            observers = world_ids_2_rational_ids(filter(lambda id: id in rational_agents,observers))

        #utility per type and action: Types x Actions
        expUPBeta = exp(dot(Utilities[:][order],Payoffs[order])*Beta) # beta must be column

        #softmax utility
        #T x Actions
        U = expUPBeta/expUPBeta.sum(axis=1) # the denom must be a column

        #account for tremble
        U = U*tremble+Uniform(len(players))*(1-tremble)

        #update Likelihoods
        Likelihoods[Observers][order[0]] *= U[:][action]

        #elementwise product of likelihood and prior
        LP = Likelihoods[Observers][order[0]]*Priors[Observers]

        #update beliefs
        Beliefs[Observers][decider] = LP/LP.sum(axis = 1)

    if not all_observers:
    #if all_observers is [] it MUST be the first call
        for observation in observations:
            for observer in observation[3]:
                observers.append(observer)
        observers = set(observers)
        for observer in filter(lambda id: id in rational_agents):
            observe_k(world.agents[observer].models, observations, K-1, observers)
    else:
        for observer in observers:
            observe_k(world.agents[observer].models, observations, K-1, observers)`