-
Notifications
You must be signed in to change notification settings - Fork 3
/
siam.m
101 lines (85 loc) · 2.74 KB
/
siam.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
function [threshold, values, reversals, measures, presentations, answers, adjustments, offsets] =...
siam(presentationhandle, answerhandle, target, minreversals, discardreversals, minmeasures, startvalue, steps, feedback)
% Implementation of the single-interval adjustment-matrix procedure (SIAM) as proposed by [1]
%
% Copyright (C) 2019 Marc René Schädler
% E-mail: marc.r.schaedler@uni-oldenburg.de
%
% [1] Kaernbach, C. (1990). A single‐interval adjustment‐matrix (SIAM) procedure for unbiased adaptive testing. The Journal of the Acoustical Society of America, 88(6), 2645-2655. https://doi.org/10.1121/1.399985
% Example config
% target = 0.75;
% minreversals = 14;
% discardreversals = 4;
% minmeasures = 25;
% startvalue = 10;
% steps = [4 4 2 1];
% feedback = 1;
% Initial values
value = startvalue;
direction = [];
count = 0;
threshold = nan;
values = [];
reversals = [];
measures = [];
presentations = [];
answers = [];
adjustments = [];
offsets = [];
adjustment_matrix = [-1 target./(1-target); 1./(1-target) 0];
minstep = min(min(abs(adjustment_matrix(abs(adjustment_matrix)>0))));
adjustment_matrix = adjustment_matrix ./ minstep;
assert(discardreversals>=0 && discardreversals<minreversals);
assert(minmeasures >= 1);
% Measure loop
while sum(abs(reversals))<minreversals || sum(presentations(measures==1))<minmeasures
count = count + 1;
% Present random stimulus after third presentation
if count < 4
presentation = 1;
else
presentation = round(rand(1));
end
offset = presentationhandle(presentation, value);
presentations(count) = presentation;
values(count) = value;
offsets(count) = offset;
% Get answer
answer = answerhandle(count, presentation, value);
answers(count) = answer;
%% Give feedback
if feedback
if answer == presentation
printf('%3i| CORRECT!\n',count);
else
printf('%3i| WRONG!\n',count);
end
end
% Determine adjustment
adjustment = adjustment_matrix(2-presentation, 2-answer) .* steps(min(1+sum(abs(reversals)),end));
adjustments(count) = adjustment;
% Apply adjustment
value = value + adjustment;
% Detect reversals
if isempty(direction) && adjustment ~= 0
direction = adjustment;
elseif (adjustment>0 && direction<0) || (adjustment<0 && direction>0)
direction = adjustment;
reversals(count) = sign(direction);
else
reversals(count) = 0;
end
% Mark measures
if sum(abs(reversals)) > discardreversals
measures(count) = 1;
else
measures(count) = 0;
end
end
% Evaluate measurement
if sum(abs(reversals))>=minreversals && sum(measures)>=minmeasures
reversalvalues = values(logical(abs(reversals)));
usereversalvalues = reversalvalues(1+discardreversals:end);
threshold = median(usereversalvalues);
end
end