def run_univariate_function(name, symbol_fmt, func):
    print('\n*************************************')
    print('Testing {} function'.format(name))

    # PsychSim elements
    world = World()
    agent = Agent('The Agent')
    world.addAgent(agent)

    # gets samples from real non-linear function
    x_params, y_params, sample_values = \
        get_bivariate_samples(func, MIN_X, MAX_X, MIN_Y, MAX_Y, NUM_SAMPLES, NUM_SAMPLES)
    sample_mean = np.nanmean(sample_values)

    # create two features: one holding the variable, the other the result (dependent)
    var_x = world.defineState(agent.name, 'var_x', float, lo=MIN_X, hi=MAX_X)
    var_y = world.defineState(agent.name, 'var_y', float, lo=MIN_Y, hi=MAX_Y)
    result = world.defineState(agent.name,
                               'result',
                               float,
                               lo=np.min(sample_values),
                               hi=np.max(sample_values))
    world.setFeature(result, 0)

    # create action that is approximates the function, storing the result in the result feature
    action = agent.addAction({'verb': 'operation', 'action': name})
    tree = makeTree(
        tree_from_bivariate_samples(result, var_x, var_y, x_params, y_params,
                                    sample_values))
    world.setDynamics(result, action, tree)

    world.setOrder([agent.name])

    np.random.seed(SEED)
    values_original = []
    values_approx = []
    for i in range(NUM_TEST_SAMPLES):
        # gets random sample parameters
        x = MIN_X + np.random.rand() * (MAX_X - MIN_X)
        y = MIN_Y + np.random.rand() * (MAX_Y - MIN_Y)

        # sets variable and updates result
        world.setFeature(var_x, x)
        world.setFeature(var_y, y)
        world.step()

        real = func(x, y)
        psych = world.getValue(result)

        print('{:3}: {:30} | Expected: {:10.2f} | PsychSim: {:10.2f}'.format(
            i, symbol_fmt.format(x, y), real, psych))
        values_original.append(real)
        values_approx.append(psych)

    # gets error stats
    rmse = np.sqrt(np.mean((np.array(values_approx) - values_original)**2))
    print('=====================================')
    print('RMSE      = {:.3f}'.format(rmse))
    print('\nPress \'Enter\' to continue...')
    input()
Exemple #2
0
    world = World()
    agent = Agent('Agent')
    world.addAgent(agent)

    # add feature to world
    feat = world.defineState(agent.name, 'x', float, lo=LOW, hi=HIGH)

    print('====================================')
    print('High:\t{}'.format(HIGH))
    print('Low:\t{}'.format(LOW))
    print('Bins:\t{}'.format(NUM_BINS))

    print('\nSamples:')
    values_original = []
    values_discrete = []
    for i in range(NUM_SAMPLES):
        num = np.random.uniform(LOW, HIGH)
        world.setFeature(feat, num)

        before = world.getValue(feat)
        discretize_feature_in_place(world, feat, NUM_BINS)
        after = world.getValue(feat)

        print('{:.3f}\t-> {}'.format(before, after))
        values_original.append(before)
        values_discrete.append(after)

        # calculates RMSE
    rmse = np.sqrt(np.mean((np.array(values_discrete) - values_original)**2))
    print('\nRMSE: {:.3f}'.format(rmse))
    # define order (parallel execution)
    world.setOrder([{ag_producer.name, ag_consumer.name}])

    # sets consumer belief that producer is at half-capacity, making it believe that asking more has more advantage
    # - in reality, producer is always at full capacity, so best strategy would be to always ask less
    ag_consumer.setBelief(var_half_cap, True)
    ag_consumer.setAttribute(
        'static', True
    )  # set to static so that beliefs never change (to their real value)

    total_rwd = 0
    for i in range(NUM_STEPS):
        logging.info('====================================')
        logging.info('Step {}'.format(i))
        step = world.step()
        reward = ag_consumer.reward()
        logging.info('Half capacity:\t\t{}'.format(
            world.getValue(var_half_cap)))
        logging.info('Asked amount:\t\t{}'.format(
            world.getValue(var_ask_amnt)))
        logging.info('Received amount:\t{}'.format(
            world.getValue(var_rcv_amnt)))
        logging.info('Consumer reward:\t{}'.format(reward))
        total_rwd += reward

        logging.info('________________________________')
        # world.explain(step, level=2)# todo step does not provide outcomes anymore

    logging.info('====================================')
    logging.info('Total reward: {0}'.format(total_rwd))
    world.setDynamics(pos, action, tree)

    # define rewards (maximize position, i.e., always go right)
    agent.setReward(maximizeFeature(pos, agent.name), 1)

    # set order
    world.setOrder([agent.name])

    # agent has initial beliefs about its position, which will be updated after executing actions
    agent.omega = {actionKey(agent.name)}  # todo should not need this
    agent.setBelief(pos, Distribution({10: 0.5, 12: 0.5}))
    # agent.setBelief(pos, 10, get_true_model_name(agent))

    print('====================================')
    print('Initial beliefs:')
    world.printBeliefs(agent.name)

    for i in range(MAX_STEPS):
        print('====================================')
        print('Current pos: {0}'.format(world.getValue(pos)))

        # decision: left, right or no-move?
        step = world.step()

        # prints all models and beliefs
        print('____________________________________')
        print("Updated beliefs:")
        world.printBeliefs(agent.name)
        print('____________________________________')

