Mercurial > hg > map
comparison Copy_of_multithreshold 1.46/Levitt2.m @ 28:02aa9826efe0
mainly multiThreshold
author | Ray Meddis <rmeddis@essex.ac.uk> |
---|---|
date | Fri, 01 Jul 2011 12:59:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
27:d4a7675b0413 | 28:02aa9826efe0 |
---|---|
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=''; |