Adaptive tracking from above and below#

This file shows how to interleave multiple Tracker objects using expyfun.stimuli.TrackerDealer to simultaneously approach a threshold from both above and below.

@author: maddycapp27

import matplotlib.pyplot as plt
import numpy as np

from expyfun.analyze import sigmoid
from expyfun.stimuli import TrackerDealer, TrackerUD

# define parameters of modeled subject (using sigmoid probability)
true_thresh = 30  # true thresholds for trial types 1 and 2
slope = 0.1
chance = 0.5

Defining Tracker Parameters#

In this example, the tracker parameters are the same for each instance of the up-down adaptive tracker except for the start value. Each start value in the list will be given to a different tracker. The other parameters are defined such that the step sizes vary for both up v. down (the up step size is larger by a factor of 3) and based on the number of reversals (the first element in each list is the step size until the number of reversals dictated by the second element in change_criteria have occurred (i.e. the up step size will be 9 until 5 reversals have occurred, then the up step size will be 3.))

up = 1
down = 1
step_size_up = [9, 3]
step_size_down = [3, 1]
stop_reversals = 30
stop_trials = np.inf
start_value = [15, 45]
change_indices = [5]
change_rule = "reversals"
x_min = 0
x_max = 90


# callback function that prints to console
def callback(event_type, value=None, timestamp=None):
    print((str(event_type) + ":").ljust(40) + str(value))


# parameters for the tracker dealer
max_lag = 2
pace_rule = "reversals"
rng_dealer = np.random.RandomState(4)  # random seed for selecting trial type

Initializing and Running Trackers#

The two trackers in this example use all of the same parameters except for the start value and then are passed into the dealer. After the dealer is created, the type of trial with the start value above or below the true threshold (returned as an index) and trial level for that trial can be acquired.

# initialize two tracker objects--one for each start value
tr_ud = [
    TrackerUD(
        callback,
        up,
        down,
        step_size_up,
        step_size_down,
        stop_reversals,
        stop_trials,
        sv,
        change_indices,
        change_rule,
        x_min,
        x_max,
    )
    for sv in start_value
]

# initialize TrackerDealer object
td = TrackerDealer(callback, tr_ud, max_lag, pace_rule, rng_dealer)

# Initialize human state
rng_human = np.random.RandomState(1)  # random seed for modeled subject

for _, level in td:
    # Get information of which trial type is next and what the level is at
    # that time from TrackerDealer
    td.respond(
        rng_human.rand() < sigmoid(level - true_thresh, lower=chance, slope=slope)
    )
