function [Alpha, AlphaApprox, TauKappa, Beta, Kappa, TauJ] = Parameterize(RelativeSpread, Chronaxie, TauSum, Threshold, Jitter, KnownInput)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameterize.m
% Joshua Goldwyn
% 5/10/11
%
% This function parameterizes the AN model presented in
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Values used in simulations
%[Alpha, AlphaApprox, TauKappa, Beta, Kappa, TauJ] = Parameterize(.0487, 276, 250, .852, 85.5,[0 0 0 0 0]);
%[Alpha, AlphaApprox, TauKappa, Beta, TauJ] = [25.6337 24.5196 325.3700 0.3330 9.3649 96.9336]
%%%
% Some needed variables
dt = 1; % mu sec, for evaluating integrals and filters
MaxPhaseDur = 2000; % Used in Chronaxie mu sec
% Pulses for Summation Experiment (Cartee et al 2006)
SummationPhaseDur = 50;
SummationPulseShape = 'pseudo';
IPIall = [100 200 300];
% Pulses for Threshold Experiment (Miller et al 2001 biphasic experiments)
ThresholdPhaseDur = 40;
ThresholdPulseShape = 'bi';
% Pulses for Jitter Experiment (Miller et al 2001 biphasic experiments)
JitterPhaseDur = 40;
JitterPulseShape = 'bi';
% Approximation of Alpha vs RS
AlphaApproximation = @(rs) rs.^(-1.0587);
% %%%% NOTE THIS CODE GIVES THE APPROXIMATION:
% RSfunc = @(a) sqrt(gamma(1+2./a)./(gamma(1+1./a)).^2 - 1);
% Alpha = linspace(1,100,1E3);
% p = fminsearch(@(p) norm(RSfunc(Alpha).^p-Alpha),-1);
% %%%%%%%%%%%%%%%%
if KnownInput(1)>0
Alpha = KnownInput(1);
else
%%% First Compute Alpha for given RS
% RS as a function of alpha using, using st dev / mean of Weibull distribution
RSfunc = @(a) sqrt(gamma(1+2./a)./(gamma(1+1./a)).^2 - 1);
Alpha = fminsearch(@(a) norm(RSfunc(a) - RelativeSpread), 10);
end
AlphaApprox = AlphaApproximation(RelativeSpread);
if KnownInput(2)>0
TauKappa = KnownInput(2);
else
%%% Next Compute TauKappa for given Chronaxie
% Maximum Phase Duration Used in Van den Honert and Stypulkowski 1984
TauKappa = fminsearch(@(tk) ChronaxieFit(tk, Chronaxie, MaxPhaseDur, AlphaApprox, dt), 100);
end
if KnownInput(3)>0
Beta = KnownInput(3);
else
%%% Next Compute Beta for given Summation Time Constant
Beta = fminbnd(@(b) SummationFit(b, TauSum, SummationPhaseDur, AlphaApprox, TauKappa, dt, SummationPulseShape, IPIall),0,1);
end
if KnownInput(4)>0
Kappa = KnownInput(4);
else
%%% Next Compute Kappa for given Threshold
tend = 5000;
t = 0:dt:tend;
D = ThresholdPhaseDur; %phase duration
switch ThresholdPulseShape
case 'bi'
w = zeros(1,length(t)); w(1:D/dt) = 1; w(D/dt+1:2*D/dt)=-Beta; %biphasic
end
wFold = 0;
wold = 0;
for i=1:length(t)
wFilter(i) = wFold*exp(-dt/TauKappa)+(dt / (2*TauKappa))*(wold*exp(-dt/TauKappa)+w(i));%conv(1/TauKappa * exp(-t/TauKappa), w)*dt;
wFold = wFilter(i);
wold = w(i);
end
W = wFilter(1:length(t)).*(wFilter(1:length(t))>0); % output of stimulus filter, no kappa
intW = trapz(W.^AlphaApprox)*dt; % integrate response
Kappa = (log(2)/intW).^(1/AlphaApprox)./ Threshold;
end
if KnownInput(5)>0
TauJ = KnownInput(5);
else
%%% Last, compute TauJ for Jitter Filter
TauJ = fminsearch(@(tj) JitterFit(Jitter, tj, JitterPhaseDur, TauKappa, Beta, AlphaApprox, Kappa, Threshold,dt), 100);
end
end
function [CAerror] = ChronaxieFit(TauKappa, Chronaxie, MaxPhaseDur, Alpha, dt)
% TauKappa will be fit based on this function
% Total time to evaluate FE
tend = 5000;
% Phase durations
D0 = Chronaxie/dt;
Dmax = MaxPhaseDur/dt;
t = 0:dt:tend;
% waveform functions, always monophasic
w1 = zeros(1,length(t)); w1(1:D0/dt) = 1;
w2 = zeros(1,length(t)); w2(1:Dmax/dt) = 1;
% Apply K filter
w1Filter = conv(1/TauKappa * exp(-t/TauKappa), w1)*dt;
w2Filter = conv(1/TauKappa * exp(-t/TauKappa), w2)*dt;
W1 = w1Filter(1:length(t)).*(w1Filter(1:length(t))>0); % output of stimulus filter, no kappa because cancels out later
W2 = w2Filter(1:length(t)).*(w2Filter(1:length(t))>0); % output of stimulus filter, no kappa because cancels out later
% Apply nonlinearity and Integrate Responses
intW1 = trapz(W1.^Alpha)*dt;
intW2 = trapz(W2.^Alpha)*dt;
% Error function that can be used to determine TauKappa
CAerror = norm(2^Alpha - (intW2/intW1));
end
function [SumError] = SummationFit(Beta, TauSum, PhaseDur, Alpha, TauKappa, dt, StimulusType, IPIall)
% Total time to evaluate FE
tend = 5000;
% Pulse Tain Parameters
D = PhaseDur;
% t
t = 0:dt:tend;
for i=1:length(IPIall)
IPI = IPIall(i);
% PseudoMonophasic
switch StimulusType
case 'pseudo'
tau = 5E6; % Cartee time constant defined by hardware
w1 = zeros(1,length(t)); w1(1:D/dt) = 1;
tt = t(D/dt+1:IPI/dt) - D;
w1(D/dt+1:IPI/dt)= w1(D/dt+1:IPI/dt) -Beta * D * exp(-(tt-D)/tau) / (tau*(1-exp(-(IPI-D)/tau)));
w2= w1; w2(IPI/dt+1:IPI/dt+D/dt) = w2(IPI/dt+1:IPI/dt+D/dt)+1; % 2nd pulse
w2((IPI+D)/dt+1:(2*IPI)/dt)= w2((IPI+D)/dt+1:(2*IPI)/dt) - Beta*D*exp(-(tt-D)/tau) / (tau*(1-exp(-(IPI-D)/tau)));
case 'bi' % Biphasic
w1 = zeros(1,length(t)); w1(1:D/dt) = 1;
w1(D/dt+1:(2*D)/dt)= w1(D/dt+1:(2*D)/dt) - Beta;
w2= w1; w2(IPI/dt+1:IPI/dt+D/dt) = w2(IPI/dt+1:IPI/dt+D/dt)+1; % 2nd pulse
w2((IPI+D)/dt+1:(IPI+2*D)/dt) = w2((IPI+D)/dt+1:(IPI+2*D)/dt)-Beta; % 2nd pulse
end
% Apply K filter
w1Filter = conv(1/TauKappa * exp(-t/TauKappa), w1)*dt;
w2Filter = conv(1/TauKappa * exp(-t/TauKappa), w2)*dt;
W1 = w1Filter(1:length(t)).*(w1Filter(1:length(t))>0); % output of stimulus filter, no kappa
W2 = w2Filter(1:length(t)).*(w2Filter(1:length(t))>0); % output of stimulus filter, no kapp
intW1 = trapz(W1.^Alpha)*dt;
intW2 = trapz(W2.^Alpha)*dt;
ThreshRatio(i) = (intW1/intW2)^(1/Alpha);
end
% Error Using Equation in Cartee et al
SumError = norm( (1-.5*exp(-IPIall/TauSum)) - ThreshRatio);
end
function [JitterError] = JitterFit(jit, tauj, PhaseDur, TauKappaFit, BetaFit, AlphaFit, KappaFit, ThreshVal,dt)
tend = 5000;
t = 0:dt:tend;
D = PhaseDur; %phase duration
w = zeros(1,length(t)); w(1:D/dt) = 1; w(D/dt+1:2*D/dt)=-BetaFit; %biphasic
wFilter = conv(1/TauKappaFit * exp(-t/TauKappaFit), w)*dt;
W = wFilter(1:length(t)).*(wFilter(1:length(t))>0); % output of stimulus filter, no kappa
JWFilter = conv(1/tauj* exp(-t/tauj), W.^AlphaFit)*dt;
JW = JWFilter(1:length(t)).*(JWFilter(1:length(t))>0);
lambda = (KappaFit*ThreshVal)^AlphaFit * JW;
Lambda = cumtrapz(lambda)*dt;
f = 2*lambda.*exp(-Lambda);
jj = sqrt(trapz(t.^2.*f) - trapz(t.*f).^2 );
JitterError = norm(jj -jit);
end