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 / psychoLogisticRareEvent.m @ 33:161913b595ae

History | View | Annotate | Download (12.4 KB)

1
function psycho 
2

    
3
% DATA from AbsThresholdCM, LS
4

    
5
levelSequence=[16.0836	6.0836	11.0836	12.725	13.4995	11.6559	12.7168	13.9507	12.0632	11.3845	11.7754	12.8639	14.1061	14.5545	13.5589	13.4736	14.1554	13.5123	13.1537	11.5334	12.6921	11.4461	10.7112	11.9171	10.8412	12.0536	13.06	14.2345	13.8535	14.0575	14.0145	15.6385	13.7959	14.0397	12.2497	11.4383	12.7685	12.7317	11.6741	10.3955	9.0334	10.4787	11.1883	11.4687	12.0583	13.8982	13.0644	14.4722	14.0304	14.7569	13.8571	12.1521	14.0865	13.2258	11.6988	12.2186	12.2561	12.2711	13.0345	14.2948	13.7838	12.9155	12.6927	12.5757	13.4818	12.8397	14.1803	12.7524	12.3169	13.0973	14.9722	14.4422	15.8944	17.2728	16.8621	15.3074	13.7319	11.7716	12.1233	12.1576	13.0023	13.2442	12.1454	13.8298	13.3997	11.7799	12.3834	12.8387	14.3718	12.7063	14.4002	14.3674	14.7882	15.0271	13.5737	15.2095	14.1789	13.4982	14.3926	13.6277	15.0551	13.493	15.3368	16.9437	16.1645	15.9275	15.7577	14.2939	14.1069	13.6184	12.728	14.4283	15.6494	14.2216	15.8188	14.3906	12.7635	13.2973	11.9934	11.1053	12.2359	11.439	12.4735	12.5466	12.9186	13.6937	13.792	13.085	12.5016	13.8401	11.9688	13.0676	14.3708	13.4891	14.4394	15.8265	17.1478	15.2337	13.6512	12.7727	14.4818	13.7045	14.5207	13.8211	13.2874	14.9221	14.3822	14.3562	13.3132	13.5015	13.1372	14.4495	13.957	15.2124	16.6607	15.114	13.8978	12.6665	12.3469	13.3699	14.1991	15.2259	13.2326	11.9325	13.1954	12.2766	13.7996	15.5274	14.7623	13.21	12.5874	10.6431	12.2121	10.4043	11.9979	10.2153	10.7945	11.5215	12.7081	14.2288	14.4475	13.9777	13.8564	14.1923	15.393	14.5229	15.3377	13.9385	13.6328	14.2861	15.0021	15.5488	13.8067	13.0269	13.3644	13.6195	14.5834	15.6554	13.8914	13.3657	14.0566	12.9857	12.9343	14.0372	14.0156	15.6395	15.4225	14.6514	14.6498	13.6421	13.4263	13.227	14.0428	14.681	15.1661	13.5285	14.9074	13.5498	14.4265	14.0798	14.6391	12.8226	12.225	13.7883	12.7012	12.7932	13.5318	14.9207	14.064	12.9551	14.2066	14.3463	13.4565	13.9379	15.7189	14.3516	12.6425	12.8485	12.2879	13.1142	11.8093	12.0037	10.2154	11.8395	12.4643	13.0501	13.5452	13.2338	12.6246	13.292	11.5661	11.6015	13.2896	15.2506	15.5295	14.523	13.6199	13.083	12.1714	12.5977	14.2862	15.7924	14.0221	14.4042	16.0364	16.6967	14.7112	14.7594	13.9874	13.3428	13.5231	14.441	13.9983	13.6414	11.862	13.2632	13.1065	12.8701	12.2578	13.7517	14.3268	13.3849	13.9609	13.3239	14.6694	14.8172	13.654	13.8144	13.5015	14.34	14.0139	15.1029	13.3895	13.3701	13.4554	11.9646	12.2519	12.4145	13.1343	14.9372	13.2483
6
];
7

    
8

    
9
responseSequence=[1	0	0	0	1	0	0	1	1	0	0	0	0	1	1	0	1	1	1	0	1	1	0	1	0	0	0	1	0	1	0	1	0	1	1	0	1	1	1	1	0	0	0	0	0	1	0	1	0	1	1	0	1	1	0	0	0	0	0	1	1	1	1	0	1	0	1	1	0	0	1	0	0	1	1	1	1	0	0	0	0	1	0	1	1	0	0	0	1	0	1	0	0	1	0	1	1	0	1	0	1	0	0	1	1	1	1	1	1	1	0	0	1	0	1	1	0	1	1	0	1	0	0	0	0	0	1	1	0	1	0	0	1	0	0	0	1	1	1	0	1	0	1	1	0	1	1	1	0	1	0	1	0	0	1	1	1	1	0	0	0	1	1	0	1	0	0	1	1	1	1	0	1	0	1	0	0	0	0	0	1	1	0	0	1	0	1	1	0	0	0	1	1	0	0	0	0	1	1	0	1	1	0	1	0	1	1	1	1	1	1	0	0	0	1	0	1	0	1	0	1	1	0	1	0	0	0	1	1	0	0	1	0	0	1	1	0	1	0	1	0	1	0	0	0	0	1	1	0	1	0	0	0	0	1	1	1	1	0	0	0	1	0	0	0	1	0	1	1	0	0	1	1	1	0	1	1	1	0	0	1	0	1	0	0	1	0	1	0	1	0	1	1	0	1	0	0	0	0	1	1
10
];
11

    
12

    
13
duration=0.008;
14

    
15

    
16
% levelSequence=[23.3987	13.3987	18.9769	25.9114	18.6243	16.4689	23.7829	20.4015	19.3156	25.1232	21.4541	24.353	22.1732	24.83	21.8257	19.3798	17.885	26.0332	23.3135	20.7889	20.1446	22.3504	25.7491	25.8517	23.2701	25.2773	24.8727	26.416	23.9425	21.4652	25.3512	18.3484	26.0988	23.2303	17.0335	26.7833	17.1426	21.1627	21.8802	24.8192	18.2626
17
% ];    
18
% responseSequence=[1	0	0	1	0	0	1	0	0	1	0	1	1	1	0	0	0	1	1	0	0	1	1	1	1	1	1	1	0	0	1	0	1	1	0	1	0	0	0	1	0
19
% ];
20
% duration=0.016;
21

    
22

    
23
% levelSequence=[24.9709	14.9709	18.3185	20.893	19.1644	17.8633	12.8493	20.2354	19.4386	14.4227	14.3361	12.0587	18.6425	20.1803	18.1533	20.8734	19.0579	20.4904	18.3061	14.8561	16.6948	19.2928	17.8098	17.6181	21.7709	16.6804	15.2661	17.967	20.0085	20.7096	15.7485	20.0475	16.0825	11.8798	19.4383	13.838	18.3323	15.8729	12.066	15.4367	12.4179
24
% ];   
25
% responseSequence=[1	0	1	1	1	1	0	1	1	0	0	0	1	1	0	1	1	1	1	0	1	1	1	0	1	1	1	1	1	1	0	1	0	0	1	0	1	1	0	1	0
26
% ];
27
% duration=0.512;
28
% 
29
% 
30
% levelSequence=[20.9248	10.9248	17.6621	16.5301	12.8652	8.4223	7.2398	13.566	14.5773	15.7202	13.4907	15.5048	10.9308	11.9566	13.3548	18.6419	15.8288	13.6961	12.8613	11.1181	10.7736	14.6912	11.3496	18.4924	16.9867	14.6383	17.4752	19.0135	14.7333	14.0739	14.637	11.7261	10.1013	17.7782	18.4642	14.1431	18.7764	19.312	10.9071	17.2639	17.9951
31
% ];   
32
% responseSequence=[1	0	1	1	1	0	0	1	0	0	0	1	0	0	0	1	0	1	0	0	0	0	0	1	1	1	1	1	1	0	0	0	0	1	0	1	1	1	0	1	1
33
% ];
34
% duration=0.256;
35

    
36

    
37
functionType='logistic';
38
functionType='rareEvent';
39

    
40
[R C]=size(levelSequence);
41
levelSequence=reshape(levelSequence',1,R*C);
42

    
43
[R C]=size(responseSequence);
44
responseSequence=reshape(responseSequence',1,R*C);
45

    
46
figure(2),clf
47
figure(3),clf
48
figure(2), plot(levelSequence,responseSequence,'k.'),hold on
49
set(gca,'ytick',[0 1])
50
set(gca,'yticklabel',{'0'; '1'})
51
ylim([-.5 1.5])
52
figure(3), plot(levelSequence,responseSequence,'k.'),hold on
53

    
54
figure(2), xlabel('dB SPL'), ylabel('p(yes)')
55
figure(3), xlabel('dB SPL'), ylabel('p(yes)')
56

    
57
set(gca,'ytick',[0 1])
58
set(gca,'yticklabel',{'0'; '1'})
59
ylim([-.5 1.5])
60
binWidth=1;
61
minBinCenter=-10;
62
maxBinCenter=100;
63
binCenters=minBinCenter:binWidth:maxBinCenter;
64
noPointers=find(responseSequence==0);
65
noLevels=levelSequence(noPointers);
66
yesPointers=find(responseSequence==1);
67
yesLevels=levelSequence(yesPointers);
68
noHist=hist(noLevels,binCenters);
69
yesHist=hist(yesLevels,binCenters);
70
warning off MATLAB:divideByZero
71
yesHist=hist(yesLevels,binCenters);
72
proportions=yesHist./(yesHist+noHist);
73
warning on MATLAB:divideByZero
74

    
75
idx=find(noHist | yesHist);
76
noHist=noHist(idx);
77
yesHist=yesHist(idx);
78
proportions=proportions(idx);
79
binCenters=binCenters(idx);
80

    
81
for i=1:length(noHist)
82
    marker=10*(noHist(i)+yesHist(i))/max(noHist);
83
    figure(2), plot(binCenters(i),proportions(i),'ko','markersize',marker), hold on
84
    figure(3), plot(binCenters(i),proportions(i),'ko','markersize',marker), hold on
85
end
86

    
87

    
88

    
89

    
90

    
91

    
92

    
93
rareEventProfile= fitRareEvent2(levelSequence,responseSequence, duration)
94
figure(2), hold on
95
plot(rareEventProfile.predictionLevels, rareEventProfile.predictionsRE,'g')
96
xlim([min(binCenters) max(binCenters)])
97
figure(3), hold on
98
plot(rareEventProfile.predictionLevels, rareEventProfile.predictionsRE,'g')
99
xlim([20 35])
100

    
101

    
102

    
103
[bestVmin, bestG, smallestEuclid]=...
104
    rareEvent(levelSequence,responseSequence, duration);
105

    
106
[bestThreshold, bestSlope, smallestEuclid]=...
107
    logistic(levelSequence,responseSequence);
108

    
109
% -------------------------------------------- rareEvent
110
function [bestVmin, bestG, smallestEuclid]=...
111
    rareEvent(levelSequence,responseSequence, duration)
112
'rare event'
113
gs=.01:.01:4;
114

    
115
Vmins=1:10:5000;
116
P=28*10.^(levelSequence/20);
117
allSmallestEuclid=[ ];
118
allBestGs=[];
119

    
120
for Vmin=Vmins
121
    Euclids=[];
122
    x=[];y=[];
123
    for G=gs;
124
        predictions= 1-exp(-duration*(G*P-Vmin));
125
        idx=find(predictions<0); predictions(idx)=0;
126
        Euclid=mean((predictions - responseSequence).^2);
127
        Euclids=[Euclids Euclid];
128
    end
129
    
130
    [smallestEuclid idx]=min(Euclids);
131
    % disp(num2str([idx smallestEuclid]))
132
    allSmallestEuclid=[allSmallestEuclid smallestEuclid];
133
    bestG=gs(idx);
134
    allBestGs=[allBestGs bestG];
135
    
136
end
137
[smallestEuclid idx2]=min(allSmallestEuclid)
138
bestVmin=Vmins(idx2);
139
bestG=allBestGs(idx2);
140
% [bestVmin bestG smallestEuclid]
141

    
142
% predictions= 1-exp(-duration*(bestG*P-Vmin));
143
% errors=responseSequence-predictions;
144
% rho=corr([errors;  levelSequence]');
145
% disp(['correlation=' num2str(rho(1,2))])
146

    
147

    
148
levels=[min(levelSequence):max(levelSequence)];
149
P=28*10.^(levels/20);
150
predictions= 1-exp(-duration*(bestG*P-bestVmin));
151
idx=find(predictions<0); predictions(idx)=0;
152
figure(2), plot(levels,predictions,'r'), hold off
153
title(['g=' num2str(bestG) ':  Vmin=' num2str(bestVmin) ':  Euclid= ' num2str(smallestEuclid)])
154
figure(4), plot(levels(1:end-1), diff(predictions))
155

    
156
xlim([levels(1)-10 levels(end)+10])
157
ylim([-0.5 1.5])
158
pause(.1)
159

    
160
% -------------------------------------------- logistic
161
function [bestThreshold, bestSlope, smallestEuclid]=...
162
    logistic(levelSequence,responseSequence)
163
'logistic'
164
candidateThresholds=-20:1:50;
165
candidateSlopes=.01:.01:10;
166

    
167
allSmallestEuclid=[ ];
168
allThresholds=[];
169

    
170
for thisSlope=candidateSlopes;
171
    Euclids=[];
172
    for thisThreshold=candidateThresholds;
173
        predictions=1./(1+exp(-thisSlope.*(levelSequence-thisThreshold)));
174
        Euclid=mean((predictions - responseSequence).^2);
175
        Euclids=[Euclids Euclid];
176
    end
177
    [smallestEuclid idx]=min(Euclids);
178
    % disp(num2str([idx smallestEuclid]))
179
    allSmallestEuclid=[allSmallestEuclid smallestEuclid];
180
    bestThreshold=candidateThresholds(idx);
181
    allThresholds=[allThresholds bestThreshold];
182
end
183
[smallestEuclid idx2]=min(allSmallestEuclid)
184
bestSlope=candidateSlopes(idx2);
185
bestThreshold=allThresholds(idx2);
186
% [bestThreshold bestSlope smallestEuclid]
187

    
188
% predictions= 1-exp(-duration*(bestG*P-Vmin));
189
% errors=responseSequence-predictions;
190
% rho=corr([errors;  levelSequence]');
191
% disp(['correlation=' num2str(rho(1,2))])
192

    
193

    
194
levels=[min(levelSequence):max(levelSequence)];
195
bestLogistic=1./(1+exp(-bestSlope*(levels-bestThreshold)));
196
figure(3), plot(levels,bestLogistic,'r'), hold off
197
title(['k=' num2str(bestSlope) ':  threshold=' num2str(bestThreshold) ':  Euclid= ' num2str(smallestEuclid)])
198
% figure(2), hold on, plot(levels,bestLogistic,'g'), hold off
199
figure(4), hold on, plot(levels(1:end-1), diff(bestLogistic), 'r')
200

    
201

    
202
xlim([levels(1)-10 levels(end)+10])
203
ylim([-0.5 1.5])
204

    
205

    
206

    
207
% --------------------------------------------------- fitRareEvent
208
function rareEvent=fitRareEvent2(stimulusLevels, responses, duration, gains, Vmins)
209
% least squares estimate of *rare event* function
210
% p(event)=gain*levelmPa -Vmin
211
% 'responses' is a binary vector of subject's decision.
212
% 'stimulusLevels' are the corresponding signal levesl (values)
213
% duration is required to compute the expectation of an event occurring
214
% gains is an optional list of gains to be tried
215
% Vmins is an optional list of Vmins to be tried
216

    
217
global experiment
218
if nargin<5
219
    minVmin=1; maxVmin=100000; nVmins=30;
220
    Vmins=[0 logspace(log10(minVmin),log10(maxVmin),nVmins)];
221
    % disp(Vmins)
222
    nGains=10;
223
    dGain=1/nGains;
224
    gains=dGain:dGain:20;
225
end
226

    
227
nVmins=length(Vmins);
228
nGains=length(gains);
229

    
230
rareEvent.bestGain=NaN;
231
rareEvent.bestVMin=NaN;
232
rareEvent.thresholddB=0;
233
rareEvent.bestPaMindB=NaN;
234
rareEvent.predictionLevels=[];
235
rareEvent.predictionsRE=[];
236
rareEvent.Euclid=NaN;
237

    
238
if isempty(stimulusLevels), return, end
239

    
240
% expected slope is negative, rareEvent can not be used
241
% if experiment.psyFunSlope<0
242
%     return
243
% end
244

    
245
% NB calculations in microPascals!
246
stimulusLevelsAsPressure=28 * 10.^(stimulusLevels/20);
247

    
248
allGains=reshape(repmat(gains,nVmins,1), 1, nVmins*nGains);
249
allVmins=repmat(Vmins, 1, nGains);
250

    
251
for repeat=1:2
252
    predictions=NaN(1,length(stimulusLevels));
253
    gainCount=0; VminCount=0;
254
    Euclid=inf; bestVmin=0; bestGain=0;
255
    for gain= gains
256
        gainCount=gainCount+1;
257
        VminCount=0;
258
        for Vmin=Vmins
259
            VminCount=VminCount+1;
260
            % all levels are simultaneously assessed
261
            gP_Vmin=gain*stimulusLevelsAsPressure-Vmin;
262
            idx=(gP_Vmin>0);
263
            predictions(idx)= 1-exp(-duration*(gP_Vmin(idx)));
264
            predictions(~idx)=0;
265

    
266
            error=(predictions - responses).^2;
267
            error=mean(error(~isnan(error)));
268
            if error<Euclid
269
                Euclid=error;
270
                bestVmin=Vmin;
271
                bestVminCount=VminCount;
272
                bestGainCount=gainCount;
273
                bestGain=gain;
274
            end
275
        end
276
    end
277
    if repeat==1
278
        if bestVminCount>1 & bestVminCount<nVmins
279
            minVmin=Vmins(bestVminCount-1); maxVmin=Vmins(bestVminCount+1); nVmins=30;
280
            Vmins=[0 logspace(log10(minVmin),log10(maxVmin),nVmins)];
281
        elseif bestVminCount==1
282
            Vmins=0:Vmins(2)/30:Vmins(2);
283
        else
284
            disp('rareEvent: Vmin estimate may be out of range')
285
        end
286
    end
287
    % disp(Vmins)
288
end
289

    
290
if bestGainCount==1 | bestGainCount==nGains
291
    disp('gain estimate may be out of range')
292
end
293

    
294

    
295
[rareEvent.Euclid idx]=min(Euclid);
296
rareEvent.bestGain=bestGain;
297
rareEvent.bestVMin=round(bestVmin);
298
rareEvent.thresholdPa=(-log(0.5)/duration + rareEvent.bestVMin)/rareEvent.bestGain;
299
rareEvent.thresholddB=20*log10(rareEvent.thresholdPa/28);
300
rareEvent.bestPaMindB=20*log10((rareEvent.bestVMin/rareEvent.bestGain)/28);
301

    
302
predictionLevels= -50:1:120;
303
rareEvent.predictionLevels=predictionLevels;
304
rareEvent.predictionsRE=...
305
    1-exp(-duration*(rareEvent.bestGain*28 * 10.^(predictionLevels/20)-rareEvent.bestVMin));
306
rareEvent.predictionsRE(rareEvent.predictionsRE<0)=0;
307