def setup():
    global args

    np.random.seed(args.seed)
    # create world and add agents
    world = World()
    world.memory = False
    world.parallel = args.parallel
    agents = []
    agent_features = {}
    for ag in range(args.agents):
        agent = Agent('Agent' + str(ag))
        world.addAgent(agent)
        agents.append(agent)

        # set agent's params
        agent.setAttribute('discount', 1)
        agent.setHorizon(args.horizon)

        # add features, initialize at random
        features = []
        agent_features[agent] = features
        for f in range(args.features_agent):
            feat = world.defineState(agent.name, 'Feature{}'.format(f), int, lo=0, hi=1000)
            world.setFeature(feat, np.random.randint(0, MAX_FEATURE_VALUE))
            features.append(feat)

        # set random reward function
        agent.setReward(maximizeFeature(np.random.choice(features), agent.name), 1)

        # add mental copy of true model and make it static (we do not have beliefs in the models)
        agent.addModel(get_fake_model_name(agent), parent=get_true_model_name(agent))
        agent.setAttribute('static', True, get_fake_model_name(agent))

        # add actions
        for ac in range(args.actions):
            action = agent.addAction({'verb': '', 'action': 'Action{}'.format(ac)})
            i = ac
            while i + args.features_action < args.features_agent:

                weights = {}
                for j in range(args.features_action):
                    weights[features[i + j + 1]] = 1
                tree = makeTree(multi_set_matrix(features[i], weights))
                world.setDynamics(features[i], action, tree)

                i += args.features_action

    # define order
    world.setOrder([set(ag.name for ag in agents)])

    for agent in agents:
        # test belief update:
        # - set a belief in one feature to the actual initial value (should not change outcomes)
        # world.setModel(agent.name, Distribution({True: 1.0}))
        rand_feat = np.random.choice(agent_features[agent])
        agent.setBelief(rand_feat, world.getValue(rand_feat))
        print('{} will always observe {}={}'.format(agent.name, rand_feat, world.getValue(rand_feat)))

    # set mental model of each agent in all other agents
    for i in range(args.agents):
        for j in range(i + 1, args.agents):
            world.setMentalModel(agents[i].name, agents[j].name, Distribution({get_fake_model_name(agents[j]): 1}))
            world.setMentalModel(agents[j].name, agents[i].name, Distribution({get_fake_model_name(agents[i]): 1}))

    return world