EconomicDecisionMaking#
- class braintools.cogtask.EconomicDecisionMaking(t_fixation=Quantity(1500., 'ms'), t_offer=(Quantity(1000., 'ms'), Quantity(2000., 'ms')), t_decision=Quantity(750., 'ms'), offers=((0, 1), (1, 3), (1, 2), (1, 1), (2, 1), (3, 1), (4, 1), (6, 1), (2, 0)), relative_value=2.2, quantity_scale=0.2, noise_sigma=Quantity(0., 'ms^0.5'), **kwargs)[source]#
Economic (value-based) decision-making task.
On each trial two offers are shown, one of juice A and one of juice B, in varying quantities (e.g. “1A vs 3B”); the subject must choose the offer of greater subjective value. Juice A is preferred: one drop of A is worth
relative_valuedrops of B. This is the orbitofrontal-cortex juice choice paradigm of Padoa-Schioppa and Assad [1], as implemented by theEconomicDecisionMakingenvironment of NeuroGym [2] (itself adapted from the reward-based RNN training of Song et al. [3]).Structure: Fixation >> Offer >> Decision
- Parameters:
t_fixation (
Quantity) – Fixation period (default: 1500 ms).t_offer (
Any) – Offer period. A Quantity gives a fixed duration; a(min, max)tuple of Quantities draws it uniformly per trial (default:(1000, 2000)ms, as in NeuroGym).t_decision (
Quantity) – Decision period (default: 750 ms).offers (
Sequence[Tuple[int,int]]) – Offer types as(nB, nA)pairs, the number of drops of juice B and of juice A (default: NeuroGym’s(0, 1), (1, 3), (1, 2), (1, 1), (2, 1), (3, 1), (4, 1), (6, 1), (2, 0)).relative_value (
float) – Value of one drop of A in drops of B, i.e.1A = relative_value B(default: 2.2; NeuroGym’sB_to_A = 1 / 2.2). Must be positive.quantity_scale (
float) – Factor applied to the drop counts in the quantity inputs (default:1 / 5).noise_sigma (
Array|ndarray|bool|number|bool|int|float|complex|Quantity) – Standard deviation of Gaussian input noise on the quantity channels during the offer, in units ofms ** 0.5and scaled by1 / sqrt(dt)(default: 0, noise-free offers).**kwargs – Forwarded to
Task(e.g.seed,dt).
- Raises:
ValueError – If
offersis empty, not of shape(K, 2)or negative,relative_value <= 0, ort_offeris a malformed tuple.
See also
PerceptualDecisionMakingTwo-alternative choice from sensory evidence.
Notes
Inputs (7 channels, NeuroGym’s order
fixation, a1, b1, a2, b2, n1, n2):fixation(1);juice1andjuice2(2 each), one-hot identity[A, B]of the juice in offer 1 and offer 2;quantity(2),quantity_scaletimes the drop counts[n1, n2]. Which offer slot holds juice A is random (juice_order0: A is offer 1, 1: A is offer 2). The fixation input is 1 during fixation and offer and 0 during the decision.Ground truth. The offer values, in units of B, are
\[V_A = \rho \, n_A, \qquad V_B = n_B,\]with \(\rho\) =
relative_value. The correct choice is the offer of juice A if \(V_A > V_B\) and of juice B if \(V_B > V_A\); a tie is broken at random (tieis set in the trial state).Labels (categorical, 3 classes): 0 (fixate) during fixation and offer,
ground_truth + 1during the decision, whereground_truthis the chosen offer slot (0 = offer 1, 1 = offer 2).Trial state:
nA,nB,juice_order,value_A,value_B,choose_A,tie,ground_truthand, when sampled,offer_duration(ms).With the default uniform
t_offerthe task runs in packed (variable-length) mode (seemax_trial_duration());batch_sampleruns underjax.jitandvmapeither way.Differences from NeuroGym. NeuroGym’s environment is trained by reward only (the reward is the chosen juice’s value) and defines no ground truth; here the higher-value offer is the supervised label and ties are broken at random. Phase names are
'fixation','offer'and'decision'(NeuroGym:'offer_on'for the offer). The optional input noise is an addition.References
Examples
>>> import brainunit as u >>> import braintools >>> task = braintools.cogtask.EconomicDecisionMaking( ... seed=0, dt=10.0 * u.ms, t_offer=1000.0 * u.ms) >>> task.num_inputs, task.num_outputs (7, 3) >>> X, Y, info = task.sample_trial(0) >>> X.shape, Y.shape ((325, 7), (325,)) >>> s = info['trial_state'] >>> correct_is_A = bool(s['value_A'] > s['value_B']) >>> bool(s['choose_A']) == correct_is_A or bool(s['tie']) True >>> chosen_slot = int(s['juice_order']) if bool(s['choose_A']) else 1 - int(s['juice_order']) >>> int(Y[-1]) == chosen_slot + 1 True >>> >>> X, Y = task.batch_sample(4) >>> X.shape, Y.shape ((325, 4, 7), (325, 4))
- define_features()[source]#
Define input and output features.
Override in subclass for class-based task definition.
- Return type:
- Returns:
input_features (Feature or FeatureSet) – Input feature definitions.
output_features (Feature or FeatureSet) – Output feature definitions.