psp.models#
Models used by the tutorials, recipes, tests and benchmarks.
psp.models.prospect: prospect theory on four bets of Kahneman and Tversky (1979).psp.models.alcove: ALCOVE (Kruschke, 1992) on the six category structures of Shepard, Hovland and Jenkins (1961), batched over parameter sets.psp.models.oscar: OSCAR on the inverse base-rate effect data (dome2025ibre), one trial order per participant.psp.models.voronoi: a cheap toy model whose regions are Voronoi cells.
They show how to write a batched model and discretize; you do not need them to partition
a model of your own.
Prospect theory#
Prospect theory on four bets of Kahneman and Tversky (1979), the model of the tutorial.
Each option is a prospect: an amount x won with probability p. Its value is
w(p) * v(x) with v(x) = x ** alpha and the probability weighting function
of Tversky and Kahneman (1992), w(p) = p**g / (p**g + (1 - p)**g) ** (1 / g).
The model returns, for each problem, the value of the riskier option minus the
value of the safer one, and the ordinal pattern is the sign of each difference on
the diagonal of a 4 x 4 matrix.
- psp.models.prospect.PROBLEMS = (Problem(problem=3, risky_amount=4000, risky_chance=0.8, safe_amount=3000, safe_chance=1.0, chose_risky=20, people=95), Problem(problem=4, risky_amount=4000, risky_chance=0.2, safe_amount=3000, safe_chance=0.25, chose_risky=65, people=95), Problem(problem=7, risky_amount=6000, risky_chance=0.45, safe_amount=3000, safe_chance=0.9, chose_risky=14, people=66), Problem(problem=8, risky_amount=6000, risky_chance=0.001, safe_amount=3000, safe_chance=0.002, chose_risky=73, people=66))#
Problems 3, 4, 7 and 8 of Kahneman and Tversky (1979).
- class psp.models.prospect.Problem(problem, risky_amount, risky_chance, safe_amount, safe_chance, chose_risky, people)[source]#
One choice between a riskier and a safer prospect, with what people chose.
- psp.models.prospect.weight(p, gamma)[source]#
The decision weight of probability
pwith weighting parametergamma.
- psp.models.prospect.prospect_value(amount, chance, alpha, gamma)[source]#
Subjective value of winning
amountwith probabilitychance.
- psp.models.prospect.model(par)[source]#
Value of the riskier minus the safer option in each problem, shape
(n, 4).parholdsalphaandgammain its two columns.
- psp.models.prospect.discretize(delta)[source]#
The sign of each difference on the diagonal of a 4 x 4 matrix, shape
(n, 4, 4).
ALCOVE#
ALCOVE (Kruschke, 1992) on the six category structures of Shepard, Hovland and Jenkins (1961).
This is a batched port of slpALCOVE() and nosof94train() from the R
package catlearn (Wills et al., 2025), wrapped for psp.PSP() as in
the ALCOVE recipe of the R package psp. Many parameter sets are run through the
same training sequences at once, which is what makes a long PSP run affordable
on a GPU.
The training orders are the ones catlearn generates for its seeds, shipped with the package, so that results can be compared with the R analysis trial for trial.
- psp.models.alcove.ALCOVE_PARAMETERS_FULL = AlcoveParameters(name=('c', 'phi', 'lw', 'la'), lower=(0.01, 0.01, 0.001, 0.001), upper=(20.0, 6.0, 1.0, 1.0))#
The full ranges of the learning rates, 0 to 1, with the same specificity and consistency ranges.
- psp.models.alcove.ALCOVE_COLUMNS = ('ctrl', 'cond', 'blk', 'stim', 'x1', 'x2', 'x3', 't1', 't2', 'm1', 'm2', 'm3')#
Columns of a training matrix, as catlearn’s
nosof94train()produces them.
- psp.models.alcove.ALCOVE_STIMULI = tensor([[0., 0., 0., 0., 1., 1., 1., 1.], [0., 0., 1., 1., 0., 0., 1., 1.], [0., 1., 0., 1., 0., 1., 0., 1.]], dtype=torch.float64)#
The eight stimuli as hidden nodes: three binary features each, one column per stimulus.
- psp.models.alcove.TYPES = ('I', 'II', 'III', 'IV', 'V', 'VI')#
The six category structures, Types I to VI.
- class psp.models.alcove.AlcoveParameters(name=('c', 'phi', 'lw', 'la'), lower=(0.01, 0.01, 0.001, 0.001), upper=(20.0, 6.0, 0.2, 0.2))[source]#
The four free parameters with the ranges of Pitt, Kim, Navarro and Myung (2006).
The lower bounds are kept above 0 because ALCOVE rejects a learning rate of 0.
- psp.models.alcove.alcove(params, training, *, h, alpha, w, colskip, r=1.0, q=1.0, dec='ER', humble=True, attcon=False, absval=-1.0)[source]#
Run ALCOVE for a batch of parameter sets over a batch of training sequences.
A port of catlearn’s
slpALCOVE(). Every parameter set runs through every sequence, all in parallel, and the state is carried from trial to trial within a sequence.- Parameters:
- params
c,phi,lwandla, each a tensor of shape(batch,).- training
Shape
(sequences, trials, columns), seesequences(). Column 0 holds the control code (0 normal, 1 reset the network, 2 freeze learning); the inputs, teaching signals and missing-dimension flags followcolskipcolumns, as in catlearn.- h
Hidden node positions, shape
(inputs, hidden).- alpha
Initial attention weights, shape
(inputs,).- w
Initial association weights, shape
(outputs, hidden).- colskip
Number of columns before the inputs, counting the control column.
- r, q
Distance metric (1 city-block, 2 Euclidean) and similarity gradient (1 exponential, 2 Gaussian).
- dec
"ER"for the exponential ratio rule,"BN"for the background noise rule.- humble
Use a humble teacher (Kruschke, 1992, Eq. 4b).
- attcon
Constrain the attention weights to sum to 1.
- absval
Teaching value for an absent category.
- Returns:
torch.TensorResponse probabilities, shape
(batch, sequences, trials, outputs).
Notes
The exponential ratio rule is computed as a numerically stable softmax. Where catlearn’s
exp(phi * o) / sum(exp(phi * o))overflows (the association weights diverge when the specificity is tiny and the association learning rate large, so every exemplar responds alike and the updates overshoot), catlearn returnsNaNand this function returns the limiting probabilities. Everywhere else the two agree to machine precision.
- psp.models.alcove.alcove_curves(unit, training, *, chunk=256, parameters=AlcoveParameters(name=('c', 'phi', 'lw', 'la'), lower=(0.01, 0.01, 0.001, 0.001), upper=(20.0, 6.0, 0.2, 0.2)))[source]#
Error rate of each type in each block for parameter sets on the unit hypercube.
This is the
modelof the ALCOVE recipe.unithas shape(n, 4)and is mapped onto ALCOVE’s ranges,parameters, withto_alcove().trainingis a matrix fromalcove_training(). The result has shape(n, 96): the 16 blocks of Type I, then of Type II, and so on, each averaged over the simulated learners.chunkbounds how many parameter sets run at once, to limit memory.
- psp.models.alcove.alcove_training(learners=5, seed=7624)[source]#
One training sequence per type and simulated learner, in catlearn’s trial order.
The orders catlearn’s
nosof94train()generates with R’s random number generator are shipped forseed7624 with 5 and 20 learners, and for seeds 11, 22, 33 and 44 with 5 learners (the settings of the ALCOVE recipe). Other settings fall back tonosof94train()and NumPy’s generator.- Returns:
torch.TensorShape
(6 * learners * 16 * 8 * 2, 12),float64: types I to VI in turn, each withlearnerssequences of 16 blocks.
- psp.models.alcove.nosof94()[source]#
Nosofsky et al.’s (1994) replication: columns
type(1-6),block(1-16),error.
- psp.models.alcove.nosof94train(cond=1, blocks=16, absval=-1, subjs=1, seed=7624, blkstyle='accurate')[source]#
Randomised training blocks for one category structure, like catlearn’s
nosof94train().Each block presents the eight stimuli twice. In block 1 (or in every block with
blkstyle="eights") each half of the block is shuffled separately; later blocks shuffle all sixteen trials together. Each simulated subject starts with a reset trial (ctrl = 1).The shuffling uses NumPy’s generator, so the orders differ from R’s for the same seed. For the orders catlearn produces, use
alcove_training().- Returns:
numpy.ndarrayShape
(subjs * blocks * 16, 12)with the columns ofALCOVE_COLUMNS.
- psp.models.alcove.human_curves()[source]#
The human error rates in the order
alcove_curves()uses, shape(96,).
- psp.models.alcove.sequences(training)[source]#
Split a training matrix into equal-length sequences at every reset trial.
Returns a tensor of shape
(sequences, trials, columns).
- psp.models.alcove.to_alcove(unit, parameters=AlcoveParameters(name=('c', 'phi', 'lw', 'la'), lower=(0.01, 0.01, 0.001, 0.001), upper=(20.0, 6.0, 0.2, 0.2)))[source]#
Stretch points of the unit hypercube onto ALCOVE’s parameter ranges.
unithas shape(n, 4); the result mapsc,phi,lwandlato tensors of shape(n,).parametersgives the ranges: those of Pitt et al. by default, orALCOVE_PARAMETERS_FULL.
- psp.models.alcove.weak_order(curves, gap=0.025)[source]#
The weak order of the six types by mean error, as a 6 x 6 comparison matrix.
This is the
discretizeof the ALCOVE recipe. The six mean errors are sorted and a new group starts wherever the gap to the next type exceedsgap. The entry(i, j)is 1 when typeiis harder than typej, -1 when easier and 0 when they are tied.curvesmay be(96,),(n, 96)or(n, 6)(mean errors); the result has shape(n, 6, 6), or(6, 6)for a vector.
OSCAR#
OSCAR (Dome & Wills, 2026) on the inverse base-rate effect data (dome2025ibre) from Dome & Wills (2025), batched over sets and participants.
OSCAR is the model of the inverse base-rate effect of Dome and Wills (2026). This module is
a port of its C++ implementation (architecture.cpp and model-row-by-row.cpp) and of
the participant-level PSP routine around it (convert.R, imac.R, psp.R):
oscar()runs the network for a batch of parameter sets, each row on one of a batch of trial sequences, and returns the response probabilities;dome2025ibre()loads the dataset (354 participants) andtraining_batch()builds the padded trial matrices ofConvertToStateList()for any set of participants;evaluate()is themodelof the PSP routine (P(rare) at test for A, B, BC and C behind a 0.5 anchor) anddiscretize()itsdiscretize(clobe’simac()with the ±0.125 thresholds).
Every function takes whole batches: no loop runs over parameter sets or participants, only over trials and over the ten recurrent attention-shift iterations of a learning trial.
Dome, L., & Wills, A. J. (2025). g-Distance: On the comparison of model and human heterogeneity. Psychological Review, 132(3), 632–655. https://doi.org/10.1037/rev0000550
Dome, L., & Wills, A. J. (2026). Errorless Irrationality: A unified computational account of the inverse base-rate effect across predictive, observational, and unsupervised procedures (arXiv:2608.06149). arXiv. https://doi.org/10.48550/arXiv.2608.06149
- psp.models.oscar.OSCAR_PARAMETERS = ('P', 'alpha', 'mu', 'rho', 'beta')#
The five free parameters, in the order PSP() passes them.
- psp.models.oscar.OSCAR_BOUNDS = ((1.0, 0.001, 0.001, 0.001, 0.001), (5.0, 1.0, 1.0, 5.0, 5.0))#
Their bounds in the PSP routine (run.r): lower, upper.
- psp.models.oscar.STIMULI = ('A', 'B', 'C', 'AB', 'ABX', 'AC', 'ACY', 'BC')#
Stimulus names, in the order their integer codes take in a trial matrix.
- psp.models.oscar.NODES = ('A', 'B', 'C', 'common', 'rare')#
The five nodes of the network: three cues and the two outcomes.
- psp.models.oscar.TRIAL_COLUMNS = ('ctrl', 'ppt', 'trials', 'stim', 'x1', 'x2', 'x3', 'x4', 'x5', 'y1', 'y2', 'y3', 'y4', 'y5', 'f1', 'f2', 'f3', 'f4', 'f5')#
Columns of a trial matrix, as
ConvertToStateList()lays them out (colskip = 4).
- class psp.models.oscar.IbreData(ppt, abstim, trial, phase, abresp)[source]#
The trials of the dataset, one entry per row: participant, stimulus, trial, phase, response.
Arrays of equal length.
- property participants#
Participant ids in order of first appearance.
- psp.models.oscar.dome2025ibre()[source]#
The inverse base-rate effect data (ply207): 354 participants, training then 72 test trials.
abrespiscommon,rareornone;phaseistrainingortest.- References:
Dome, L., & Wills, A. J. (2025). g-Distance: On the Comparison of Model and Human Heterogeneity. Psychological Review, 132(3), 632–655. https://doi.org/10.1037/rev0000550
- psp.models.oscar.convert_to_state_list(schedule, block, trials, ppt=0, design='supervised')[source]#
One participant’s trial matrix, as
ConvertToStateList()in convert.R builds it.- Parameters:
- schedule
Stimulus of each trial, names from
STIMULI.- block
Phase code of each trial:
0or4for training (4is what psp.R uses for a supervised design),2for test.- trials
Trial numbers, kept as a column.
- ppt
Participant code, kept as a column (an integer here; R keeps the string).
- design
"supervised": outcomes are eligible outputs in both phases and training trials carry feedback; the first trial resets the network with code 3."unsupervised": no feedback and no eligible outputs in training; code 1.
- Returns:
numpy.ndarrayShape
(trials, 19)withTRIAL_COLUMNS;stimholds the index of the stimulus inSTIMULI.
- psp.models.oscar.training_batch(data, participants=None, *, dtype=torch.float64)[source]#
Trial matrices of several participants, padded to the longest with control code
PAD.Returns the tensor of shape
(participants, trials, 19)and the participant ids in row order.
- psp.models.oscar.oscar(params, training, *, eta0, weights0, sequence=None, zero_first_column=True, return_trials=False)[source]#
Run OSCAR for a batch of parameter sets, each on one trial sequence.
- Parameters:
- params
P,alpha,mu,rhoandbeta, each of shape(B,).- training
Trial matrices, shape
(S, T, 19)withTRIAL_COLUMNS, or(T, 19)for a single sequence shared by the batch. Control codes: 1 and 3 reset the network before the trial; 2 responds without learning; 0, 4 and 5 learn (3 and 4 with feedback as part of the teacher);PADrows are skipped.- eta0, weights0
Initial saliences and connection weights, shape
(B, 5, 5); their diagonals are zeroed as in the C++.- sequence
For each row of the batch, the index of its sequence in
training, shape(B,). Defaults to sequence 0 for every row.- zero_first_column
Reproduce the C++
AttentionShift, whose.diag().zeros()on a one-row matrix zeroes the attended activation of node A (column 0) for every row, instead of each row’s own node.Falsezeroes each row’s own node.- return_trials
Also return the trial-by-trial probabilities, activations and errors.
- Returns:
- psp.models.oscar.random_initial_state(batch, *, scale=0.001, generator=None, device='cpu', dtype=torch.float64)[source]#
Initialize non-zero saliences and weights for a batch of parameter sets. Returns
eta0with a zero diagonal andweights0, both of shape(batch, 5, 5).
- psp.models.oscar.evaluate(par, training, *, sequence=None, generator=None, eta0=None, weights0=None, zero_first_column=True)[source]#
The
modelfor the PSP routine:Evaluates OSCAR.
Adds a 0.5 anchor.
Computes P(rare) at test for A, B, BC and C.
parholds P, alpha, mu, rho and beta in its columns, shape(B, 5). The initial saliences and weights are drawn afresh for every row, asevaluate()in imac.R does, unlesseta0andweights0are given.Returns
(B, 5).
- psp.models.oscar.imac(probabilities, thresholds=(0.125, -0.125))[source]#
clobe’s inequality matrix constructor as the PSP routine used it:
psp.clobe.imac()withinclusive=True.For
probabilitiesof shape(B, m)returns(B, m, m): above the diagonal, 1 wherep_i - p_j >= thresholds[0], -1 where<= thresholds[1], 0 between; 2 on and below the diagonal. A NaN difference stays NaN.
- psp.models.oscar.discretize(probabilities, thresholds=(0.125, -0.125))[source]#
The
discretizeof the PSP routine:imac(), every cell 99 for a row with any NaN.
- psp.models.oscar.EVALUATED_STIMULI = ('A', 'B', 'BC', 'C')#
The stimuli whose P(rare) at test enter the ordinal pattern, after the 0.5 anchor.
Voronoi cells#
A cheap toy model whose ordinal regions are Voronoi cells of the unit hypercube.
The model returns the squared distance from the parameter set to each of
regions random centres, and discretize returns the index of the nearest
centre in a 2 x 2 matrix. It is the model of the package tests and benchmarks.
- class psp.models.voronoi.VoronoiModel(centres)[source]#
A Voronoi model:
centresof shape(regions, dimensions).
References#
Dome, L., & Wills, A. J. (2025). g-Distance: On the comparison of model and human heterogeneity. Psychological Review, 132(3), 632–655. https://doi.org/10.1037/rev0000550
Dome, L., & Wills, A. J. (2026). Errorless Irrationality: A unified computational account of the inverse base-rate effect across predictive, observational, and unsupervised procedures (arXiv:2608.06149). arXiv. https://doi.org/10.48550/arXiv.2608.06149
Kahneman, D., & Tversky, A. (1979). Prospect Theory: An Analysis of Decision under Risk. Econometrica, 47(2), 263–292. https://doi.org/10.2307/1914185
Kruschke, J. K. (1992). ALCOVE: An exemplar-based connectionist model of category learning. Psychological Review, 99(1), 22–44. https://doi.org/10.1037/0033-295X.99.1.22
Pitt, M. A., Kim, W., Navarro, D. J., & Myung, J. I. (2006). Global model analysis by parameter space partitioning. Psychological Review, 113(1), 57–83. https://doi.org/10.1037/0033-295X.113.1.57
Shepard, R. N., Hovland, C. I., & Jenkins, H. M. (1961). Learning and memorization of classifications. Psychological Monographs: General and Applied, 75(13), 1–42. https://doi.org/10.1037/h0093825
Tversky, A., & Kahneman, D. (1992). Advances in prospect theory: Cumulative representation of uncertainty. Journal of Risk and Uncertainty, 5(4), 297–323. https://doi.org/10.1007/BF00122574
Wills, A. J., Dome, L., Edmunds, C., Honke, G., Inkster, A., Schlegelmilch, R., & Spicer, S. (2025). catlearn: Formal Psychological Models of Categorization and Learning. R package version 1.1. https://CRAN.R-project.org/package=catlearn