📄 pulsetrain.m
字号:
function [prperpulse, stdperpulse]=pulsetrain(stim,properties,pulserate,pulsewidth)% [prperpulse, stdperpulse]=pulsetrain(stim,properties,pulserate,pulsewidth)%% INPUT:%% stim is the stimulus intensity in units of microA, NOT dB%% properties is a structure containing the model parameters:%% properties.resptype is the fiber I/O function type:% 'stp' = deterministic (step-function) model% '3_p' = 3-piece linear model% 'erf' = stochastic (error-function) model%% properties.thrsh is the matrix of fiber thresholds%% properties.noisestd is the matrix of fiber noise standard deviations%% pulserate is the rate of stimulation in pulses/s%% pulsewidth is the phase duration in microseconds/phase%% OUTPUT:%% prperpulse is the discharge probability (mean discharge rate) per pulse%% stdperpulse is the standard deviation in discharge rate per pulse%% Usage Agreement: Any publication of results obtained using this model should cite both-%% [1] Bruce, I. C., Irlicht, L. S., White, M. W., O'Leary, S. J., Dynes,% S., Javel, E., Clark, G. M. (1999) "A stochastic model of the% electrically stimulated auditory nerve: Pulse-train response,"% IEEE Transactions on Biomedical Engineering, 46(6):630-637.%% and%% [2] Bruce, I. C. (1997) Spatiotemporal coding of sound in the auditory% nerve for cochlear implants, PhD Thesis, The University of Melbourne, Australia.% Copyright (c) 1996-1999 Ian Bruce% Created by Ian Bruce, 1996% Released for public distribution as version 1.1, 1999Fs = 1e5; % Sampling frequency in Hzresptype = properties.resptype;thrsh = properties.thrsh;noisestd = properties.noisestd;% Run pulse-train model for each individual fiber at each stimulus intensityfor i=1:size(stim,1) for j=1:size(stim,2) disp([num2str(pulserate) 'Hz - Run ' num2str(size(stim,2)*(i-1)+j) '/' num2str(size(stim,1)*size(stim,2))]) [prperpulse(i,j), stdperpulse(i,j)] = pulsetrain_perelement(stim(i,j),resptype,thrsh(i,j),noisestd(i,j),pulserate,pulsewidth,Fs); endendfunction [prperpulse, stdperpulse, isiprs, Pinf]=pulsetrain_perelement(level,resptype,thrsh,noisestd,pulserate,pulsewidth,Fs)%% [prperpulse, stdperpulse, isiprs, Pinf]=pulsetrain_perelement(level,resptype,thrsh,noisestd,pulserate,pulsewidth,Fs)% For Vrefr relative to Vthrabsref = 0.7e-3; % Absolute refractory period in secondsif pulserate>1/absref error(['this model is not appropriate for pulserates above ' num2str(round(1/absref)) ' pulses/s'])endrelref = 20e-3; % Relative refractory period in secondsmagn = 0.97; % Relative magnitude of refactory functiontconst = 1.32e-3; % Time-constant of refactory function in secondsy0 = 1; % Asymptotic relative magnitude of refactory functiondt = 1/Fs; % bin size in secondspulsewidth = pulsewidth*1e-6; % convert from microseconds/phase to seconds/phase% Need to calculate number of bins per pulse, to calculate mean and variance of renewal time% depending on which bin the previous spike was in, i.e., the 'starting' binstarts=1:round(pulsewidth*Fs);% Number of starting binsstlst = length(starts);% Initialize 3D refractory function matrixr = ones(round(relref/dt),1,stlst);% Calculate refractory function for each starting binfor lp=1:stlst r(1:round(absref/dt)-1+starts(lp),1,starts(lp))=Inf; r(round(absref/dt)+starts(lp):round(relref/dt),1,starts(lp))=y0+magn*exp(-([round(absref/dt)+starts(lp):round(relref/dt)]-(round(absref/dt)+starts(lp)-1))/tconst*dt); % exp rend% Calculate number of bins per stimulus periodbins = round(1/pulserate/dt);% Pad out refractory function to integer multiple of the stimulus periodrtmp = cat(1,r,ones(bins*round(length(r)/bins+1)-length(r),1,stlst));rlen = size(rtmp,1);% Reshape refractory function matrix so that:% 1st dimension is the bin number within a stimulus cycle (from the start of one pulse to the start of the next),% 2nd dimension is the stimulus cycle, and% 3rd dimension is the starting bin.rftemp = reshape(rtmp,bins,rlen/bins,stlst);% Get refractory function for bins that fall within a pulse from the 2nd pulse onwards% (the 'previous' spike has occurred in the 1st pulse)rf = rftemp(1:round(pulsewidth*Fs),2:rlen/bins,starts);dims = size(rf);% Number of pulses, excluding the 1st pulse where the 'previous' spike has occurredplss = dims(2);% Initialize matricesf = zeros(plss,1,stlst);p = zeros(dims);stim = ones(dims);% Put model parameters into a single structureproperties.resptype = resptype;properties.thrsh = thrsh;properties.noisestd = noisestd;% Calculate asymptotic discharge probability using single-pulse modelPinf = singlepulse(level,properties);% Create matrix of stimulus levellevels=stim.*level;% Create matrix of refractory-modified thresholdproperties.thrsh = thrsh.*rf;% Calculate discharge probabilities using single-pulse modelp = singlepulse(levels,properties);% Get discharge probability for each pulseP = p(dims(1),:,:);% Transpose the 3D matrixP = permute(P,[2 1 3]);q = 1-P;Q = cumprod(q); % See Lemma 7.3.2 of [2]f(1,1,:) = P(1,1,:); % Eqn. (7.7) of [2]f(2:plss,1,:) = P(2:plss,1,:).*Q(1:plss-1,1,:); % Eqn. (7.7) of [2]% Calculate pulse numbersks=repmat([1:plss]',[1 1 stlst]);if Pinf==0 % Handle case where asymptotic discharge probability is zero tmean = Inf; disrate = 0; tvar = 0; ratestd = 0; isipr = zeros(size(f));else tmean = sum(ks.*f)+Q(end,1,:).*(plss+1./Pinf); % Eqn. (7.9) of [2] disrate = 1./tmean; % Eqn. (7.17) of [2] tvar = sum(ks.^2.*f)+Q(end,1,:).*(-2*(plss+1)-3./Pinf+1+(plss+1)^2+2*(plss+1)./Pinf+2./Pinf.^2)-tmean.^2; % Eqn. (7.10) of [2] ratestd = sqrt(tvar./(tmean).^3); % Eqn. (7.18) of [2] isipr = f;end% Calculate matrix B using Eqn. (7.11) of [2]X=diff(cat(1,zeros(1,plss,stlst),p)); % Eqn. (7.12) of [2]Y=permute(repmat(cat(1,ones(1,1,stlst),Q(1:plss-1,:,:)),[1 dims(1) 1]),[2 1 3]);Z=Q(end,1,:);AA=cat(1, ones(1,1,stlst), zeros(dims(1)-1,1,stlst));Barray = sum((X.*Y),2)+arraydotprod(AA,Z);% Reduce to 2D matrixB = squeeze(Barray);[v, d] = eig(B); % Find eigenvectors and eigenvalues[i, j] = find(round(d)==1); % Find which eigenvector has eigenvalue 1b = v(:,j)/sum(v(:,j)); % Normalize eigenvector% Turn vectors into column vectorsdisrate = disrate(:);ratestd = ratestd(:);prperpulse = sum(disrate.*b); % Eqn. (7.15) of [2]stdperpulse = sqrt(sum(ratestd.^2.*b)); % Eqn. (7.16) of [2]isiprs = squeeze(isipr)*b; % Eqn. (7.19) of [2]function Y=arraydotprod(A,B);if ndims(A)~=3 Y=[]; disp('??? Error using ==> arraydotprod') disp('First input must be 3-D array')elseif ndims(A)~=3 Y=[]; disp('??? Error using ==> arraydotprod') disp('Second input must be 3-D array')elseif size(A,2)~=size(B,1) Y=[]; disp('??? Error using ==> arraydotprod') disp('Inner matrix dimensions must agree.')elseif size(A,3)~=size(B,3) Y=[]; disp('??? Error using ==> arraydotprod') disp('3rd dimensions must agree.')elseif size(B,2)~=1 Y=[]; disp('??? Error using ==> arraydotprod') disp('Second input must have singleton 2nd dimension.')else Y=sum(A.*repmat(permute(B,[2 1 3]),[size(A,1) 1 1]),2);end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -