Home > voicebox > psycest.m

psycest

PURPOSE ^

Estimate multiple psychometric functions

SYNOPSIS ^

function [xx,ii,m,v]=psycest(iq,x,r,xp)

DESCRIPTION ^

 Estimate multiple psychometric functions

 Usage: [xx,ii,m,v]=psycest(-n,p,q,xp) % initialize n models
        [xx,ii,m,v]=psycest(i,x,r)     % supply a trial result to psycest
                    psycest(i)         % plot pdf of model i
              [p,q]=psychest(0)        % output model parameters (or print them if no outputs)

 Inputs:
         -n        minus the number of models
          p(:,n)   parameters for each model
                      1  thresh [0.75]
                      2  miss [0.04]
                      3  guess [0.1]
                      4  SNR min [-20]
                      5  SNR max [20]
                      6  Slope min [0]
                      7  slope max [0.5]
          q(:)     parameters common to all models (vector or struct)
                      1  q.nx  number of SNR values in pdf [40]
                      2  q.ns  number of slope values in pdf [21]
                      3  q.nh  number of probe SNR values to evaluate [30]
                      4  q.cs  weighting of slope relative to threshold in cost function [1]
                      5  q.dh  minimum step size in dB for probe SNRs [0.2]
                      6  q.sl  min slope at threshold [0.02]
                      7  q.kp  number of std deviations of the pdfs to keep [4]
                      8  q.hg  amount to grow expected gains in ni trials [1.3]
                      9  q.cf  cost function: 1=variance, 2=entropy [2]
                     10  q.pm  psychometric model: 1=logistic, 2=cumulative gaussian [1]
                     11  q.lg  use log slope in pdf: 0=no, 1=yes [1]
          xp{n}(:) list of available probe SNR values
          i        model probed
          x        probe SNR value used
          r        response: 0=wrong, 1=right.

 Outputs:
          xx       recommended probe SNR
          ii       recommended model to probe next
          m(2,n,3) estimated srt and slope of all models
                   m(:,:,1:3) are respectively the mean, mode (MAP) and marginal mode estimates
          v(3,n)   estimated covariance matrix entries:
                   [var(srt) cov(srt,slope) var(slope)]'

 Algorithm parameters:

 The algorithm estimates the psychometric function for a number of models simultaneously.
 A psychometric function specifies the probability of correct recognition as a function of
 SNR and is completely specified by two parameters: the SNR (in dB) and the slope (in 1/dB)
 at a specified target recognition probability (e.g. 0.5 or 0.75). The p(:,n) parameters specify
 some of the details of the psychometric function and can be different for each model:
   p(1,n) gives the target recognition probability
   p(2,n) gives the probability of incorrect recognition at very good SNRs (the "miss" probability).
          If this value is made too low, a single unwarrented recognition error will have a large
          effect of the estimated parameters and greatly lengthen the time to convergence. The default
          value is 4%.
   p(3,n) gives the probability of correct recognition at very poor SNRs (the "guess" probabiity).
          This should be set to 1/N where N is the number of possible responses to a stimulus.
 p(4:5,n) These give the initial min and max SNR at the target recognition probability. They will
           be adjusted by the algorithm if necessary but wrong values will delay convergence.
 p(6:7,n) These given the initial min and max slope (in probability per dB) at the target
          recognition probability.
 The remaining parameters are shared between all the models and control how the algorithm operates.
   q(1:2) These parameters determine the sampling density of the joint pdf of SNR and Slope.
   q(3)   This parameter specifies how many potential values of probe SNR to evaluate in order to
          determine which is likely to give the most improvement in the parameter estimates.
   q(4)   This parameter gives the relative weight of SNR and Slope in the cost function. Increasing
          its value will improve the slope estimate (or log(slope) estimate) at the expense of the
          SNR estimate. Actually its value is not all that critical.
   q(5)   At each iteration psycest evaluates several potential probe SNR levels to see which is
          likely to give the most improvement to the parameter estimates. This parameter fixes the
          minimum spacing between these potential probe values. It only has an effect when the variances
          of the parameter estimates are very small.
   q(6)   To prevent the routine getting lost, this parameter specifies the smallest reasonable value
          of the Slope parameter at the target recognition probability. Under normal circumstances, it
          has no effect.
   q(7)   For each model, the routine maintains a sampled version of the joint pdf of the SNR and slope.
          The sampling grid is reclculated after each iteration to encompass this number of standard
          deviations in each dimension.
   q(8)   At each iteration, psycest advises which model to probe next on the basis of which
          gives the greatest expected reduction in cost function. To ensure that all models
          are periodically sampled, this expected reduction of each unprobed model is multiplied
          by this parameter at each iteration. Thus a model will eventually be probed even if
          its expected cost factor improvement is small.
   q(9)   This determines whether the recommended probe SNR to use at the next iteration is chosen to
          minimize the expected variance or the entropy of the estimated SNR and slope distributions.
          My experience is that entropy (the default) gives faster convergence.
  q(10)   This selects whether the underlying model is a logistic function (1) or a cumulative
          gaussian (2). The choice makes little difference unless the "miss" or "guess" probabilities
          are very very small.
  q(11)   This selects whether the internal pdf samples "slope" or "log(slope)". It is recommended
          that you stick to the default of log(slope) since this results in more symmetrical
          distributions.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [xx,ii,m,v]=psycest(iq,x,r,xp)
