To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at git://github.com/rmeddis/MAP.git .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Revision:

root / multithreshold 1.46 / Levitt2.m @ 31:c54a34161e4a

History | View | Annotate | Download (4.63 KB)

1
function [nextStep, msg]=Levitt2 (decision, currentValue)
2
global LevittControl withinRuns
3
% descision is a string: 'hit' or 'miss'
4
% current value is the value of the variable parameter (e.g. level)
5
% msg:
6
%     msg='' indicates trial progressing successfully
7
%     msg='done' indicates that a threshold estimate has been found
8
%     msg='maximum level exceeded'
9
%     msg='maximum no of trials exceeded'
10

    
11
% Initialize by running Levitt2 without arguments
12
%  later LevittControl will be set in aReadAndCheckParameterBoxes in  expGUI_MT
13
if nargin==0
14
    
15
    LevittControl.peakTroughValues=[];   
16
    LevittControl.trialRunning=0;
17
    LevittControl.sequence='****'; 
18
    LevittControl.LevittValuesUsed=[NaN NaN NaN NaN];
19
    LevittControl.TurnsToSmallSteps=4; % 2 peaks and 2 troughs
20
    LevittControl.direction='same';
21
    LevittControl.prevDirection='easier';
22
    LevittControl.Nreversals=0;
23
    
24
    LevittControl.trialRunning=1;
25
    LevittControl.meanPeakTrough=NaN;
26
    LevittControl.sd=NaN;
27
    msg='';
28
    return
29
end
30

    
31
% apply Levitt rules to find next stimulus value
32
rule=LevittControl.rule;
33
sequence=LevittControl.sequence;
34
meanPT=LevittControl.meanPeakTrough;
35
sdPT=LevittControl.sd;
36

    
37
% response sequence: '+' is a hit and '-' is a miss.
38
if strcmp(decision,'hit')
39
    sequence=[sequence '+'];
40
else
41
    sequence=[sequence '-'];
42
end
43
LevittControl.LevittValuesUsed=[LevittControl.LevittValuesUsed withinRuns.levelList(end)];
44

    
45
switch rule
46
    case '++'
47
        peakCriterion='-++';
48
        troughCriteria={'++ -', '++ +-'};
49
    case '+++'
50
        peakCriterion='-+++';
51
        troughCriteria={'+++ -', '+++ +-', '+++ ++-'};
52
    otherwise
53
        error('Levitt:')
54
end	
55

    
56
troughs=[]; allTroughPtrs=[];
57
for i=1:length(troughCriteria)              % do all trough criteria
58
    troughCriterion=char(troughCriteria(i));% one criterion at a time
59
    % identify the location of a trough
60
    troughPtrs=findstr(sequence, troughCriterion) + length(troughCriterion)-1;
61
    % identify the level at which it occurred
62
    troughLevels=LevittControl.LevittValuesUsed(troughPtrs);
63
    % archive the list
64
    withinRuns.troughs=troughLevels;
65
    troughs=[troughs troughLevels];
66
    allTroughPtrs=[allTroughPtrs troughPtrs];
67
end
68
% only one peak criterion used
69
withinRuns.troughs=troughs;
70
peakPtrs=findstr(sequence,peakCriterion)+length(peakCriterion)-1;
71
peakLevels=LevittControl.LevittValuesUsed(peakPtrs);
72
withinRuns.peaks=peakLevels;
73

    
74
% almagamate and sort into date order
75
peakTroughList=[peakLevels troughs];
76
peakTroughPtrs=[peakPtrs allTroughPtrs];
77
[peakTroughPtrs idx]=sort(peakTroughPtrs);
78
% it needs to be sequenced so that the algorithm can take the last peaks
79
% and troughs
80
peakTroughList=peakTroughList(idx);
81

    
82
% adjust step size as the trial progresses
83
% a positive step size indicates the 'harder' direction 
84
if length(peakTroughList)>=LevittControl.TurnsToSmallSteps
85
    currentStep=LevittControl.steadyLevittStep;
86
else
87
    currentStep=LevittControl.startLevelStep;
88
end    
89

    
90
% base next stimulus on the basis of the sequence
91
%  any miss requires an 'easier' stimulus next time.
92
if strcmp(sequence(end),'-')
93
    nextStep= -currentStep;
94
    
95
    % success requires 2 or more successive hits
96
elseif strcmp(sequence(end-length(rule)+1:end),rule)
97
    sequence=[sequence ' '];  % add space to prevent success on successive trials
98
    LevittControl.LevittValuesUsed=[LevittControl.LevittValuesUsed NaN];
99
    nextStep=currentStep;
100
    
101
    % not enough hits to provoke a change
102
else	
103
    nextStep=0;
104
end
105

    
106
LevittControl.sequence=sequence;
107

    
108
LevittControl.Nreversals=length(peakTroughList);
109
% compute threshold estimate 
110
% only if minReversals exceeded and even number of peaks and troughs
111
if LevittControl.Nreversals>=LevittControl.minReversals && rem(length(peakTroughList),2)==0   
112
    % use only the peaks and troughs at the end of the sequence
113
    peaksAndTroughs=peakTroughList(end-LevittControl.useLastNturns+1:end);
114
    disp(['peak/trough sequence= ' num2str(peaksAndTroughs, '%6.0f') ] )
115
    
116
    meanPT=mean(peaksAndTroughs);
117
    sdPT=std(peaksAndTroughs);
118
    LevittControl.meanPeakTrough=meanPT;
119
    LevittControl.sd=sdPT;
120
    fprintf('Levitt, mean, sd= %6.1f,%6.1f\n', meanPT, sdPT)
121
    % final check that the sd is low enough
122
    if sdPT<LevittControl.targetsdPT        
123
        nextValue=currentValue;
124
        msg='done';
125
        return
126
    end
127
end
128

    
129
nextValue=currentValue + nextStep;
130
if nextValue>LevittControl.maxLevittValue
131
    msg='maximum level exceeded'
132
    return
133
end
134

    
135
% required for later use
136
LevittControl.trialRunning=LevittControl.trialRunning+1;
137
LevittControl.peakTroughValues=peakTroughList;
138

    
139
if LevittControl.trialRunning>LevittControl.maxTrials
140
    msg='maximum no of trials exceeded'
141
    return
142
end
143

    
144
% Trial continues
145
msg='';