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.
root / multithreshold 1.46 / Levitt2.m
History | View | Annotate | Download (4.63 KB)
| 1 | 0:f233164f4c86 | rmeddis | 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=''; |