0002 % Estimate multiple psychometric functions
0003 %
0004 % Usage: [xx,ii,m,v]=psycest(-n,p,q,xp) % initialize n models
0005 %        [xx,ii,m,v]=psycest(i,x,r)     % supply a trial result to psycest
0006 %                    psycest(i)         % plot pdf of model i
0007 %              [p,q]=psychest(0)        % output model parameters (or print them if no outputs)
0008 %
0009 % Inputs:
0010 %         -n        minus the number of models
0011 %          p(:,n)   parameters for each model
0012 %                      1  thresh [0.75]
0013 %                      2  miss [0.04]
0014 %                      3  guess [0.1]
0015 %                      4  SNR min [-20]
0016 %                      5  SNR max [20]
0017 %                      6  Slope min [0]
0018 %                      7  slope max [0.5]
0019 %          q(:)     parameters common to all models (vector or struct)
0020 %                      1  q.nx  number of SNR values in pdf [40]
0021 %                      2  q.ns  number of slope values in pdf [21]
0022 %                      3  q.nh  number of probe SNR values to evaluate [30]
0023 %                      4  q.cs  weighting of slope relative to threshold in cost function [1]
0024 %                      5  q.dh  minimum step size in dB for probe SNRs [0.2]
0025 %                      6  q.sl  min slope at threshold [0.02]
0026 %                      7  q.kp  number of std deviations of the pdfs to keep [4]
0027 %                      8  q.hg  amount to grow expected gains in ni trials [1.3]
0028 %                      9  q.cf  cost function: 1=variance, 2=entropy [2]
0029 %                     10  q.pm  psychometric model: 1=logistic, 2=cumulative gaussian [1]
0030 %                     11  q.lg  use log slope in pdf: 0=no, 1=yes [1]
0031 %          xp{n}(:) list of available probe SNR values
0032 %          i        model probed
0033 %          x        probe SNR value used
0034 %          r        response: 0=wrong, 1=right.
0035 %
0036 % Outputs:
0037 %          xx       recommended probe SNR
0038 %          ii       recommended model to probe next
0039 %          m(2,n,3) estimated srt and slope of all models
0040 %                   m(:,:,1:3) are respectively the mean, mode (MAP) and marginal mode estimates
0041 %          v(3,n)   estimated covariance matrix entries:
0042 %                   [var(srt) cov(srt,slope) var(slope)]'
0043 %
0044 % Algorithm parameters:
0045 %
0046 % The algorithm estimates the psychometric function for a number of models simultaneously.
0047 % A psychometric function specifies the probability of correct recognition as a function of
0048 % SNR and is completely specified by two parameters: the SNR (in dB) and the slope (in 1/dB)
0049 % at a specified target recognition probability (e.g. 0.5 or 0.75). The p(:,n) parameters specify
0050 % some of the details of the psychometric function and can be different for each model:
0051 %   p(1,n) gives the target recognition probability
0052 %   p(2,n) gives the probability of incorrect recognition at very good SNRs (the "miss" probability).
0053 %          If this value is made too low, a single unwarrented recognition error will have a large
0054 %          effect of the estimated parameters and greatly lengthen the time to convergence. The default
0055 %          value is 4%.
0056 %   p(3,n) gives the probability of correct recognition at very poor SNRs (the "guess" probabiity).
0057 %          This should be set to 1/N where N is the number of possible responses to a stimulus.
0058 % p(4:5,n) These give the initial min and max SNR at the target recognition probability. They will
0059 %           be adjusted by the algorithm if necessary but wrong values will delay convergence.
0060 % p(6:7,n) These given the initial min and max slope (in probability per dB) at the target
0061 %          recognition probability.
0062 % The remaining parameters are shared between all the models and control how the algorithm operates.
0063 %   q(1:2) These parameters determine the sampling density of the joint pdf of SNR and Slope.
0064 %   q(3)   This parameter specifies how many potential values of probe SNR to evaluate in order to
0065 %          determine which is likely to give the most improvement in the parameter estimates.
0066 %   q(4)   This parameter gives the relative weight of SNR and Slope in the cost function. Increasing
0067 %          its value will improve the slope estimate (or log(slope) estimate) at the expense of the
0068 %          SNR estimate. Actually its value is not all that critical.
0069 %   q(5)   At each iteration psycest evaluates several potential probe SNR levels to see which is
0070 %          likely to give the most improvement to the parameter estimates. This parameter fixes the
0071 %          minimum spacing between these potential probe values. It only has an effect when the variances
0072 %          of the parameter estimates are very small.
0073 %   q(6)   To prevent the routine getting lost, this parameter specifies the smallest reasonable value
0074 %          of the Slope parameter at the target recognition probability. Under normal circumstances, it
0075 %          has no effect.
0076 %   q(7)   For each model, the routine maintains a sampled version of the joint pdf of the SNR and slope.
0077 %          The sampling grid is reclculated after each iteration to encompass this number of standard
0078 %          deviations in each dimension.
0079 %   q(8)   At each iteration, psycest advises which model to probe next on the basis of which
0080 %          gives the greatest expected reduction in cost function. To ensure that all models
0081 %          are periodically sampled, this expected reduction of each unprobed model is multiplied
0082 %          by this parameter at each iteration. Thus a model will eventually be probed even if
0083 %          its expected cost factor improvement is small.
0084 %   q(9)   This determines whether the recommended probe SNR to use at the next iteration is chosen to
0085 %          minimize the expected variance or the entropy of the estimated SNR and slope distributions.
0086 %          My experience is that entropy (the default) gives faster convergence.
0087 %  q(10)   This selects whether the underlying model is a logistic function (1) or a cumulative
0088 %          gaussian (2). The choice makes little difference unless the "miss" or "guess" probabilities
0089 %          are very very small.
0090 %  q(11)   This selects whether the internal pdf samples "slope" or "log(slope)". It is recommended
0091 %          that you stick to the default of log(slope) since this results in more symmetrical
0092 %          distributions.
0093 
0094 %      Copyright (C) Mike Brookes 2009-2010
0095 %      Version: $Id: psycest.m 713 2011-10-16 14:45:43Z dmb $
0096 %
0097 %   VOICEBOX is a MATLAB toolbox for speech processing.
0098 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
0099 %
0100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0101 %   This program is free software; you can redistribute it and/or modify
0102 %   it under the terms of the GNU General Public License as published by
0103 %   the Free Software Foundation; either version 2 of the License, or
0104 %   (at your option) any later version.
0105 %
0106 %   This program is distributed in the hope that it will be useful,
0107 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0108 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0109 %   GNU General Public License for more details.
0110 %
0111 %   You can obtain a copy of the GNU General Public License from
0112 %   http://www.gnu.org/copyleft/gpl.html or by writing to
0113 %   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
0114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0115 
0116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0117 % Bugs/Suggestions:
0118 % (1) allow lookahead by 2 tests rather than 1
0119 % (2)use a structure for input parameters
0120 % (3)should only resample the pdfs when necessary
0121 % (4)add a forgetting factor for old measurements
0122 % (8) use quadratic interpolation to find cost function minimum
0123 % (10) optionally output the whole pdf + its axis values
0124 % (11) optionally output all model probe values
0125 % (13) Should perhaps estimate and return the mean and slope compensated for the guess rate
0126 %      i.e. if you want p, you actually test at guess+ p*(1-guess-miss)/(1-miss)
0127 % (17) remember probe snrs, models and results and recalculate the entire
0128 %      array when changing precision
0129 % (18) could force probe SNRs to be a multiple of minimum step size
0130 % (19) use a non-uniform prior e.e. 1/(1+x^2)
0131 % (20) possibly use different parametrization (e.g. 1/slope or a second SRT threshold)
0132 % (22) save inputs so that pdfs can be recalculated when rescaling
0133 % (24) Parametrize slope as x=(100s^2-1)/20s to make the distribution more uniform
0134 %      inverse is s=(sqrt(x^2+1)-x)/10; alternatively use log(slope)
0135 % (25) optionally have no prior (i.e. maximum likelihood)
0136 % (26) Check why the estimated variances are too small
0137 % (27) Adapt range of potential probes if optimum is at the limit
0138 % (28) Resample the pdf on the basis of the marginal distributions
0139 % (29) Select the probe range on the basis of marginal distributions
0140 % (30) Resample the pdfs by a factor of 2 always
0141 % (31) use uneven samples in pdf concentrated in the middle
0142 % (32) Use a parametric mixture including one-sided constants for the pdf
0143 % (33) Selection of subset of prescribed probe SNRs is not optimum
0144 % (34) use quadratic interpolation to select the probe SNR unless using fixed values
0145 % (35) expand the pdf grid based on the effective number of samples (like particle filters)
0146 
0147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0148 % persistent variables
0149 % sizes: nx=SNR values in pdf
0150 %        ns=slope values in pdf (1/std dev of cumulative gaussian)
0151 %        nh=potential test SNRs
0152 %        ni=simultaneous models being estimated
0153 % wq(ns*nx,ni) = prob of model; each column is a vectorized ns*nx matrix
0154 % nr(1,10)      = parameter values: [SNR-pdf slope-pdf SNR-probe ...]
0155 % pr(7,ni)     = input model parameters
0156 % qr(4,ni)     = derived model parameters
0157 % xq(nr(1),ni) = SNR values in pdf
0158 % sq(nr(2),ni) = slope values in pdf
0159 % mq(2,ni)     = estimated srt and slope of all models
0160 % vq(3,ni)     = estimated covariance matrix entries:[var(srt) cov(srt,slope) var(slope)]'
0161 % xn(1,ni)     = next probe value to use
0162 % hn(1,ni)     = expected decrease in cost function after next probe
0163 
0164 persistent wq xq sq nr pr qr mq vq xn hn hfact xz
0165 
0166 % algorithm parametes that could be programmable
0167 pfloor=0.001;    % pdf floor relative to uniform distribution
0168 trynsig=2; % number of standard deviations to explore
0169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0170 if iq<0  % initialization
0171     ni=-iq;                                                 % number of models
0172     pr=repmat([0.75 0.04 0.1 -20 20 0 0.5]',1,ni);          % default parameters
0173     if nargin>1
0174         if size(x,2)>1
0175             if size(x,2)>ni
0176                 error('initialization parameter argument has too many columns');
0177             end
0178             pr(1:size(x,1),1:size(x,2))=x;
0179         else
0180             pr(1:size(x,1),:)=repmat(x,1,ni);
0181         end
0182     end
0183     nr=[40 21 30 1 0.2 0.02 4 1.3 2 1 1]';                      % default parameter values
0184     nrf={'nx','ns','nh','cs','dh','sl','kp','hg','cf','pm','lg'};     % parameter field names
0185     numnr=length(nr);
0186     if nargin>2
0187         if isstruct(r)
0188             fnn=fieldnames(r);
0189             for i=1:length(fnn)
0190                 mk=strcmp(fnn{i},nrf);
0191                 if any(mk)
0192                     nr(mk)=r.(fnn{i});
0193                 end
0194             end
0195         else
0196             nr(1:min(numnr,numel(r)))=r(:);
0197         end
0198         nr(1:3)=round(nr(1:3));
0199     end
0200     pr(6,:)=max(pr(6,:),nr(6));                         % low limit of slope in prob/dB
0201     nsxq=nr(1)*nr(2);
0202     xq=(0:nr(1)-1)'*(pr(5,:)-pr(4,:))/(nr(1)-1)+repmat(pr(4,:),nr(1),1);
0203     if nr(11)  % if log slope
0204         sq=(1-nr(2):0)'*(log(pr(7,:))-log(max(pr(6,:),nr(6))))/(nr(2)-1)+repmat(log(pr(7,:)),nr(2),1);
0205     else
0206         sq=(0:nr(2)-1)'*(pr(7,:)-pr(6,:))/(nr(2)-1)+repmat(pr(6,:),nr(2),1);
0207     end
0208     wq=repmat(1/nsxq,nsxq,ni);                          % initialize to uniform pdf
0209     qr=zeros(5,ni);
0210     qr(1,:)=1-pr(2,:)-pr(3,:);                          % prob range covered by cumulative gaussian
0211     qr(2,:)=(pr(1,:)-pr(3,:))./qr(1,:);                 % cumulative gaussian probability at threshold
0212     switch nr(10)
0213         case 1
0214             qr(3,:)=log(qr(2,:)./(1-qr(2,:)));                      % x position of target in std measure
0215             qr(4,:)=qr(1,:).*qr(2,:).*(1-qr(2,:));                  % slope*"stddev" at threshold
0216         case 2
0217             qr(3,:)=norminv(qr(2,:));                           % x position of target in std measure
0218             qr(4,:)=qr(1,:).*normpdf(qr(3,:));                  % slope*stddev at threshold
0219         otherwise
0220             error('Unrecognised psychometric model selection');
0221     end
0222     mq=repmat([mean(xq,1); mean(sq,1)],[1,1,3]);        % initial means
0223     vq=[var(xq,1,1); zeros(1,ni); var(sq,1,1)];         % initial variances
0224     %     hn=[1-nr(4) 0 nr(4)]*vq;  % artificially high value of cost function ensures all models are probed early on
0225     hn=repmat(Inf,1,ni);    % very high initial cost function
0226     hfact=nr(8)^(1/ni);     % growth factor to ensure that no model is neglected for too long
0227     xn=mq(1,:);             % start at mean value
0228     if nargin>=4 && ~isempty(xp)
0229         if iscell(xp)
0230             xz=xp;
0231         else
0232             xz=repmat(num2cell(xp(:)',2),ni,1);        % else replicate for each model
0233         end
0234         for i=1:ni
0235             [dummy,j]=min(abs(xz{i}-mq(1,i)));      % select the closest available probe to the mean
0236             xn(i)=xz{i}(j);
0237         end
0238     else
0239         xz=cell(ni,1);          % make empty cells
0240     end
0241 elseif iq>0 && nargin==3        % update pdfs with a new probe result
0242     nxq=nr(1);
0243     nsq=nr(2);
0244     nxh=nr(3);
0245     nsxq=nxq*nsq;
0246     %     thresh=pr(1,iq);            % target threshold
0247     guess=pr(3,iq);             % guess rate (1/choices)
0248     pscale=qr(1,iq);            % prob range left after subtracting miss and guess probs
0249     xtstd=qr(3,iq);             % x position of target in std measure
0250     sqi=sq(:,iq);               % slope (or log slope) values in PDF
0251     if nr(11)  % if log slope
0252         sqis=exp(sqi)/qr(4,iq);     % inverse std dev of gaussian (proportional to slope)
0253     else
0254         sqis=sqi/qr(4,iq);          % inverse std dev of gaussian (proportional to slope)
0255     end
0256     xqi=xq(:,iq);
0257     wqi=wq(:,iq);
0258     %
0259     % update probabilities with the previous test result
0260     % If r==1, we multiply by a horizontally reflected version of the psychometric function that equals
0261     % the threshold (e.g. 0.75) at the probe SNR, x, for all slopes.
0262     % If r==0, we multiply by 1- this reflected version which therefore equals (1-thresh) at x.
0263     %
0264     r0=r==0;
0265     switch nr(10)
0266         case 1
0267             wqi=wqi.*(r0+(1-2*r0)*(guess+pscale*((1+exp(reshape(sqis*xqi'-xtstd,nsxq,1)-repmat(sqis,nxq,1)*x)).^(-1)))); %  P(l | r,x)
0268         case 2
0269             wqi=wqi.*(r0+(1-2*r0)*(guess+pscale*normcdf(repmat(sqis,nxq,1)*x-reshape(sqis*xqi'-xtstd,nsxq,1)))); %  P(l | r,x)
0270         otherwise
0271             error('Unrecognised psychometric model selection');
0272     end
0273     wqi=wqi./sum(wqi,1);                        % normalize
0274     %     wq(:,iq)=wqi;               % save updated probabilities (not needed if we always interpolate them)
0275 
0276     % **** this section copied to graph plotting ****
0277     % Calculate mean and covariance and entropy
0278 
0279     wqsx=reshape(wqi,nsq,nxq);
0280     px=sum(wqsx,1);                             % p(x0)
0281     ps=sum(wqsx,2);                             % p(s0)
0282     xe=px*xqi;                                  % E(x0)
0283     se=ps'*sqi;                                 % E(s0)
0284 
0285     [pxpk,xm]=max(px);                          % marginal mode in x
0286     if xm>1 && xm<nxq                           % use quadratic interpolation if possible
0287         [dum,xm2]=quadpeak(px(xm-1:xm+1)');
0288         xm=xm+xm2-2;
0289     end
0290     xm=(2-xm)*xqi(1)+(xm-1)*xqi(2);             % marginal mode(x0)
0291 
0292     [pspk,sm]=max(ps);
0293     if sm>1 && sm<nsq                           % use quadratic interpolation if possible
0294         [dum,sm2]=quadpeak(ps(sm-1:sm+1));
0295         sm=sm+sm2-2;
0296     end
0297     sm=(2-sm)*sqi(1)+(sm-1)*sqi(2);             % marginal mode(s0)
0298 
0299     [wqpk,j]=max(wqi);
0300     i=1+floor((j-1)/nsq);
0301     j=j-nsq*(i-1);
0302     if i>1 && i<nxq && j>1 && j<nsq             % use quadratic interpolation if possible
0303         [dum,ji]=quadpeak(wqsx(j-1:j+1,i-1:i+1));
0304         i=i+ji(2)-2;
0305         j=j+ji(1)-2;
0306     end
0307     xj=(2-i)*xqi(1)+(i-1)*xqi(2);               % joint mode  x
0308     sj=(2-j)*sqi(1)+(j-1)*sqi(2);               % joint mode: s
0309     xv=px*(xqi.^2)-xe^2;                        % Var(x0)
0310     sv=ps'*(sqi.^2)-se^2;                       % Var(s0)
0311     sxv=wqi'*(repmat(sqi,nxq,1).*reshape(repmat(xqi',nsq,1),nsxq,1))-xe*se; % Cov(s0*x0)
0312 
0313     % ************   end of copied section
0314 
0315     mq(:,iq,1)=[xe; se];                        % save means
0316     mq(:,iq,2)=[xj; sj];                        % save means
0317     mq(:,iq,3)=[xm; sm];                        % save means
0318     vq(:,iq)=[xv; sxv; sv];                     % save covariance matrix
0319     xh=(px*log(px)')*(xqi(1)-xqi(2));           % h(x0)
0320     sh=(ps'*log(ps))*(sqi(1)-sqi(2));              % h(s0)
0321 
0322     % now estimate the next probe SNR $$$$
0323 
0324     if ~numel(xz{iq})                               % if no list of probe SNRs was specified
0325         ytry=exp(0.25i*pi*(0:7))';   % points around the circle
0326         ytry=[real(ytry) imag(ytry)];
0327         [vtry,dtry]=eig([xv sxv; sxv sv]);  % eigendecomposition of covariance matrix
0328         tryxs=repmat([xe,se],8,1)+trynsig*ytry*sqrt(dtry)*vtry';
0329         pmin=0.05;                             % target probe success probability
0330         if nr(11)
0331             tryxs(:,2)=qr(4,iq)*exp(-tryxs(:,2));        % convert log(slope) to std dev
0332         else
0333             tryxs(:,2)=qr(4,iq)*tryxs(:,2).^(-1);             % convert slope to std dev
0334         end
0335         switch nr(10)
0336             case 1 % logistic
0337                 qmax=max(tryxs(:,1)+(log((1-pmin)/pmin)-xtstd)*tryxs(:,2));
0338                 qmin=min(tryxs(:,1)+(log(pmin/(1-pmin))-xtstd)*tryxs(:,2));
0339             case 2 % cumulative gaussian
0340                 qmax=max(tryxs(:,1)+(norminv(1-pmin)-xtstd)*tryxs(:,2));
0341                 qmin=min(tryxs(:,1)+(norminv(pmin)-xtstd)*tryxs(:,2));
0342         end
0343         dxt=max(nr(5),(qmax-qmin)/nxh);      % minimum step size of nr(5) [0.2 dB]
0344         xt=(qmin+qmax)/2+((1:nxh)-(1+nxh)/2)*dxt;
0345     else                                            % if a specific list of probe SNRs exists
0346         xzi=xz{iq};                                 % xzi is the list of available probe SNRs
0347         if numel(xzi)<=nxh                          % use all available probe SNRs if there are not too many
0348             xt=xzi;
0349         else
0350             [xt,ixt]=min(abs(xzi-xe));                  % find the closest one to xe ** not necessarily optimum ***
0351             ixt=max(1,min(1+numel(xzi)-nxh,ixt-floor((1+nxh)/2))); % arrange symmetrically around xt
0352             xt=xzi(ixt:min(ixt+nxh-1,numel(xzi)));
0353         end
0354     end
0355     nxhp=length(xt);  % xt are the potential probe SNRs
0356     switch nr(10)
0357         case 1
0358             prt=guess+pscale*((1+exp(repmat(reshape(sqis*xqi'-xtstd,nsxq,1),1,nxhp)-repmat(sqis,nxq,1)*xt)).^(-1)); %  P(r | l,x)
0359         case 2
0360             prt=guess+pscale*normcdf(repmat(sqis,nxq,1)*xt-repmat(reshape(sqis*xqi'-xtstd,nsxq,1),1,nxhp)); %  P(r | l,x)
0361     end
0362     wqt=repmat(wqi,1,nxhp);
0363     pl1=prt.*wqt;                       % posterior prob given success = p(l | x,r=1) unnormalized
0364     pl0=(wqt-pl1);                      % posterior prob given failure = p(l | x,r=0) unnormalized
0365     prh=sum(pl1,1);                     % p(r | x)=Sum{P(r | l,x)*P(l)} [note wqt is normalized] (row vector)
0366     pl1=pl1./repmat(prh,nsxq,1);        % normalize
0367     pl0=pl0./repmat(1-prh,nsxq,1);      % posterior prob given failure = p(l | x,r=0) normalized
0368     px1=squeeze(sum(reshape(pl1,nsq,nxq,[]),1));    % p(x0 | x,r=1)
0369     px0=squeeze(sum(reshape(pl0,nsq,nxq,[]),1));    % p(x0 | x,r=0)
0370     ps1=squeeze(sum(reshape(pl1,nsq,nxq,[]),2));    % p(s0 | x,r=1)
0371     ps0=squeeze(sum(reshape(pl0,nsq,nxq,[]),2));    % p(s0 | x,r=0)
0372     xet1=xqi'*px1;                                  % E(x0 | x,r=1)
0373     xvt1=(xqi.^2)'*px1-xet1.^2;                     % Var(x0 | x,r=1)
0374     xet0=xqi'*px0;                                  % E(x0 | x,r=0)
0375     xvt0=(xqi.^2)'*px0-xet0.^2;                     % Var(x0 | x,r=0)
0376     xvt=xvt1.*prh+xvt0.*(1-prh);                    % E(Var(x0 | x ))
0377     set1=sqi'*ps1;                                  % E(s0 | x,r=1)
0378     svt1=(sqi.^2)'*ps1-set1.^2;                     % Var(s0 | x,r=1)
0379     set0=sqi'*ps0;                                  % E(s0 | x,r=0)
0380     svt0=(sqi.^2)'*ps0-set0.^2;                     % Var(s0 | x,r=0)
0381     svt=svt1.*prh+svt0.*(1-prh);                    % E(Var(s0 | x ))
0382     xht1=sum(log(px1).*px1,1);                      % -H(x0 | x,r=1)
0383     xht0=sum(log(px0).*px0,1);                      % -H(x0 | x,r=0)
0384     xht=(xht1.*prh+xht0.*(1-prh))*(xqi(1)-xqi(2));    % h(x0 | x)
0385     sht1=sum(log(ps1).*ps1,1);                      % -H(s0 | x,r=1)
0386     sht0=sum(log(ps0).*ps0,1);                      % -H(s0 | x,r=0)
0387     sht=(sht1.*prh+sht0.*(1-prh))*(sqi(1)-sqi(2));    % h(s0 | x)
0388     switch nr(9)
0389         case 1
0390             hx=(xvt + nr(4)*svt)/(1+nr(4));               % cost function for each possible test SNR
0391             [hxmin,ix]=min(hx);                         % find the minimum of cost function
0392             hn(iq)=(xv + nr(4)*sv)/(1+nr(4))-hxmin;        % expected decrease in cost function
0393         case 2
0394             hx=(xht + nr(4)*sht)/(1+nr(4));                % cost function for each possible test SNR
0395             [hxmin,ix]=min(hx);                            % find the minimum of cost function
0396             hn(iq)=(xh + nr(4)*sh)/(1+nr(4))-hxmin;        % expected decrease in cost function
0397         otherwise
0398             error('Unrecognised cost function option');
0399     end
0400     xn(iq)=xt(ix);                              % next probe value for this model
0401     %         fprintf('Probe range: %.3g %.3g; choose %.3g\n',xt(1),xt(end),xt(ix));
0402 
0403 
0404     % rescale the pdfs if necessary
0405 
0406     ssd=sqrt(sv);
0407     xsd=sqrt(xv);
0408     if nr(11)
0409         sq2=linspace(max(log(nr(6)),se-nr(7)*ssd),se+nr(7)*ssd,nsq)';
0410     else
0411         sq2=linspace(max(nr(6),se-nr(7)*ssd),se+nr(7)*ssd,nsq)';
0412     end
0413     xq2=linspace(xe-nr(7)*xsd,xe+nr(7)*xsd,nxq)';   % new x axis values
0414     % do linear interpolation in the x direction
0415     wqi=reshape(wqi,nsq,nxq);           % turn into a matrix for easy interpolation
0416     xqf=(xq2-xq(1,iq))/(xq(2,iq)-xq(1,iq));
0417     xqj=ceil(xqf);
0418     xqf=xqj-xqf;
0419     xqg=1-xqf;
0420     xqf((xqj<=0) | (xqj>nxq))=0;
0421     xqg((xqj<0) | (xqj>=nxq))=0;
0422     wq2=wqi(:,min(max(xqj,1),nxq)).*repmat(xqf',nsq,1)+wqi(:,min(max(xqj+1,1),nxq)).*repmat(xqg',nsq,1);
0423     % do linear interpolation in the s direction
0424     sqf=(sq2-sq(1,iq))/(sq(2,iq)-sq(1,iq));
0425     sqj=ceil(sqf);
0426     sqf=sqj-sqf;
0427     sqg=1-sqf;
0428     sqf((sqj<=0) | (sqj>nsq))=0;
0429     sqg((sqj<0) | (sqj>=nsq))=0;
0430     wq2=wq2(min(max(sqj,1),nsq),:).*repmat(sqf,1,nxq)+wq2(min(max(sqj+1,1),nsq),:).*repmat(sqg,1,nxq);
0431     % now normalize and apply a floor
0432     wq2=wq2(:);     % turn back into a vector
0433     wq2=wq2/sum(wq2,1);  % normalize
0434     wq2=max(wq2,pfloor/nsxq); %impose a floor
0435     wq2=wq2/sum(wq2,1);  % normalize again
0436     sq(:,iq)=sq2;
0437     xq(:,iq)=xq2;
0438     wq(:,iq)=wq2;
0439 elseif iq==0        % output model parameters
0440     xx=pr;
0441     ii=nr;
0442     if ~nargout
0443         pdesc={'Threshold','Miss prob','Guess Prob','Min SNR','Max SNR','Min Slope','Max Slope'};
0444         fprintf('\n*********\nModel-specific Parameters\n');
0445         for i=1:7
0446             fprintf('%4d) %s: ',i,pdesc{i});
0447             if size(pr,2)>1
0448                 fprintf('%.5g, ',pr(i,1:size(pr,2)-1));
0449             end
0450             fprintf('%.5g\n',pr(i,size(pr,2)));
0451         end
0452         qdesc={'nx  SNR values in PDF', ...
0453             'ns  Slope values in PDF', ...
0454             'nh  Probe SNR values to evaluate', ...
0455             'cs  Weighting of slope relative to threshold in cost function', ...
0456             'dh  Min step size in dB for probe SNRs', ...
0457             'sl  Min slope at threshold', ...
0458             'kp  Std deviations of the pdfs to keep', ...
0459             'hg  Amount to grow expected gains in ni trials', ...
0460             'cf  Cost function', ...
0461             'pm  Psychometric model'};
0462         qoptf=[9 10]; % fields with options
0463         qoptval={'variance','entropy'; ...
0464             'logistic','cumulative gaussian'};
0465         fprintf('\nShared Parameters\n');
0466         for i=1:10
0467             fprintf('%4d) %s: ',i,qdesc{i});
0468             j=find(qoptf==i,1);
0469             if numel(j)
0470                 fprintf('%d=%s\n',nr(i),qoptval{j,nr(i)});
0471             else
0472                 fprintf('%.5g\n',nr(i));
0473             end
0474         end
0475     end
0476 end
0477 
0478 % now select the appropriate model to probe next
0479 
0480 if iq~=0
0481     [hnmin,ii]=max(hn);         % chose model with the biggest expected decrease
0482     hn=hn*hfact;         % increase values to ensure they all get a chance
0483     xx=xn(ii);
0484     m=mq;
0485     v=vq;
0486     if nr(11)
0487         m(2,:,:)=exp(m(2,:,:));  % convert to real slope
0488         v(2,:)=v(2,:).*m(2,:,1); % correct the covariance
0489         v(3,:)=v(3,:).*m(2,:,1).^2; % and the slope variance
0490     end
0491 end
0492 
0493 if ~nargout && iq>0
0494     sqi=sq(:,iq);
0495     nsq=length(sqi);
0496     xqi=xq(:,iq);
0497     nxq=length(xqi);
0498     wqi=wq(:,iq);
0499     nsxq=nxq*nsq;
0500 
0501     % **** this section copied from main processing ****
0502     % Calculate mean and covariance and entropy
0503 
0504     wqsx=reshape(wqi,nsq,nxq);
0505     px=sum(wqsx,1); % p(x0)
0506     ps=sum(wqsx,2); % p(s0)
0507     xe=px*xqi;                            % E(x0)
0508     se=ps'*sqi;                            % E(s0)
0509     [pxpk,xm]=max(px);
0510     if xm>1 && xm<nxq  % use quadratic interpolation if possible
0511         [dum,xm2]=quadpeak(px(xm-1:xm+1)');
0512         xm=xm+xm2-2;
0513     end
0514     xm=(2-xm)*xqi(1)+(xm-1)*xqi(2);          % marginal mode(x0)
0515     [pspk,sm]=max(ps);
0516     if sm>1 && sm<nsq  % use quadratic interpolation if possible
0517         [dum,sm2]=quadpeak(ps(sm-1:sm+1));
0518         sm=sm+sm2-2;
0519     end
0520     sm=(2-sm)*sqi(1)+(sm-1)*sqi(2);          % marginal mode(s0)
0521     [wqpk,j]=max(wqi);
0522     i=1+floor((j-1)/nsq);
0523     j=j-nsq*(i-1);
0524     if i>1 && i<nxq && j>1 && j<nsq % use quadratic interpolation if possible
0525         [dum,ji]=quadpeak(wqsx(j-1:j+1,i-1:i+1));
0526         i=i+ji(2)-2;
0527         j=j+ji(1)-2;
0528     end
0529     xj=(2-i)*xqi(1)+(i-1)*xqi(2);    % joint mode  x
0530     sj=(2-j)*sqi(1)+(j-1)*sqi(2);   % joint mode: s
0531     xv=px*(xqi.^2)-xe^2;               % Var(x0)
0532     sv=ps'*(sqi.^2)-se^2;               % Var(s0)
0533     sxv=wqi'*(repmat(sqi,nxq,1).*reshape(repmat(xqi',nsq,1),nsxq,1))-xe*se; % Cov(s0*x0)
0534 
0535     % ************   end of copied section
0536 
0537     % draw final 2-D distribution
0538     nxq=nr(1);
0539     nsq=nr(2);
0540     axm=[3 -2; 2 -1];
0541     xqi2=[axm*xqi(1:2);xqi];
0542     sqi2=[axm*sqi(1:2);sqi];
0543     imagesc(xqi2,sqi2,[zeros(1,2) px/pxpk; zeros(1,nxq+2);ps/pspk zeros(nsq,1) wqsx/wqpk]);
0544     hold on
0545     plot(xe,se,'wo',xm,sm,'w^',xj,sj,'w*');
0546     plot(xqi2(2),se,'wo',xqi2(2),sm,'w^',xqi2(2),sj,'w*');
0547     plot(xe,sqi2(2),'wo',xm,sqi2(2),'w^',xj,sqi2(2),'w*');
0548     t=linspace(0,2*pi,200);
0549     xcir=cos(t);
0550     scir=sin(t);
0551     vcir=sqrt((sv*xcir.^2+xv*scir.^2-2*sxv*xcir.*scir)/(xv*sv-sxv^2));
0552     plot(xe+xcir./vcir,se+scir./vcir,'w-');
0553     hold off
0554     axis 'xy';
0555     %     colorbar;
0556     %     cblabel('Relative Probability');
0557     xlabel(sprintf('SNR @ %d%%SRT (dB)',round(pr(1)*100)));
0558     if nr(11)
0559         ylabel('Log psychometric Slope at threshold (prob/dB)');
0560     else
0561         ylabel('Psychometric Slope at threshold (prob/dB)');
0562     end
0563     title('Joint pdf: o mean, * mode, \Delta marginal mode');
0564 end

Generated on Thu 23-Feb-2012 09:25:48 by m2html © 2003