tracker_identify:                       {"tracker_id": "139642810042208-1721686490565335", "tracker_type": "TrackerUD"}
tracker_139642810042208-1721686490565335_init:{"callback": null, "up": 1, "down": 1, "step_size_up": [9.0, 3.0], "step_size_down": [3.0, 1.0], "stop_reversals": 30, "stop_trials": Infinity, "start_value": 15, "change_indices": [5], "change_rule": "reversals", "x_min": 0.0, "x_max": 90.0, "repeat_limit": "reversals"}
tracker_identify:                       {"tracker_id": "139642810040720-1721686490565511", "tracker_type": "TrackerUD"}
tracker_139642810040720-1721686490565511_init:{"callback": null, "up": 1, "down": 1, "step_size_up": [9.0, 3.0], "step_size_down": [3.0, 1.0], "stop_reversals": 30, "stop_trials": Infinity, "start_value": 45, "change_indices": [5], "change_rule": "reversals", "x_min": 0.0, "x_max": 90.0, "repeat_limit": "reversals"}
dealer_identify:                        {"dealer_id": 139642810042304}
dealer_139642810042304_init:            {"trackers": ["139642810042208-1721686490565335", "139642810040720-1721686490565511"], "shape": [2], "max_lag": 2, "pace_rule": "reversals"}
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810040720-1721686490565511_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810040720-1721686490565511_respond:False
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:True
tracker_139642810042208-1721686490565335_respond:False
tracker_139642810040720-1721686490565511_stop:{"responses": [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1], "reversals": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 3, 4, 5, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 0, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 14, 0, 0, 15, 16, 17, 0, 18, 0, 0, 19, 20, 21, 22, 0, 23, 24, 0, 25, 26, 27, 0, 28, 0, 0, 0, 29, 30], "x": [45.0, 42.0, 39.0, 36.0, 33.0, 30.0, 27.0, 24.0, 21.0, 18.0, 27.0, 24.0, 21.0, 18.0, 15.0, 24.0, 21.0, 24.0, 23.0, 22.0, 25.0, 28.0, 27.0, 26.0, 29.0, 32.0, 31.0, 30.0, 29.0, 32.0, 31.0, 30.0, 29.0, 28.0, 27.0, 26.0, 25.0, 24.0, 23.0, 22.0, 25.0, 28.0, 27.0, 26.0, 25.0, 28.0, 27.0, 30.0, 33.0, 32.0, 31.0, 30.0, 33.0, 32.0, 35.0, 34.0, 33.0, 36.0, 35.0, 34.0, 37.0, 36.0, 39.0, 42.0, 41.0, 40.0, 39.0, 38.0, 41.0]}
tracker_139642810042208-1721686490565335_stop:{"responses": [1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1], "reversals": [0, 1, 0, 2, 0, 0, 3, 4, 5, 6, 0, 0, 7, 8, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 0, 17, 18, 19, 0, 20, 0, 0, 0, 0, 0, 0, 21, 22, 0, 0, 0, 23, 24, 25, 26, 0, 0, 27, 28, 0, 0, 0, 0, 29, 30], "x": [15.0, 12.0, 21.0, 30.0, 27.0, 24.0, 21.0, 30.0, 27.0, 30.0, 29.0, 28.0, 27.0, 30.0, 29.0, 28.0, 31.0, 30.0, 33.0, 32.0, 31.0, 30.0, 29.0, 28.0, 27.0, 26.0, 25.0, 28.0, 27.0, 30.0, 29.0, 28.0, 31.0, 30.0, 33.0, 36.0, 35.0, 34.0, 33.0, 32.0, 31.0, 30.0, 29.0, 32.0, 31.0, 30.0, 29.0, 28.0, 31.0, 30.0, 33.0, 32.0, 31.0, 30.0, 33.0, 32.0, 31.0, 30.0, 29.0, 28.0, 31.0]}
dealer_139642810042304_stop:            {"tracker_history": [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0], "response_history": [1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0], "x_history": [15.0, 12.0, 45.0, 42.0, 39.0, 36.0, 33.0, 30.0, 27.0, 24.0, 21.0, 18.0, 27.0, 21.0, 30.0, 24.0, 21.0, 27.0, 18.0, 24.0, 21.0, 15.0, 24.0, 30.0, 27.0, 21.0, 30.0, 24.0, 23.0, 22.0, 29.0, 28.0, 27.0, 30.0, 25.0, 28.0, 27.0, 26.0, 29.0, 28.0, 29.0, 31.0, 32.0, 30.0, 31.0, 30.0, 29.0, 33.0, 32.0, 32.0, 31.0, 30.0, 29.0, 28.0, 31.0, 27.0, 30.0, 29.0, 28.0, 27.0, 26.0, 26.0, 25.0, 25.0, 24.0, 23.0, 22.0, 28.0, 25.0, 28.0, 27.0, 27.0, 26.0, 25.0, 30.0, 28.0, 27.0, 29.0, 28.0, 31.0, 30.0, 33.0, 30.0, 32.0, 31.0, 30.0, 33.0, 33.0, 36.0, 35.0, 34.0, 32.0, 33.0, 32.0, 31.0, 30.0, 29.0, 32.0, 35.0, 31.0, 34.0, 30.0, 33.0, 29.0, 28.0, 36.0, 31.0, 30.0, 35.0, 34.0, 33.0, 37.0, 36.0, 32.0, 31.0, 30.0, 33.0, 39.0, 42.0, 41.0, 32.0, 40.0, 39.0, 31.0, 38.0, 30.0, 29.0, 28.0, 41.0, 31.0]}

Plotting the Results#

axes = plt.subplots(2, 1)[1]
for i in [0, 1]:
    fig, ax, lines = td.trackers.ravel()[i].plot(ax=axes[i], n_skip=4)

    ax.legend(loc="best")
    ax.set_title(
        f"Adaptive track with start value {start_value[i]} (true threshold "
        f"is {true_thresh})"
    )
    fig.tight_layout()
Adaptive track with start value 15 (true threshold is 30), Adaptive track with start value 45 (true threshold is 30)

Total running time of the script: (0 minutes 0.245 seconds)

Gallery generated by Sphinx-Gallery