function [K] = ku0u0(x, y, xp, yp, hyp, ubar, vbar, ubarp, vbarp, dt, i)

logsigma = hyp(1);
logthetax = hyp(2);
logthetay = hyp(3);

a1 = hyp(4);
a2 = hyp(5);

logsigmap = hyp(6);
logthetaxp = hyp(7);
logthetayp = hyp(8);

n_x = size(x,1);
n_y = size(y,1);
n_xp = size(xp,1);
n_yp = size(yp,1);

x = repmat(x,1,n_xp);
y = repmat(y,1,n_yp);
xp = repmat(xp',n_x,1);
yp = repmat(yp',n_y,1);

ubar = repmat(ubar,1,n_xp);
vbar = repmat(vbar,1,n_yp);
ubarp = repmat(ubarp',n_x,1);
vbarp = repmat(vbarp',n_y,1);

switch i

case 0

K=dt.^2.*exp(1).^(logsigmap+(-2).*logthetaxp+(-1/2).*exp(1).^((-1).* ...
  logthetaxp).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetayp).*(y+(-1) ...
  .*yp).^2).*(exp(1).^logthetaxp+(-1).*(x+(-1).*xp).^2)+a1.*dt.*exp(1).^( ...
  logsigma+(-5).*logthetay+(-1/2).*exp(1).^((-1).*logthetax).*(x+(-1).*xp) ...
  .^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2).*(exp(1).^((-2) ...
  .*logthetax+logthetay).*ubar.*((-1).*exp(1).^logthetax.*(x+(-1).*xp).*( ...
  exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).* ...
  yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).* ...
  logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+ ...
  3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1) ...
  .^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+a1.*dt.*exp(1).^( ...
  logthetax+2.*logthetay).*ubarp.*(exp(1).^logthetay+(-1).*(y+(-1).*yp) ...
  .^2)+(-2).*dt.*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2))+vbar.*(exp(1).^logthetay.*(a1.*dt.* ...
  exp(1).^((-1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+logthetay).* ...
  vbarp+(-2).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^(2.*logthetay) ...
  .*(y+(-1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).*exp(1).^(2.* ...
  logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+exp(1).^(2.* ...
  logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+(-1).*yp).^2) ...
  .*(y+(-1).*yp))+(-1).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).* ...
  (y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^( ...
  2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(y+ ...
  (-1).*yp)))+exp(1).^(logsigma+(-4).*logthetay+(-1/2).*exp(1).^((-1).* ...
  logthetax).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).* ...
  yp).^2).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp) ...
  .^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.* ...
  logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+(-1) ...
  .*dt.*exp(1).^(a2+logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).* ...
  logthetax).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).* ...
  yp).^2).*((-2).*exp(1).^((-2).*logthetax+2.*logthetay).*(exp(1).^(2.*( ...
  logthetax+logthetay))+dt.*(6.*exp(1).^(a2+2.*logthetax+logthetay)+exp(1) ...
  .^(a2+logthetax+2.*logthetay)+a1.*exp(1).^(logthetax+2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+(-1).*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).^2+3.* ...
  a1.*exp(1).^(2.*logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-6).*exp(1) ...
  .^(a2+2.*logthetax).*(y+(-1).*yp).^2))+exp(1).^((-2).*logthetax+2.* ...
  logthetay).*((-1).*exp(1).^logthetax+(x+(-1).*xp).^2).*(exp(1).^(2.* ...
  logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^(( ...
  -1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+ ...
  3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*( ...
  3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+( ...
  -1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.* ...
  logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+(-2).*dt.*exp(1) ...
  .^(a2+(-2).*logthetax+4.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).* ...
  yp).^2)+(-2).*dt.*exp(1).^((-3).*logthetax+4.*logthetay).*(a1.*exp(1) ...
  .^logthetax.*ubarp+(-2).*exp(1).^a2.*(x+(-1).*xp)).*(x+(-1).*xp).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2)+(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4)).*((-1).*exp(1).^logthetay+(y+(-1).*yp).^2) ...
  +(-2).*exp(1).^logthetay.*(a1.*dt.*exp(1).^((-1).*logthetax+logthetay).* ...
  (3.*exp(1).^(logthetax+logthetay).*vbarp+(-2).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+( ...
  -1).*yp).^2)+(-2).*exp(1).^(2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^( ...
  a2+(-2).*logthetax).*((-6).*exp(1).^(2.*logthetax+logthetay)+(-1).*exp( ...
  1).^(logthetax+2.*logthetay)+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.* ...
  exp(1).^(2.*logthetax).*(y+(-1).*yp).^2).*(y+(-1).*yp)).*(y+(-1).*yp)); ...

case 1 % logsigma

K=exp(1).^(logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).*logthetax).*(x+ ...
  (-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2).*(a1.* ...
  dt.*exp(1).^logthetay.*(exp(1).^((-2).*logthetax+logthetay).*ubar.*((-1) ...
  .*exp(1).^logthetax.*(x+(-1).*xp).*(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4))+a1.*dt.*exp(1).^(logthetax+2.*logthetay).* ...
  ubarp.*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-2).*dt.*exp(1).^(a2+ ...
  2.*logthetay).*(x+(-1).*xp).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2))+ ...
  vbar.*(exp(1).^logthetay.*(a1.*dt.*exp(1).^((-1).*logthetax+logthetay).* ...
  (3.*exp(1).^(logthetax+logthetay).*vbarp+(-2).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+( ...
  -1).*yp).^2)+(-2).*exp(1).^(2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^( ...
  a2+(-2).*logthetax).*((-6).*exp(1).^(2.*logthetax+logthetay)+(-1).*exp( ...
  1).^(logthetax+2.*logthetay)+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.* ...
  exp(1).^(2.*logthetax).*(y+(-1).*yp).^2).*(y+(-1).*yp))+(-1).*(exp(1).^( ...
  2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1) ...
  .^((-1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).* ...
  xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*( ...
  3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+( ...
  -1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.* ...
  logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(y+(-1).*yp)))+ ...
  exp(1).^(2.*logthetay).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1) ...
  .*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1) ...
  .^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+(-1) ...
  .*dt.*exp(1).^a2.*((-2).*exp(1).^((-2).*logthetax+2.*logthetay).*(exp(1) ...
  .^(2.*(logthetax+logthetay))+dt.*(6.*exp(1).^(a2+2.*logthetax+logthetay) ...
  +exp(1).^(a2+logthetax+2.*logthetay)+a1.*exp(1).^(logthetax+2.* ...
  logthetay).*ubarp.*(x+(-1).*xp)+(-1).*exp(1).^(a2+2.*logthetay).*(x+(-1) ...
  .*xp).^2+3.*a1.*exp(1).^(2.*logthetax+logthetay).*vbarp.*(y+(-1).*yp)+( ...
  -6).*exp(1).^(a2+2.*logthetax).*(y+(-1).*yp).^2))+exp(1).^((-2).* ...
  logthetax+2.*logthetay).*((-1).*exp(1).^logthetax+(x+(-1).*xp).^2).*( ...
  exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).* ...
  yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).* ...
  logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+ ...
  3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1) ...
  .^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+(-2).*dt.*exp(1) ...
  .^(a2+(-2).*logthetax+4.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).* ...
  yp).^2)+(-2).*dt.*exp(1).^((-3).*logthetax+4.*logthetay).*(a1.*exp(1) ...
  .^logthetax.*ubarp+(-2).*exp(1).^a2.*(x+(-1).*xp)).*(x+(-1).*xp).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2)+(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4)).*((-1).*exp(1).^logthetay+(y+(-1).*yp).^2) ...
  +(-2).*exp(1).^logthetay.*(a1.*dt.*exp(1).^((-1).*logthetax+logthetay).* ...
  (3.*exp(1).^(logthetax+logthetay).*vbarp+(-2).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+( ...
  -1).*yp).^2)+(-2).*exp(1).^(2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^( ...
  a2+(-2).*logthetax).*((-6).*exp(1).^(2.*logthetax+logthetay)+(-1).*exp( ...
  1).^(logthetax+2.*logthetay)+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.* ...
  exp(1).^(2.*logthetax).*(y+(-1).*yp).^2).*(y+(-1).*yp)).*(y+(-1).*yp))); ...

case 2 % logthetax

K=(1/2).*exp(1).^(logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).* ...
  logthetax).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).* ...
  yp).^2).*(a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(x+(-1).*xp).^2.* ...
  (exp(1).^((-2).*logthetax+logthetay).*ubar.*((-1).*exp(1).^logthetax.*( ...
  x+(-1).*xp).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).* ...
  yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.* ...
  logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+a1.* ...
  dt.*exp(1).^(logthetax+2.*logthetay).*ubarp.*(exp(1).^logthetay+(-1).*( ...
  y+(-1).*yp).^2)+(-2).*dt.*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2))+vbar.*(exp(1).^logthetay.*(a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+ ...
  logthetay).*vbarp+(-2).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1) ...
  .*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^( ...
  2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).* ...
  exp(1).^(2.*logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+( ...
  -1).*yp).^2).*(y+(-1).*yp))+(-1).*(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4)).*(y+(-1).*yp)))+exp(1).^((-1).*logthetax+ ...
  2.*logthetay).*(x+(-1).*xp).^2.*(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4))+(-2).*a1.*dt.*exp(1).^((-3).*logthetax+2.* ...
  logthetay).*((-1).*exp(1).^(2.*(logthetax+logthetay)).*ubar.*(x+(-1).* ...
  xp).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^( ...
  logthetax+logthetay).*(exp(1).^(logthetax+2.*logthetay).*ubar.*ubarp+( ...
  -2).*exp(1).^(2.*logthetay).*ubar.*ubarp.*(x+(-1).*xp).^2+(-1).*exp(1) ...
  .^(logthetax+logthetay).*(3.*ubar.*vbarp.*(x+(-1).*xp)+ubarp.*(3.*vbar.* ...
  (x+(-1).*xp)+ubar.*(y+(-1).*yp))).*(y+(-1).*yp)+2.*exp(1).^logthetay.* ...
  ubar.*ubarp.*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^logthetax.*( ...
  ubarp.*vbar+ubar.*vbarp).*(x+(-1).*xp).*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^a2.*((-6).*exp(1).^(logthetax+3.*logthetay).*ubar.*(x+(-1).*xp)+3.* ...
  exp(1).^(3.*logthetay).*ubar.*(x+(-1).*xp).^3+(-3).*exp(1).^(2.*( ...
  logthetax+logthetay)).*(ubar.*(x+(-1).*xp)+vbar.*(y+(-1).*yp))+6.*exp(1) ...
  .^(logthetax+2.*logthetay).*(x+(-1).*xp).*(vbar.*(x+(-1).*xp)+ubar.*(y+( ...
  -1).*yp)).*(y+(-1).*yp)+(-3).*exp(1).^(2.*logthetay).*ubar.*(x+(-1).*xp) ...
  .^3.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax+logthetay).*(6.*ubar.*(x+(-1) ...
  .*xp)+vbar.*(y+(-1).*yp)).*(y+(-1).*yp).^2+(-2).*exp(1).^(logthetax+ ...
  logthetay).*vbar.*(x+(-1).*xp).^2.*(y+(-1).*yp).^3+(-1).*exp(1).^(2.* ...
  logthetax).*ubar.*(x+(-1).*xp).*(y+(-1).*yp).^4))+(-2).*dt.*exp(1).^(a2+ ...
  (-4).*logthetax+2.*logthetay).*(exp(1).^(2.*(logthetax+logthetay)).*( ...
  exp(1).^logthetax+(-2).*(x+(-1).*xp).^2).*(exp(1).^logthetay+(-1).*(y+( ...
  -1).*yp).^2)+dt.*(6.*exp(1).^(a2+3.*logthetax+2.*logthetay)+6.*exp(1).^( ...
  a2+2.*logthetax+3.*logthetay)+6.*a1.*exp(1).^(2.*logthetax+3.*logthetay) ...
  .*ubarp.*(x+(-1).*xp)+(-18).*exp(1).^(a2+logthetax+3.*logthetay).*(x+( ...
  -1).*xp).^2+(-3).*a1.*exp(1).^(logthetax+3.*logthetay).*ubarp.*(x+(-1).* ...
  xp).^3+4.*exp(1).^(a2+3.*logthetay).*(x+(-1).*xp).^4+3.*a1.*exp(1).^(3.* ...
  logthetax+2.*logthetay).*(ubarp.*(x+(-1).*xp)+vbarp.*(y+(-1).*yp))+(-6) ...
  .*exp(1).^(a2+2.*(logthetax+logthetay)).*(2.*x.^2+(-4).*x.*xp+2.*xp.^2+( ...
  y+(-1).*yp).^2)+(-6).*a1.*exp(1).^(2.*(logthetax+logthetay)).*(x+(-1).* ...
  xp).*(vbarp.*(x+(-1).*xp)+ubarp.*(y+(-1).*yp)).*(y+(-1).*yp)+(-12).*exp( ...
  1).^(a2+3.*logthetax+logthetay).*(y+(-1).*yp).^2+24.*exp(1).^(a2+2.* ...
  logthetax+logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+18.*exp(1).^(a2+ ...
  logthetax+2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+3.*a1.*exp(1) ...
  .^(logthetax+2.*logthetay).*ubarp.*(x+(-1).*xp).^3.*(y+(-1).*yp).^2+(-4) ...
  .*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).^4.*(y+(-1).*yp).^2+(-1).*a1.* ...
  exp(1).^(3.*logthetax+logthetay).*(6.*ubarp.*(x+(-1).*xp)+vbarp.*(y+(-1) ...
  .*yp)).*(y+(-1).*yp).^2+2.*a1.*exp(1).^(2.*logthetax+logthetay).*vbarp.* ...
  (x+(-1).*xp).^2.*(y+(-1).*yp).^3+2.*exp(1).^(a2+3.*logthetax).*(y+(-1).* ...
  yp).^4+a1.*exp(1).^(3.*logthetax).*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^4+ ...
  (-4).*exp(1).^(a2+2.*logthetax).*(x+(-1).*xp).^2.*(y+(-1).*yp).^4))+(-1) ...
  .*dt.*exp(1).^(a2+(-1).*logthetax).*(x+(-1).*xp).^2.*((-2).*exp(1).^(( ...
  -2).*logthetax+2.*logthetay).*(exp(1).^(2.*(logthetax+logthetay))+dt.*( ...
  6.*exp(1).^(a2+2.*logthetax+logthetay)+exp(1).^(a2+logthetax+2.* ...
  logthetay)+a1.*exp(1).^(logthetax+2.*logthetay).*ubarp.*(x+(-1).*xp)+( ...
  -1).*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).^2+3.*a1.*exp(1).^(2.* ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-6).*exp(1).^(a2+2.* ...
  logthetax).*(y+(-1).*yp).^2))+exp(1).^((-2).*logthetax+2.*logthetay).*(( ...
  -1).*exp(1).^logthetax+(x+(-1).*xp).^2).*(exp(1).^(2.*logthetay).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4))+(-2).*dt.*exp(1).^(a2+(-2).*logthetax+4.* ...
  logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-2).*dt.*exp(1) ...
  .^((-3).*logthetax+4.*logthetay).*(a1.*exp(1).^logthetax.*ubarp+(-2).* ...
  exp(1).^a2.*(x+(-1).*xp)).*(x+(-1).*xp).*(exp(1).^logthetay+(-1).*(y+( ...
  -1).*yp).^2)+(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).* ...
  yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.* ...
  logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(( ...
  -1).*exp(1).^logthetay+(y+(-1).*yp).^2)+(-2).*exp(1).^logthetay.*(a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+ ...
  logthetay).*vbarp+(-2).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1) ...
  .*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^( ...
  2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).* ...
  exp(1).^(2.*logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+( ...
  -1).*yp).^2).*(y+(-1).*yp)).*(y+(-1).*yp))+(-2).*dt.*exp(1).^((-2).* ...
  logthetax+4.*logthetay).*(exp(1).^(a2+logthetax)+a1.*exp(1).^logthetax.* ...
  ubarp.*(x+(-1).*xp)+(-2).*exp(1).^a2.*(x+(-1).*xp).^2).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2));

case 3 % logthetay

K=exp(1).^(logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).*logthetax).*(x+ ...
  (-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2).*(exp( ...
  1).^((-2).*logthetax+3.*logthetay).*(exp(1).^(2.*logthetax+logthetay).*( ...
  3.*exp(1).^logthetay+(-2).*(y+(-1).*yp).^2)+dt.*(6.*exp(1).^(a2+2.* ...
  logthetax+logthetay)+3.*exp(1).^(a2+logthetax+2.*logthetay)+3.*a1.*exp( ...
  1).^(logthetax+2.*logthetay).*ubarp.*(x+(-1).*xp)+(-3).*exp(1).^(a2+2.* ...
  logthetay).*(x+(-1).*xp).^2+6.*a1.*exp(1).^(2.*logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-6).*exp(1).^(a2+2.*logthetax).*(y+(-1).*yp).^2+( ...
  -2).*exp(1).^(a2+logthetax+logthetay).*(y+(-1).*yp).^2+(-2).*a1.*exp(1) ...
  .^(logthetax+logthetay).*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+2.*exp(1) ...
  .^(a2+logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+(-1).*a1.*exp(1).^( ...
  2.*logthetax).*vbarp.*(y+(-1).*yp).^3))+a1.*dt.*exp(1).^((-3).* ...
  logthetax+2.*logthetay).*(exp(1).^(2.*logthetax+logthetay).*((-4).*exp( ...
  1).^(2.*logthetay).*ubar.*(x+(-1).*xp)+(-9).*exp(1).^(logthetax+ ...
  logthetay).*vbar.*(y+(-1).*yp)+3.*exp(1).^logthetay.*ubar.*(x+(-1).*xp) ...
  .*(y+(-1).*yp).^2+2.*exp(1).^logthetax.*vbar.*(y+(-1).*yp).^3)+a1.*dt.* ...
  exp(1).^logthetax.*(4.*exp(1).^(logthetax+3.*logthetay).*ubar.*ubarp+9.* ...
  exp(1).^(2.*(logthetax+logthetay)).*vbar.*vbarp+(-4).*exp(1).^(3.* ...
  logthetay).*ubar.*ubarp.*(x+(-1).*xp).^2+(-3).*exp(1).^(logthetax+2.* ...
  logthetay).*(3.*ubar.*vbarp.*(x+(-1).*xp)+ubarp.*(3.*vbar.*(x+(-1).*xp)+ ...
  ubar.*(y+(-1).*yp))).*(y+(-1).*yp)+(-12).*exp(1).^(2.*logthetax+ ...
  logthetay).*vbar.*vbarp.*(y+(-1).*yp).^2+3.*exp(1).^(2.*logthetay).* ...
  ubar.*ubarp.*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+2.*exp(1).^(logthetax+ ...
  logthetay).*(ubarp.*vbar+ubar.*vbarp).*(x+(-1).*xp).*(y+(-1).*yp).^3+ ...
  exp(1).^(2.*logthetax).*vbar.*vbarp.*(y+(-1).*yp).^4)+dt.*exp(1).^a2.*(( ...
  -12).*exp(1).^(logthetax+3.*logthetay).*ubar.*(x+(-1).*xp)+4.*exp(1).^( ...
  3.*logthetay).*ubar.*(x+(-1).*xp).^3+(-9).*exp(1).^(2.*(logthetax+ ...
  logthetay)).*(ubar.*(x+(-1).*xp)+vbar.*(y+(-1).*yp))+(-30).*exp(1).^(3.* ...
  logthetax+logthetay).*vbar.*(y+(-1).*yp)+9.*exp(1).^(logthetax+2.* ...
  logthetay).*(x+(-1).*xp).*(vbar.*(x+(-1).*xp)+ubar.*(y+(-1).*yp)).*(y+( ...
  -1).*yp)+(-3).*exp(1).^(2.*logthetay).*ubar.*(x+(-1).*xp).^3.*(y+(-1).* ...
  yp).^2+2.*exp(1).^(2.*logthetax+logthetay).*(6.*ubar.*(x+(-1).*xp)+ ...
  vbar.*(y+(-1).*yp)).*(y+(-1).*yp).^2+10.*exp(1).^(3.*logthetax).*vbar.*( ...
  y+(-1).*yp).^3+(-2).*exp(1).^(logthetax+logthetay).*vbar.*(x+(-1).*xp) ...
  .^2.*(y+(-1).*yp).^3+(-1).*exp(1).^(2.*logthetax).*ubar.*(x+(-1).*xp).*( ...
  y+(-1).*yp).^4))+dt.*exp(1).^(a2+(-4).*logthetax+logthetay).*(exp(1).^( ...
  2.*logthetax+logthetay).*(12.*exp(1).^(2.*(logthetax+logthetay))+5.*exp( ...
  1).^(logthetax+3.*logthetay)+(-5).*exp(1).^(3.*logthetay).*(x+(-1).*xp) ...
  .^2+(-18).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-4).*exp( ...
  1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+4.*exp(1).^(2.*logthetay) ...
  .*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+2.*exp(1).^(2.*logthetax).*(y+(-1).* ...
  yp).^4)+dt.*(45.*exp(1).^(a2+4.*logthetax+2.*logthetay)+15.*exp(1).^(a2+ ...
  2.*logthetax+4.*logthetay)+24.*exp(1).^(a2+3.*(logthetax+logthetay))+ ...
  15.*a1.*exp(1).^(2.*logthetax+4.*logthetay).*ubarp.*(x+(-1).*xp)+(-30).* ...
  exp(1).^(a2+logthetax+4.*logthetay).*(x+(-1).*xp).^2+(-5).*a1.*exp(1).^( ...
  logthetax+4.*logthetay).*ubarp.*(x+(-1).*xp).^3+5.*exp(1).^(a2+4.* ...
  logthetay).*(x+(-1).*xp).^4+12.*a1.*exp(1).^(3.*(logthetax+logthetay)).* ...
  (ubarp.*(x+(-1).*xp)+vbarp.*(y+(-1).*yp))+(-12).*exp(1).^(a2+2.* ...
  logthetax+3.*logthetay).*(2.*x.^2+(-4).*x.*xp+2.*xp.^2+(y+(-1).*yp).^2)+ ...
  45.*a1.*exp(1).^(4.*logthetax+2.*logthetay).*vbarp.*(y+(-1).*yp)+(-12).* ...
  a1.*exp(1).^(2.*logthetax+3.*logthetay).*(x+(-1).*xp).*(vbarp.*(x+(-1).* ...
  xp)+ubarp.*(y+(-1).*yp)).*(y+(-1).*yp)+(-90).*exp(1).^(a2+4.*logthetax+ ...
  logthetay).*(y+(-1).*yp).^2+(-36).*exp(1).^(a2+3.*logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+24.*exp(1).^(a2+logthetax+3.*logthetay).*(x+ ...
  (-1).*xp).^2.*(y+(-1).*yp).^2+36.*exp(1).^(a2+2.*(logthetax+logthetay)) ...
  .*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+4.*a1.*exp(1).^(logthetax+3.* ...
  logthetay).*ubarp.*(x+(-1).*xp).^3.*(y+(-1).*yp).^2+(-4).*exp(1).^(a2+ ...
  3.*logthetay).*(x+(-1).*xp).^4.*(y+(-1).*yp).^2+(-3).*a1.*exp(1).^(3.* ...
  logthetax+2.*logthetay).*(6.*ubarp.*(x+(-1).*xp)+vbarp.*(y+(-1).*yp)).*( ...
  y+(-1).*yp).^2+(-20).*a1.*exp(1).^(4.*logthetax+logthetay).*vbarp.*(y+( ...
  -1).*yp).^3+3.*a1.*exp(1).^(2.*(logthetax+logthetay)).*vbarp.*(x+(-1).* ...
  xp).^2.*(y+(-1).*yp).^3+15.*exp(1).^(a2+4.*logthetax).*(y+(-1).*yp).^4+ ...
  4.*exp(1).^(a2+3.*logthetax+logthetay).*(y+(-1).*yp).^4+2.*a1.*exp(1).^( ...
  3.*logthetax+logthetay).*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^4+(-4).*exp( ...
  1).^(a2+2.*logthetax+logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^4+a1.* ...
  exp(1).^(4.*logthetax).*vbarp.*(y+(-1).*yp).^5))+(-1).*dt.*exp(1).^a2.*( ...
  (-2).*exp(1).^((-2).*logthetax+2.*logthetay).*(exp(1).^(2.*(logthetax+ ...
  logthetay))+dt.*(6.*exp(1).^(a2+2.*logthetax+logthetay)+exp(1).^(a2+ ...
  logthetax+2.*logthetay)+a1.*exp(1).^(logthetax+2.*logthetay).*ubarp.*(x+ ...
  (-1).*xp)+(-1).*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).^2+3.*a1.*exp(1) ...
  .^(2.*logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-6).*exp(1).^(a2+2.* ...
  logthetax).*(y+(-1).*yp).^2))+exp(1).^((-2).*logthetax+2.*logthetay).*(( ...
  -1).*exp(1).^logthetax+(x+(-1).*xp).^2).*(exp(1).^(2.*logthetay).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4))+(-2).*dt.*exp(1).^(a2+(-2).*logthetax+4.* ...
  logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-2).*dt.*exp(1) ...
  .^((-3).*logthetax+4.*logthetay).*(a1.*exp(1).^logthetax.*ubarp+(-2).* ...
  exp(1).^a2.*(x+(-1).*xp)).*(x+(-1).*xp).*(exp(1).^logthetay+(-1).*(y+( ...
  -1).*yp).^2)+(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).* ...
  yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.* ...
  logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(( ...
  -1).*exp(1).^logthetay+(y+(-1).*yp).^2)+(-2).*exp(1).^logthetay.*(a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+ ...
  logthetay).*vbarp+(-2).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1) ...
  .*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^( ...
  2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).* ...
  exp(1).^(2.*logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+( ...
  -1).*yp).^2).*(y+(-1).*yp)).*(y+(-1).*yp)).*((-6)+(1/2).*exp(1).^((-1).* ...
  logthetay).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^logthetay.*(exp(1).^((-2).* ...
  logthetax+logthetay).*ubar.*((-1).*exp(1).^logthetax.*(x+(-1).*xp).*( ...
  exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.* ...
  dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).* ...
  yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).* ...
  logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+ ...
  3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1) ...
  .^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+a1.*dt.*exp(1).^( ...
  logthetax+2.*logthetay).*ubarp.*(exp(1).^logthetay+(-1).*(y+(-1).*yp) ...
  .^2)+(-2).*dt.*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2))+vbar.*(exp(1).^logthetay.*(a1.*dt.* ...
  exp(1).^((-1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+logthetay).* ...
  vbarp+(-2).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^(2.*logthetay) ...
  .*(y+(-1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).*exp(1).^(2.* ...
  logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+exp(1).^(2.* ...
  logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+(-1).*yp).^2) ...
  .*(y+(-1).*yp))+(-1).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1).* ...
  (y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1).^( ...
  2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(y+ ...
  (-1).*yp))).*((-5)+(1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2)+ ...
  exp(1).^(2.*logthetay).*(exp(1).^(2.*logthetay).*(exp(1).^logthetay+(-1) ...
  .*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+logthetay).*(exp(1) ...
  .^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1) ...
  .^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(( ...
  -4)+(1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2));

case 4 % a1

K=dt.*exp(1).^(logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).*logthetax) ...
  .*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2).*( ...
  exp(1).^logthetay.*(exp(1).^((-2).*logthetax+logthetay).*ubar.*((-1).* ...
  exp(1).^logthetax.*(x+(-1).*xp).*(exp(1).^(2.*logthetay).*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).*logthetax+ ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*(3.*exp(1).^(2.*( ...
  logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^( ...
  3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*( ...
  y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+ ...
  exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4))+a1.*dt.*exp(1).^(logthetax+2.*logthetay).* ...
  ubarp.*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-2).*dt.*exp(1).^(a2+ ...
  2.*logthetay).*(x+(-1).*xp).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2))+ ...
  vbar.*(exp(1).^logthetay.*(a1.*dt.*exp(1).^((-1).*logthetax+logthetay).* ...
  (3.*exp(1).^(logthetax+logthetay).*vbarp+(-2).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1).^logthetax.*vbarp.*(y+( ...
  -1).*yp).^2)+(-2).*exp(1).^(2.*logthetay).*(y+(-1).*yp)+2.*dt.*exp(1).^( ...
  a2+(-2).*logthetax).*((-6).*exp(1).^(2.*logthetax+logthetay)+(-1).*exp( ...
  1).^(logthetax+2.*logthetay)+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+2.* ...
  exp(1).^(2.*logthetax).*(y+(-1).*yp).^2).*(y+(-1).*yp))+(-1).*(exp(1).^( ...
  2.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1) ...
  .^((-1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).* ...
  xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*( ...
  3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+( ...
  -1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.* ...
  logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*(y+(-1).*yp)))+ ...
  a1.*dt.*exp(1).^((-2).*logthetax+2.*logthetay).*(exp(1).^logthetay.* ...
  ubar.*(exp(1).^(logthetax+logthetay).*ubarp.*(exp(1).^logthetay+(-1).*( ...
  y+(-1).*yp).^2)+(-1).*(x+(-1).*xp).*(exp(1).^(2.*logthetay).*ubarp.*(x+( ...
  -1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).* ...
  exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3))+exp(1).^logthetax.*vbar.*(3.*exp( ...
  1).^(logthetax+2.*logthetay).*vbarp+(-3).*exp(1).^(2.*logthetay).* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-6).*exp(1).^(logthetax+logthetay).* ...
  vbarp.*(y+(-1).*yp).^2+exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).* ...
  yp).^3+exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^4))+(-1).*dt.*exp(1).^( ...
  a2+(-3).*logthetax+logthetay).*((-2).*exp(1).^(2.*(logthetax+logthetay)) ...
  .*(exp(1).^logthetay.*ubarp.*(x+(-1).*xp)+3.*exp(1).^logthetax.*vbarp.*( ...
  y+(-1).*yp))+(-2).*exp(1).^(logthetax+3.*logthetay).*ubarp.*(x+(-1).*xp) ...
  .*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+exp(1).^(2.*logthetay).*(( ...
  -1).*exp(1).^logthetax+(x+(-1).*xp).^2).*(exp(1).^(2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).* ...
  yp)+(-1).*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).* ...
  exp(1).^logthetax.*vbarp.*(y+(-1).*yp).^3)+exp(1).^(2.*logthetax).*((-1) ...
  .*exp(1).^logthetay+(y+(-1).*yp).^2).*(exp(1).^(2.*logthetay).*ubarp.*( ...
  x+(-1).*xp)+3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).* ...
  exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+(-2).*exp(1).^(2.*logthetax+ ...
  logthetay).*(3.*exp(1).^(logthetax+logthetay).*vbarp+(-2).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1).^logthetax.* ...
  vbarp.*(y+(-1).*yp).^2).*(y+(-1).*yp))+exp(1).^((-1).*logthetax+3.* ...
  logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.*exp(1).^( ...
  logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1).^logthetay.* ...
  ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1).^logthetax.*vbarp.*(y+ ...
  (-1).*yp).^3));

case 5 % a2

K=dt.*exp(1).^(logsigma+(-6).*logthetay+(-1/2).*exp(1).^((-1).*logthetax) ...
  .*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetay).*(y+(-1).*yp).^2).*( ...
  exp(1).^a2.*(2.*exp(1).^((-2).*logthetax+2.*logthetay).*(exp(1).^(2.*( ...
  logthetax+logthetay))+dt.*(6.*exp(1).^(a2+2.*logthetax+logthetay)+exp(1) ...
  .^(a2+logthetax+2.*logthetay)+a1.*exp(1).^(logthetax+2.*logthetay).* ...
  ubarp.*(x+(-1).*xp)+(-1).*exp(1).^(a2+2.*logthetay).*(x+(-1).*xp).^2+3.* ...
  a1.*exp(1).^(2.*logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-6).*exp(1) ...
  .^(a2+2.*logthetax).*(y+(-1).*yp).^2))+(-1).*exp(1).^((-2).*logthetax+ ...
  2.*logthetay).*((-1).*exp(1).^logthetax+(x+(-1).*xp).^2).*(exp(1).^(2.* ...
  logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^(( ...
  -1).*logthetax+logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+ ...
  3.*exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*( ...
  3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+( ...
  -1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.* ...
  logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+2.*dt.*exp(1).^( ...
  a2+(-2).*logthetax+4.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp) ...
  .^2)+2.*dt.*exp(1).^((-3).*logthetax+4.*logthetay).*(a1.*exp(1) ...
  .^logthetax.*ubarp+(-2).*exp(1).^a2.*(x+(-1).*xp)).*(x+(-1).*xp).*(exp( ...
  1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-1).*(exp(1).^(2.*logthetay).*( ...
  exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+a1.*dt.*exp(1).^((-1).* ...
  logthetax+logthetay).*(exp(1).^(2.*logthetay).*ubarp.*(x+(-1).*xp)+3.* ...
  exp(1).^(logthetax+logthetay).*vbarp.*(y+(-1).*yp)+(-1).*exp(1) ...
  .^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp).^2+(-1).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^3)+dt.*exp(1).^(a2+(-2).*logthetax).*( ...
  3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.*logthetay)+( ...
  -1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.* ...
  logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)).*((-1).*exp(1) ...
  .^logthetay+(y+(-1).*yp).^2)+2.*exp(1).^logthetay.*(a1.*dt.*exp(1).^(( ...
  -1).*logthetax+logthetay).*(3.*exp(1).^(logthetax+logthetay).*vbarp+(-2) ...
  .*exp(1).^logthetay.*ubarp.*(x+(-1).*xp).*(y+(-1).*yp)+(-3).*exp(1) ...
  .^logthetax.*vbarp.*(y+(-1).*yp).^2)+(-2).*exp(1).^(2.*logthetay).*(y+( ...
  -1).*yp)+2.*dt.*exp(1).^(a2+(-2).*logthetax).*((-6).*exp(1).^(2.* ...
  logthetax+logthetay)+(-1).*exp(1).^(logthetax+2.*logthetay)+exp(1).^(2.* ...
  logthetay).*(x+(-1).*xp).^2+2.*exp(1).^(2.*logthetax).*(y+(-1).*yp).^2) ...
  .*(y+(-1).*yp)).*(y+(-1).*yp))+a1.*dt.*exp(1).^(a2+(-2).*logthetax+ ...
  logthetay).*(exp(1).^logthetay.*ubar.*(x+(-1).*xp).*((-2).*exp(1).^(2.* ...
  logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+(-1).*exp(1).^(( ...
  -1).*logthetax).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^( ...
  logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+( ...
  -6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^( ...
  logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1) ...
  .*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4))+ ...
  vbar.*((-15).*exp(1).^(2.*(logthetax+logthetay))+(-3).*exp(1).^( ...
  logthetax+3.*logthetay)+3.*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+10.* ...
  exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(2.*logthetay).*(x+(-1).*xp) ...
  .^2.*(y+(-1).*yp).^2+(-1).*exp(1).^(2.*logthetax).*(y+(-1).*yp).^4).*(y+ ...
  (-1).*yp))+(-1).*dt.*exp(1).^(a2+(-4).*logthetax).*((-2).*exp(1).^(a2+ ...
  2.*logthetax+4.*logthetay).*(exp(1).^logthetay+(-1).*(y+(-1).*yp).^2)+ ...
  4.*exp(1).^(a2+logthetax+4.*logthetay).*(x+(-1).*xp).^2.*(exp(1) ...
  .^logthetay+(-1).*(y+(-1).*yp).^2)+(-2).*exp(1).^(a2+2.*(logthetax+ ...
  logthetay)).*(6.*exp(1).^(2.*logthetax+logthetay)+exp(1).^(logthetax+2.* ...
  logthetay)+(-1).*exp(1).^(2.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^( ...
  2.*logthetax).*(y+(-1).*yp).^2)+exp(1).^(a2+2.*logthetay).*((-1).*exp(1) ...
  .^logthetax+(x+(-1).*xp).^2).*(3.*exp(1).^(2.*(logthetax+logthetay))+ ...
  exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).* ...
  xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).* ...
  exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay) ...
  .*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp) ...
  .^4)+exp(1).^(a2+2.*logthetax).*((-1).*exp(1).^logthetay+(y+(-1).*yp) ...
  .^2).*(3.*exp(1).^(2.*(logthetax+logthetay))+exp(1).^(logthetax+3.* ...
  logthetay)+(-1).*exp(1).^(3.*logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^( ...
  2.*logthetax+logthetay).*(y+(-1).*yp).^2+(-1).*exp(1).^(logthetax+2.* ...
  logthetay).*(y+(-1).*yp).^2+exp(1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+ ...
  (-1).*yp).^2+exp(1).^(2.*logthetax).*(y+(-1).*yp).^4)+(-4).*exp(1).^(a2+ ...
  2.*logthetax+logthetay).*((-6).*exp(1).^(2.*logthetax+logthetay)+(-1).* ...
  exp(1).^(logthetax+2.*logthetay)+exp(1).^(2.*logthetay).*(x+(-1).*xp) ...
  .^2+2.*exp(1).^(2.*logthetax).*(y+(-1).*yp).^2).*(y+(-1).*yp).^2)+exp(1) ...
  .^(a2+(-2).*logthetax+2.*logthetay).*(3.*exp(1).^(2.*(logthetax+ ...
  logthetay))+exp(1).^(logthetax+3.*logthetay)+(-1).*exp(1).^(3.* ...
  logthetay).*(x+(-1).*xp).^2+(-6).*exp(1).^(2.*logthetax+logthetay).*(y+( ...
  -1).*yp).^2+(-1).*exp(1).^(logthetax+2.*logthetay).*(y+(-1).*yp).^2+exp( ...
  1).^(2.*logthetay).*(x+(-1).*xp).^2.*(y+(-1).*yp).^2+exp(1).^(2.* ...
  logthetax).*(y+(-1).*yp).^4));

case 6 % logsigmap

K=dt.^2.*exp(1).^(logsigmap+(-2).*logthetaxp+(-1/2).*exp(1).^((-1).* ...
  logthetaxp).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetayp).*(y+(-1) ...
  .*yp).^2).*(exp(1).^logthetaxp+(-1).*(x+(-1).*xp).^2);

case 7 % logthetaxp

K=(-1/2).*dt.^2.*exp(1).^(logsigmap+(-3).*logthetaxp+(-1/2).*exp(1).^((-1) ...
  .*logthetaxp).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1).*logthetayp).*(y+( ...
  -1).*yp).^2).*(2.*exp(1).^(2.*logthetaxp)+(-5).*exp(1).^logthetaxp.*(x+( ...
  -1).*xp).^2+(x+(-1).*xp).^4);

case 8 % logthetayp

K=(1/2).*dt.^2.*exp(1).^(logsigmap+(-2).*logthetaxp+(-1).*logthetayp+( ...
  -1/2).*exp(1).^((-1).*logthetaxp).*(x+(-1).*xp).^2+(-1/2).*exp(1).^((-1) ...
  .*logthetayp).*(y+(-1).*yp).^2).*(exp(1).^logthetaxp+(-1).*(x+(-1).*xp) ...
  .^2).*(y+(-1).*yp).^2;

otherwise

        K = zeros(n_x, n_xp);
end

end


%
%  Context-Aware Correlation Filters
%
%  Written by Luca Bertinetto, 2016
%  Adapted by Matthias Mueller, 2016
%
%  This function takes care of setting up parameters, loading video
%  information and computing precisions. For the actual tracking code,
%  check out the TRACKERMAIN.m function.
%

function run_tracker(video, start_frame)
% RUN_TRACKER  is the external function of the tracker - does initialization and calls trackerMain

	%path to the videos (you'll be able to choose one with the GUI).
	base_path = 'sequences/';

	%default settings
	if nargin < 1, video = 'Skiing'; end
	if nargin < 2, start_frame = 1; end
    if nargin < 3, show_plots = 1; end

    %% Read params.txt
    params = readParams('params.txt');
	%% load video info
    sequence_path = fullfile(base_path,video);
    img_path = fullfile(sequence_path, 'img');
    %% Read files
    text_files = dir([sequence_path '*_frames.txt']);
    if(~isempty(text_files))
        f = fopen([sequence_path text_files(1).name]);
        frames = textscan(f, '%f,%f');
        fclose(f);
    else
        frames = {};
    end
    if exist('start_frame')
        frames{1} = start_frame;
    else
        frames{1} = 1;
    end

    params.bb_VOT = csvread(fullfile(sequence_path, 'groundtruth_rect.txt'));
    region = params.bb_VOT(frames{1},:);
    %%%%%%%%%%%%%%%%%%%%%%%%%
    % read all the frames in the 'imgs' subfolder
    dir_content = dir(fullfile(sequence_path, 'img'));
    % skip '.' and '..' from the count
    n_imgs = length(dir_content) - 2;
    img_files = cell(n_imgs, 1);
    for ii = 1:n_imgs
        img_files{ii} = dir_content(ii+2).name;
    end

    img_files(1:start_frame-1)=[];

    im = imread(fullfile(img_path, img_files{1}));
    % is a grayscale sequence ?
    if(size(im,3)==1)
        params.grayscale_sequence = true;
    end

    params.img_files = img_files;
    params.img_path = img_path;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    if(numel(region)==8)
        % polygon format
        [cx, cy, w, h] = getAxisAlignedBB(region);
    else
        x = region(1);
        y = region(2);
        w = region(3);
        h = region(4);
        cx = x+w/2;
        cy = y+h/2;
    end

    % init_pos is the centre of the initial bounding box
    params.init_pos = [cy cx];
    params.target_sz = round([h w]);
    [params, bg_area, fg_area, area_resize_factor] = initializeAllAreas(im, params);
	if params.visualization
		params.videoPlayer = vision.VideoPlayer('Position', [100 100 [size(im,2), size(im,1)]+30]);
	end
    % in runTracker we do not output anything
	params.fout = -1;
	% start the actual tracking
	results = trackerMain(params, im, bg_area, fg_area, area_resize_factor);

    %calculate and show precision plot, as well as frames-per-second
    precisions = precision_plot(results.res, params.bb_VOT, video, show_plots);
    fprintf('%12s - Precision (20px):% 1.3f, FPS:% 4.2f\n', video, precisions(20), results.fps)
    fclose('all');

end


function [maps,stats] = SurveyFiringMaps(units,varargin)

%SurveyFiringMaps - Compute and plot firing maps for all subsessions.
%
%  USAGE
%
%    [maps,stats] = SurveyFiringMaps(units,<options>)
%
%    units          optional list of units, i.e. [electrode group, cluster]
%                   pairs; set cluster to -1 to process all clusters
%    <options>      optional list of property-value pairs (see table below)
%
%    =========================================================================
%     Properties    Values
%    -------------------------------------------------------------------------
%     'minv'        minimum instantaneous velocity (default = 0)
%     'pixel'       size of the video pixel in cm (no default value)
%     'show'        set to 'off' to compute but not plot data (default = 'on')
%    =========================================================================
%
%  OUTPUT
%
%    The outputs are the same as for MapStats, except for map.z which is
%    replaced by map.rate.
%
%  SEE
%
%    See also FiringMap, PlotColorMap.

% Copyright (C) 2009-2013 by Anne Cei, Michaël Zugaro
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 3 of the License, or
% (at your option) any later version.

% Default values
minv = [];
pixel = [];
show = 'on';

% No unit list provided?
if ~(nargin >= 1 && isimatrix(units)),
	units = GetUnits;
	varargin = {units,varargin{:}};
else
	all = units(:,2) == -1;
	groups = unique(units(all,1));
	units(all,:) = [];
	units = unique([units;GetUnits(groups)],'rows');
end
nUnits = size(units,1);

if mod(length(varargin),2) ~= 0,
	error('Incorrect number of parameters (type ''help SurveyFiringMaps'' for details).');
end

% Parse options
for i = 1:2:length(varargin),
	if ~ischar(varargin{i}),
		error(['Parameter ' num2str(i+1) ' is not a property (type ''help SurveyFiringMaps'' for details).']);
	end
	switch(lower(varargin{i})),
		case 'minv',
			minv = varargin{i+1};
			if ~isdscalar(minv,'>=0'),
				error('Incorrect value for property ''minv'' (type ''help SurveyFiringMaps'' for details).');
			end
		case 'pixel',
			pixel = varargin{i+1};
			if ~isdscalar(pixel,'>0'),
				error('Incorrect value for property ''pixel'' (type ''help SurveyFiringMaps'' for details).');
			end
		case 'show',
			show = varargin{i+1};
			if ~isstring_FMAT(show,'on','off'),
				error('Incorrect value for property ''show'' (type ''help SurveyFiringMaps'' for details).');
			end
		otherwise,
			error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help SurveyFiringMaps'' for details).']);
	end
end

% Get positions
positions = GetPositions;
if isempty(positions), warning('No positions found for current subsession'); return; end
if ~isempty(minv),
	if isempty(pixel),
		error(['Missing pixel size for minimum velocity (type ''help SurveyFiringMaps'' for details).']);
	end
	x = GetPositions('coordinates','real','pixel',pixel);
	v = LinearVelocity(x,30);
	[~,in] = Threshold(v,'>',minv,'min',10,'max',2);
	positions = positions(in,:);
end

% Get start/stop events for each subsession
start = GetEvents('beginning of .*');
stop = GetEvents('end of .*');
nSubsessions = length(start);

if strcmp(show,'on'),
	titles = GetEventTypes('beginning of .*');
	status = Hide('status');
	Hide('on');
	figureList = [];
end

try
	n = 0;
	% Loop through units
	for j = 1:nUnits,
		if strcmp(show,'on'), figureList = [figureList figure]; end
		spikes = GetSpikes(units(j,:));
		% Loop through subsessions
		for i = 1:nSubsessions,
			p = Restrict(positions,[start(i) stop(i)]);
			s = Restrict(spikes,[start(i) stop(i)]);
			if nargin == 0,
				map = FiringMap(p(:,1:3),s,'nbins',[250 250],'smooth',5,'mintime',0);
			else
				[map,st] = FiringMap(p(:,1:3),s,'nbins',[250 250],'smooth',5,'mintime',0);
				st.unit = units(j,:);
				st.subsession = i;
				n = n + 1;
				stats(n) = st;
				maps(n) = map;
			end
			if strcmp(show,'on'),
				SquareSubplot(nSubsessions,i);
				PlotColorMap(map.rate,map.time,'ydir','reverse','bar','off','cutoffs',[0 10],'gamma',2);
				title = titles{i}(14:end);
				SplitTitle([title ' (' int2str(units(j,1)) '-' int2str(units(j,2)) ')'],round(150/sqrt(nSubsessions)));
			end
		end
	end
catch err
	if strcmp(show,'on'),
		Hide(status);
		Hide(figureList,status);
	end
	err.rethrow;
end

if strcmp(show,'on'),
	Hide(status);
	Hide(figureList,status);
end


%% Example 1 Overview
%
% GLMsingle is new tool that provides efficient, scalable, and accurate
% single-trial fMRI response estimates.
%
% The purpose of this Example 1 notebook is to guide the user through basic
% calls to GLMsingle, using a representative, small-scale test dataset (in
% this case, an example session from a rapid event-related visual fMRI
% dataset - the Natural Scenes Dataset core experiment).
%
% The goal is to examine the effect of GLMsingle on the reliability of
% single-trial fMRI response estimates. By default, the tool implements a
% set of optimizations that improve upon generic GLM approaches by: (1)
% identifying an optimal hemodynamic response function (HRF) at each voxel,
% (2) deriving a set of useful GLM nuisance regressors via "GLMdenoise" and
% picking an optimal number to include in the final GLM, and (3) applying a
% custom amount of ridge regularization at each voxel using an efficient
% technique called "fracridge". The output of GLMsingle are GLM betas
% reflecting the estimated percent signal change in each voxel in response
% to each experimental stimulus or condition being modeled.
%
% Beyond directly improving the reliability of neural responses to repeated
% stimuli, these optimized techniques for signal estimation can have a
% range of desirable downstream effects such as: improving cross-subject
% representational similarity within and between datasets; improving the
% single-image decodability of evoked neural patterns via MVPA; and,
% decreasing the correlation in spatial patterns observed at neighboring
% timepoints in analysis of fMRI GLM outputs. See our video presentation at
% V-VSS 2020 for a summary of these phenomena as observed in recent
% massive-scale fMRI datasets (the Natural Scenes Dataset and BOLD5000):
% https://www.youtube.com/watch?v=yb3Nn7Han8o
%
% Example 1 contains a full walkthrough of the process of loading an
% example dataset and design matrix, estimating neural responses using
% GLMsingle, estimating the reliability of responses at each voxel, and
% comparing those achieved via GLMsingle to those achieved using a baseline
% GLM. After loading and visualizing formatted fMRI time-series and their
% corresponding design matrices, we will describe the default behavior of
% GLMsingle and show how to modify hyperparameters if the user desires.
% Throughout the notebook we will highlight important metrics and outputs
% using figures, print statements, and comments.
%
% Users encountering bugs, unexpected outputs, or other issues regarding
% GLMsingle shouldn't hesitate to raise an issue on GitHub:
% https://github.com/kendrickkay/GLMsingle/issues

%% Add dependencies and download the example dataset

% Start fresh
clear
clc
close all

this_dir    = fileparts(which('example1.m'));

% Add path to GLMsingle
run(fullfile(this_dir, '..', '..', 'setup.m'));

% Name of directory to which outputs will be saved
outputdir = fullfile(this_dir, 'example1outputs');

% Download files to data directory
input_dir = fullfile(this_dir, 'data');
if ~exist(input_dir, 'dir')
    mkdir('data')
end

input_file = fullfile(input_dir, 'nsdcoreexampledataset.mat');
URL = 'https://osf.io/k89b2/download';

download_data(URL, input_file);

load(input_file)

% Data comes from the NSD dataset (subj01, nsd01 scan session).
% https://www.biorxiv.org/content/10.1101/2021.02.22.432340v1.full.pdf

%% Data overview
clc
whos

% data -> consists of several runs of 4D volume files (x,y,z,t)  where
% (t)ime is the 4th dimention. In this example, data consists of only a
% single slice and has been prepared with a TR = 1s

% ROI -> manually defined region in the occipital cortex. It is a binary
% matrix where (x,y,z) = 1 corresponds to the cortical area that responded
% to visual stimuli used in the NSD project.

fprintf('There are %d runs in total.\n',length(design));
fprintf('The dimensions of the data for the first run are %s.\n',mat2str(size(data{1})));
fprintf('The stimulus duration is %.3f seconds.\n',stimdur);
fprintf('The sampling rate (TR) is %.3f seconds.\n',tr);

%%

figure(1);clf

%Show example design matrix.
for d = 1
    imagesc(design{d}); colormap gray; drawnow
    xlabel('Conditions')
    ylabel('TRs')
    title(sprintf('Design matrix for run%i',d))
    axis image
end

xticks(0:53:length(design{d}))
set(gcf,'Position',[418   412   782   605])

%%
% design -> Each run has a corresponding design matrix where each column
% describes a single condition (conditions are repeated across runs). Each
% design matrix is binary with 1 specfing the time (TR) when the stimulus
% is presented on the screen.
%
% In this NSD scan session, there are a total of 750 trials, in which a
% total of 583 distinct images are shown. (Thus, some images were presented
% more than once.) In the design matrix shown, there are 583 predictor
% columns/conditions, one per distinct image. Notice that white rectangles
% are pseudo randomized and they indicate when the presentation of each
% image occurs. Note that in some runs not all images are shown; if a
% column does not have a white rectangle it means that this image is shown
% in a different run within the session.

%%

% Show an example slice of the first fMRI volume.
figure(2);clf
imagesc(data{1}(:,:,:,1));
colormap(gray);
axis equal tight;
c=colorbar;
title('fMRI data (first volume)');
set(gcf,'Position',[418   412   782   605])
axis off
c.Label.String = 'T2*w intensity';
set(gca,'FontSize',15)

%% Call GLMestimatesingletrial with default parameters

% Outputs and figures will be stored in a folder (you can specify its name
% as the 5th input to GLMestimatesingletrial). Model estimates can be also
% saved to the 'results' variable which is the only output of
% GLMestimatesingletrial.

% Optional parameters below can be assigned to a structure, i.e., opt =
% struct('wantlibrary',1,'wantglmdenoise',1); Options are the 6th input to
% GLMestimatesingletrial.

% There are many options that can be specified; here, we comment on the
% main options that one might want to modify/set. Defaults for the options
% are indicated below.

% wantlibrary = 1 -> Fit HRF to each voxel
% wantglmdenoise = 1 -> Use GLMdenoise
% wantfracridge = 1  -> Use ridge regression to improve beta estimates
% chunknum = 50000 -> is the number of voxels that we will
%     process at the same time. For setups with lower memory, you may need to
%     decrease this number.

% wantmemoryoutputs is a logical vector [A B C D] indicating which of the
%     four model types to return in the output <results>. The user must be
%     careful with this, as large datasets can require a lot of RAM. If you
%     do not request the various model types, they will be cleared from
%     memory (but still potentially saved to disk). Default: [0 0 0 1]
%     which means return only the final type-D model.

% wantfileoutputs is a logical vector [A B C D] indicating which of the
%     four model types to save to disk (assuming that they are computed). A
%     = 0/1 for saving the results of the ONOFF model, B = 0/1 for saving
%     the results of the FITHRF model, C = 0/1 for saving the results of the
%     FITHRF_GLMdenoise model, D = 0/1 for saving the results of the
%     FITHRF_GLMdenoise_RR model. Default: [1 1 1 1] which means save all
%     computed results to disk.

% numpcstotry (optional) is a non-negative integer indicating the maximum
%     number of GLMdenoise PCs to enter into the model. Default: 10.

% fracs (optional) is a vector of fractions that are greater than 0
%     and less than or equal to 1. We automatically sort in descending
%     order and ensure the fractions are unique. These fractions indicate
%     the regularization levels to evaluate using fractional ridge
%     regression (fracridge) and cross-validation. Default:
%     fliplr(.05:.05:1). A special case is when <fracs> is specified as a
%     single scalar value. In this case, cross-validation is NOT performed
%     for the type-D model, and we instead blindly use the supplied
%     fractional value for the type-D model.

% For the purpose of this example, we will keep all outputs in the memory.
opt = struct('wantmemoryoutputs',[1 1 1 1]);

% This example saves output .mat files to the folder
% "example1outputs/GLMsingle". If these outputs don't already exist, we
% will perform the time-consuming call to GLMestimatesingletrial.m;
% otherwise, we will just load from disk.
if ~exist(fullfile(outputdir, 'GLMsingle', 'TYPEB_FITHRF.mat'),'file') || ...
   ~exist(fullfile(outputdir, 'GLMsingle', 'TYPEC_FITHRF_GLMDENOISE.mat'),'file') || ...
   ~exist(fullfile(outputdir, 'GLMsingle', 'TYPED_FITHRF_GLMDENOISE_RR.mat'),'file')

    [results designSINGLE] = GLMestimatesingletrial(design,data,stimdur,tr,[outputdir '/GLMsingle'],opt);

    % We assign outputs of GLMestimatesingletrial to "models" structure.
    % Note that results{1} contains GLM estimates from an ONOFF model,
    % where all images are treated as the same condition. These estimates
    % could be potentially used to find cortical areas that respond to
    % visual stimuli. We want to compare beta weights between conditions
    % therefore we are not going to store the ONOFF GLM results.

    clear models;
    models.FIT_HRF = results{2};
    models.FIT_HRF_GLMdenoise = results{3};
    models.FIT_HRF_GLMdenoise_RR = results{4};

else
    % Load existing file outputs if they exist
    results = load([outputdir '/GLMsingle/TYPEB_FITHRF.mat']);
    models.FIT_HRF = results;
    results = load([outputdir '/GLMsingle/TYPEC_FITHRF_GLMDENOISE.mat']);
    models.FIT_HRF_GLMdenoise = results;
    results = load([outputdir '/GLMsingle/TYPED_FITHRF_GLMDENOISE_RR.mat']);
    models.FIT_HRF_GLMdenoise_RR = results;

end

%% Summary of important outputs

% The outputs of GLMestimatesingletrial.m are formally documented in its
% header. Here, we highlight a few of the more important outputs:
%
% R2 -> is model accuracy expressed in terms of R^2 (percentage).
%
% modelmd -> is the full set of single-trial beta weights (X x Y x Z x
% TRIALS). Beta weights are arranged in chronological order.
%
% HRFindex -> is the 1-index of the best fit HRF. HRFs can be recovered
% with getcanonicalHRFlibrary(stimdur,tr)
%
% FRACvalue -> is the fractional ridge regression regularization level
% chosen for each voxel. Values closer to 1 mean less regularization.

%% Plot a slice of brain showing GLMsingle outputs

% We are going to plot several outputs from the FIT_HRF_GLMdenoise_RR GLM,
% which contains the full set of GLMsingle optimizations.

slice = 1;

% we will plot betas, R2, optimal HRF indices, and the voxel frac values
val2plot = {'modelmd';'R2';'HRFindex';'FRACvalue'};
cmaps = {cmapsign2;hot;jet;copper};

figure(3);clf

for v = 1 : length(val2plot)

    f=subplot(2,2,v);

    if contains('modelmd',val2plot{v})
        % When plotting betas, for simplicity just average across all image
        % presentations This will yield a summary of whether voxels tend to
        % increase or decrease their activity in response to the
        % experimental stimuli (similar to outputs from an ONOFF GLM)
        imagesc(nanmean(models.FIT_HRF_GLMdenoise_RR.(val2plot{v})(:,:,slice),4),[-5 5]); axis off image;
        title('Average GLM betas (750 stimuli)')

    else
        % Plot all other voxel-wise metrics as outputted from GLMsingle
        imagesc(models.FIT_HRF_GLMdenoise_RR.(val2plot{v})(:,:,slice)); axis off image;
        title(val2plot{v})

    end

    colormap(f,cmaps{v})
    colorbar
    set(gca,'FontSize',15)
end

set(gcf,'Position',[418   412   782   605])

%% Run a baseline GLM to compare with GLMsingle

% Additionally, for comparison purposes we are going to run a standard GLM
% without HRF fitting, GLMdenoise, or ridge regression regularization. We
% will change the default settings by using the "opt" structure.
opt.wantlibrary = 0; % switch off HRF fitting
opt.wantglmdenoise = 0; % switch off GLMdenoise
opt.wantfracridge = 0; % switch off ridge regression
opt.wantfileoutputs = [0 1 0 0];
opt.wantmemoryoutputs = [0 1 0 0];

% If these outputs don't already exist, we will perform the call to
% GLMestimatesingletrial.m; otherwise, we will just load from disk.
if ~exist(fullfile(outputdir, 'GLMbaseline', 'TYPEB_FITHRF.mat'),'file')

    [ASSUME_HRF] = GLMestimatesingletrial(design,data,stimdur,tr,[outputdir '/GLMbaseline'],opt);
    models.ASSUME_HRF = ASSUME_HRF{2};

else

    % Note that even though we are loading TYPEB_FITHRF betas, HRF fitting
    % has been turned off and this struct field will thus contain the
    % outputs of a GLM fit using the canonical HRF.
    results = load([outputdir '/GLMbaseline/TYPEB_FITHRF.mat']);
    models.ASSUME_HRF = results;

end

% We assign outputs from GLMestimatesingletrial to "models" structure.
% Again, results{1} contains GLM estimates from an ONOFF model so we are
% not going to extract it.

%%

% Now, "models" variable holds solutions for 4 GLM models
disp(fieldnames(models))

%% Get indices of repeated conditions to use for reliability calculations

% To compare the results of different GLMs we are going to calculate the
% voxel-wise split-half reliablity for each model. Reliability values
% reflect a correlation between beta weights for repeated presentations of
% the same conditions. In short, we are going to check how
% reliable/reproducible are the single trial responses to repeated
% conditions estimated with each GLM type.

% This NSD scan session has a large number of images that are just shown
% once during the session, some images that are shown twice, and a few that
% are shown three times. In the code below, we are attempting to locate the
% indices in the beta weight GLMsingle outputs modelmd(x,y,z,trials) that
% correspond to repeated images. Here we only consider stimuli that have
% been presented at least twice. For the purpose of the example we ignore
% the 3rd repetition of the stimulus.

% Consolidate design matrices
designALL = cat(1,design{:});

% Construct a vector containing 1-indexed condition numbers in
% chronological order.

corder = [];
for p=1:size(designALL,1)
    if any(designALL(p,:))
        corder = [corder find(designALL(p,:))];
    end
end

%%

% Let's take a look at the first few entries
corder(1:3)

% Note that [375 497 8] means that the first stimulus trial involved
% presentation of the 375th condition, the second stimulus trial involved
% presentation of the 497th condition, and so on.

%%

% In order to compute split-half reliability, we have to do some indexing.
% we want to find images with least two repetitions and then prepare a
% useful matrix of indices that refer to when these occur.
repindices = [];  % 2 x images containing stimulus trial indices.

% The first row refers to the first presentation; the second row refers to
% the second presentation.
for p=1:size(designALL,2)  % loop over every condition
    temp = find(corder==p);
    if length(temp) >= 2
        repindices = cat(2,repindices,[temp(1); temp(2)]);  % note that for images with 3 presentations, we are simply ignoring the third trial
    end
end

% Let's take a look at a few entries
repindices(:,1:3)

% Notice that the first condition is presented on the 217th stimulus trial
% and the 486th stimulus trial, the second condition is presented on the
% 218th and 621st stimulus trials, and so on.

fprintf('There are %i repeated images in the experiment \n',length(repindices))

% Now, for each voxel we are going to correlate beta weights describing the
% response to images presented for the first time with beta weights
% describing the response from the repetition of the same image. With 136
% repeated conditions, the correlation for each voxel will reflect the
% relationship between two vectors with 136 beta weights each.

%% Compute median split-half reliability for each GLM version

% Finally, let's compute split-half reliability. We are going to loop
% through our 4 models and calculate split-half reliability for each of
% them.

% We first arrange models from least to most sophisticated (for
% visualization purposes)
model_names = fieldnames(models);
model_names = model_names([4 1 2 3]);

% Create output variable for reliability values
vox_reliabilities = cell(1,length(models));

% For each GLM...
for m = 1 : length(model_names)

    % Get the GLM betas
    betas = models.(model_names{m}).modelmd(:,:,:,repindices);  % use indexing to pull out the trials we want
    betas_reshaped = reshape(betas,size(betas,1),size(betas,2),size(betas,3),2,[]);  % reshape to X x Y x Z x 2 x CONDITIONS

    % compute reliabilities using an efficient (vectorized) utility
    % function
    vox_reliabilities{m} = calccorrelation(betas_reshaped(:,:,:,1,:),betas_reshaped(:,:,:,2,:),5);

    % Note that calccorrelation.m is a utility function that computes
    % correlations in a vectorized fashion (for optimal speed).

end

%% Compare visual voxel reliabilities between beta versions

figure(4);clf
subplot(1,2,1);
cmap = [0.2314    0.6039    0.6980
    0.8615    0.7890    0.2457
    0.8824    0.6863         0
    0.9490    0.1020         0];

% For each GLM type we calculate median reliability for voxels within the
% visual ROI and plot it as a bar plot.
for m = 1 : 4
    bar(m,nanmedian(vox_reliabilities{m}(ROI==1)),'FaceColor','None','Linewidth',3,'EdgeColor',cmap(m,:)); hold on
end
ylabel('Median reliability')
legend(model_names,'Interpreter','None','Location','NorthWest')
set(gca,'Fontsize',16)
set(gca,'TickLabelInterpreter','none')
xtickangle(0)
xticks([])
ylim([0.1 0.2])
set(gcf,'Position',[418   412   782   605])
title('Median voxel split-half reliability of GLM models')

subplot(1,2,1);

% Comparison is the final output (FIT_HRF_GLMDENOISE_RR) vs. the baseline
% GLM (ASSUME_HRF)
vox_reliability = vox_reliabilities{4} - vox_reliabilities{1};
underlay = data{1}(:,:,:,1);
ROI(ROI~=1) = NaN;
overlay = vox_reliability;

underlay_im = cmaplookup(underlay,min(underlay(:)),max(underlay(:)),[],gray(256));
overlay_im = cmaplookup(overlay,-0.3,0.3,[],cmapsign2);

mask = ROI==1;

subplot(1,2,2);
hold on
imagesc(underlay_im);
imagesc(overlay_im, 'AlphaData', mask);
hold off
axis image
colormap(cmapsign2)
c = colorbar;
c.Ticks = [0 0.5 1];
c.TickLabels = {'-0.3';'0';'0.3'};
title('change in nsdgeneral voxel reliability** due to GLMsingle (\Delta{\itr})')
set(gca,'Fontsize',16)
xlabel('**plotting (FITHRF_GLMDENOISE_RR - ASSUMEHRF) reliabilities','Interpreter','none','FontSize',12);
xticks([])
yticks([])

set(gcf,'Position',[36 343 1116 674])

% Notice that there is systematic increase in reliability moving from the
% first to the second to the third to the final fourth version of the GLM
% results. These increases reflect, respectively, the addition of HRF
% fitting, the derivation and use of data-driven nuisance regressors, and
% the use of ridge regression as a way to regularize the instability of
% closely spaced experimental trials. Depending on one's experimental
% goals, it is possible with setting of option flags to activate a subset
% of these analysis features.
%
% Also, keep in mind that in the above figure, we are simply showing the
% median as a metric of the central tendency (you may want to peruse
% individual voxels in scatter plots, for example).


% Copyright (C) 2017-2018 Titus Cieslewski, RPG, University of Zurich,
%   Switzerland
%   You can contact the author at <titus at ifi dot uzh dot ch>
% Copyright (C) 2017-2018 Siddharth Choudhary, College of Computing,
%   Georgia Institute of Technology, Atlanta, GA, USA
% Copyright (C) 2017-2018 Davide Scaramuzza, RPG, University of Zurich,
%   Switzerland
%
% This file is part of dslam_open.
%
% dslam_open is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% dslam_open is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with dslam_open. If not, see <http://www.gnu.org/licenses/>.

function [decentr_state, dgs_stats, final_increments, ...
    final_increment_times, opt_handle, final_accuracy_measurements] = ...
    wrapUpOptimization(...
    decentr_state, opt_handle, distributed_mapper_location, params, ...
    final_time)

t = tic;
% Collect data from still running optimization and launch last one.
[decentr_state, opt_handle, dgs_stats, opt_increment] = ...
    manageAsyncGaussSeidel(...
    decentr_state, opt_handle, distributed_mapper_location, true, ...
    params.opt_max_iters, true);
t0 = toc(t);
for i = 1:numel(dgs_stats)
    dgs_stats{i}.end_time = final_time + t0;
end
final_increments = ...
    {cat(3, opt_increment, zeros(size(opt_increment)), ...
    zeros(size(opt_increment)))};
final_increment_times = [final_time + t0];
[accuracy_measurement, decentr_state] = ...
    evalAccuracy(...
    decentr_state, opt_handle, final_time + t0);
final_accuracy_measurements = {accuracy_measurement};
plotDecentrState(decentr_state);
pause(0.0001);

% Collect last one (final launch will be ignored).
[decentr_state, ~, last_dgs_stats, opt_increment] = ...
    manageAsyncGaussSeidel(...
    decentr_state, opt_handle, distributed_mapper_location, true, ...
    params.opt_max_iters, false);
t1 = toc(t);
for i = 1:numel(last_dgs_stats)
    last_dgs_stats{i}.end_time = final_time + t1;
end
dgs_stats = [dgs_stats; last_dgs_stats];
final_increments = [final_increments;
    cat(3, opt_increment, zeros(size(opt_increment)), ...
    zeros(size(opt_increment)))];
final_increment_times = [final_increment_times; final_time + t1];
[accuracy_measurement, decentr_state] = ...
    evalAccuracy(decentr_state, opt_handle, final_time + t1);
final_accuracy_measurements = [final_accuracy_measurements; ...
    accuracy_measurement];
plotDecentrState(decentr_state);
pause(0.0001);

end


%CODEGENERATOR.GENSLBLOCKINERTIA Generate Simulink block for inertia matrix
%
% cGen.genslbgenslblockinertia() generates a robot-specific Simulink block to compute
% robot inertia matrix.
%
% Notes::
% - Is called by CodeGenerator.geninertia if cGen has active flag genslblock
% - The Inertia matrix is stored row by row to avoid memory issues.
% - The Simulink block recombines the the individual blocks for each row.
% - The Simulink blocks are generated and stored in a robot specific block
%   library cGen.slib in the directory cGen.basepath.
%
% Author::
%  Joern Malzahn, (joern.malzahn@tu-dortmund.de)
%
% See also CodeGenerator.CodeGenerator, CodeGenerator.geninertia.

% Copyright (C) 2012-2014, by Joern Malzahn
%
% This file is part of The Robotics Toolbox for Matlab (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
%
% The code generation module emerged during the work on a project funded by
% the German Research Foundation (DFG, BE1569/7-1). The authors gratefully
% acknowledge the financial support.

function genslblockinertia(CGen)

%% Open or create block library
bdclose('all')                                                              % avoid problems with previously loaded libraries
load_system('simulink');
if ~(exist([CGen.slibpath,simulinkext]) == 2)                                  % Create new block library if none exists
 CGen.createnewblocklibrary;
end
open_system(CGen.slibpath);
set_param(CGen.slib,'lock','off');

q = CGen.rob.gencoords;

%% Generate Inertia Block
CGen.logmsg([datestr(now),'\tGenerating Simulink Block for the robot inertia matrix\n']);
nJoints = CGen.rob.n;

CGen.logmsg([datestr(now),'\t\t... enclosing subsystem ']);
symname = 'inertia';
InertiaBlock = [CGen.slib,'/',symname];
    if ~isempty(find_system(CGen.slib,'SearchDepth',1,'Name',symname))                    % Delete previously generated inertia matrix block
        delete_block(InertiaBlock);
        save_system;
    end
% Subsystem in which individual rows are concatenated
add_block('built-in/SubSystem',InertiaBlock);                               % Add new inertia matrix block
add_block('simulink/Math Operations/Matrix Concatenate'...
    , [InertiaBlock,'/inertia']...
    , 'NumInputs',num2str(nJoints)...
    , 'ConcatenateDimension','1');
add_block('simulink/Sinks/Out1',[InertiaBlock,'/out']);
add_block('simulink/Sources/In1',[InertiaBlock,'/q']);
add_line(InertiaBlock,'inertia/1','out/1');
CGen.logmsg('\t%s\n',' done!');

for kJoints = 1:nJoints
    CGen.logmsg([datestr(now),'\t\t... Embedded Matlab Function Block for joint ',num2str(kJoints),': ']);

    % Generate Embedded Matlab Function block for each row
    symname = ['inertia_row_',num2str(kJoints)];
    fname = fullfile(CGen.sympath,[symname,'.mat']);

    if exist(fname,'file')
        tmpStruct = load(fname);
    else
        error ('genslblockinertia:SymbolicsNotFound','Save symbolic expressions to disk first!')
    end

    blockaddress = [InertiaBlock,'/',symname];
    if doesblockexist(CGen.slib,symname)
        delete_block(blockaddress);
        save_system;
    end

    CGen.logmsg('%s',' block creation');
    symexpr2slblock(blockaddress,tmpStruct.(symname),'vars',{q});

    % connect output
    CGen.logmsg('%s',', output wiring');
    if ( verLessThan('matlab','7.11.0.584') ) && ( isequal(tmpStruct.(symname),zeros(1,nJoints)) )
        % There is a bug in earlier Matlab versions. If the symbolic
        % vector is a zero vector, then the Simulink Embedded Matlab
        % Function block outputs a scalar zero. We need to concatenate
        % a row vector of zeros here, which we have to construct on our
        % own.
        add_block('simulink/Math Operations/Matrix Concatenate'...              % Use a matrix concatenation block ...
            , [InertiaBlock,'/DimCorrection',num2str(kJoints)]...               % ... named with the current row number ...
            , 'NumInputs',num2str(nJoints),'ConcatenateDimension','2');         % ... intended to concatenate zero values for each joint ...
        % ... columnwise. This will circumvent the bug.

        for iJoints = 1:nJoints                                                 % Connect signal lines from the created block (which outputs
            add_line(InertiaBlock...                                            % a scalar zero in this case) with the bugfix block.
                , [symname,'/1']...
                , ['DimCorrection',num2str(kJoints),'/', num2str(iJoints)]);
        end

        add_line(InertiaBlock,['DimCorrection',num2str(kJoints)...              % Connect the fixed row with other rows.
            , '/1'],['inertia/', num2str(kJoints)]);

    else
        add_line(InertiaBlock,[symname,'/1']...          % In case that no bug occurs, we can just connect the rows.
            , ['inertia/', num2str(kJoints)]);
    end

    % Connect inputs
    CGen.logmsg('%s',', input wiring');
    add_line(InertiaBlock,'q/1',[symname,'/1']);
    CGen.logmsg('\t%s\n','row complete!');
end
addterms(InertiaBlock); % Add terminators where needed
distributeblocks(InertiaBlock);
CGen.logmsg([datestr(now),'\tInertia matrix block complete\n']);

%% Built inverse Inertia matrix block
CGen.logmsg([datestr(now),'\tGenerating Simulink Block for the inverse robot inertia matrix\n']);
CGen.logmsg([datestr(now),'\t\t... enclosing subsystem ']);
% block address
symname = 'invinertia';
invInertiaBlock = [CGen.slib,'/',symname];
% remove any existing blocks
    if ~isempty(find_system(CGen.slib,'SearchDepth',1,'Name',symname))                    % Delete previously generated block
        delete_block(invInertiaBlock);
        save_system;
    end
add_block('built-in/SubSystem',invInertiaBlock);
CGen.logmsg('\t%s\n',' done!');

% matrix inversion
CGen.logmsg([datestr(now),'\t\t... matrix inversion block ']);
add_block('simulink/Math Operations/Product',[invInertiaBlock,'/inverse']); % Use a product block...
set_param([invInertiaBlock,'/inverse'],'Inputs','/');                       % ... with single input '/'...
set_param([invInertiaBlock,'/inverse'],'Multiplication','Matrix(*)');       % ... and matrix multiplication
CGen.logmsg('\t%s\n',' done!');

% wire the input and output
CGen.logmsg([datestr(now),'\t\t... input and output ']);
add_block(InertiaBlock,[invInertiaBlock,'/inertiaMatrix']);
add_block('simulink/Sources/In1',[invInertiaBlock,'/q']);
add_block('simulink/Sinks/Out1',[invInertiaBlock,'/out']);

% wire the blocks among each other
CGen.logmsg('and internal wiring');
add_line(invInertiaBlock,'q/1','inertiaMatrix/1');
add_line(invInertiaBlock,'inertiaMatrix/1','inverse/1');
add_line(invInertiaBlock,'inverse/1','out/1');
CGen.logmsg('\t%s\n',' done!');

% add terminators where necessary
addterms(invInertiaBlock);
distributeblocks(invInertiaBlock);
CGen.logmsg([datestr(now),'\tInverse inertia matrix block complete.\n']);

%% Cleanup
% Arrange blocks
distributeblocks(CGen.slib);

% Lock, save and close library
set_param(CGen.slib,'lock','on');
save_system(CGen.slib,CGen.slibpath);
close_system(CGen.slib);

end


function ConvHDRvtoLDRv(hdrv, filenameOutput, fstops, ldrv_gamma, ldrv_quality, ldrv_video_profile)
%
%
%        ConvHDRvtoLDRv(hdrv, filenameOutput, fstops, ldrv_gamma, ldrv_quality, ldrv_video_profile)
%
%
%
%        Input:
%           -hdrv:
%           -filenameOutput:
%           -fstops:
%           -ftops:
%           -ldrv_gamma:
%           -ldrv_quality:
%           -ldrv_video_profile:
%
%
%     Copyright (C) 2016  Francesco Banterle
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
%

if(~exist('ldrv_gamma', 'var'))
    ldrv_gamma = 2.2;
end

if(~exist('ldrv_quality', 'var'))
    ldrv_quality = 95;
end

if(~exist('ldrv_video_profile', 'var'))
    ldrv_video_profile = 'MPEG-4';
end

if(ldrv_gamma < 0)
    bsRGB = 1;
else
    bsRGB = 0;
end

if(isempty(fstops))
    errir('ConvHDRvtoLDRv: fstops cannot be empty!');
end

name = RemoveExt(filenameOutput);
ext = fileExtension(filenameOutput);

bVideo = 0;
writerObj = 0;

if(strcmp(ext, 'avi') == 1 | strcmp(ext, 'mp4') == 1)
    bVideo = 1;
    writerObj = VideoWriter(filenameOutput, ldrv_video_profile);
    writerObj.FrameRate = hdrv.FrameRate;
    writerObj.Quality = ldrv_quality;
    open(writerObj);
end

if(bVideo == 0)
    mkdir([name,'_img']);
end

hdrv = hdrvopen(hdrv, 'r');

n = length(fstops);

for i=1:hdrv.totalFrames
    disp(['Processing frame ', num2str(i)]);
    [frame, hdrv] = hdrvGetFrame(hdrv, i);

    frame(frame < 0) = 0;

    j = mod(i, n) + 1;

    frameOut = frame * 2^fstops(j);

    %Gamma/sRGB encoding
    if(bsRGB)
        frameOut = ClampImg(ConvertRGBtosRGB(frameOut, 0), 0, 1);
    else
        frameOut = ClampImg(GammaTMO(frameOut, ldrv_gamma, 0, 0), 0, 1);
    end

    %Storing
    if(bVideo)
        writeVideo(writerObj, frameOut);
    else
        nameOut = [name, '_img/frame_', sprintf('%.10d',i), '.', ext];
        imwrite(frameOut, nameOut);

        nameOut = [name, '_img/frame_', sprintf('%.10d',i), '.exr'];
        hdrimwrite(frame, nameOut);
    end
end

hdrvclose(hdrv);

end


function extra_data_info=my_net_forward(net_info, work_info_batch, data_info, net_run_config, extra_output_layer_idxes)

    gpu_mode=net_run_config.use_gpu;
    if gpu_mode
      if ~net_info.ref.net_on_gpu
           my_move_net(net_info, 'gpu') ;
      end
      data_info.ref.output_info_layers{1}=...
          move_output_info_gpu(data_info.ref.output_info_layers{1});
    else
      assert(~net_info.ref.net_on_gpu);
      data_info.ref.output_info_layers{1}=...
          move_output_info_cpu(data_info.ref.output_info_layers{1});
    end

    extra_data_info=do_forward(net_info, work_info_batch, data_info, net_run_config, extra_output_layer_idxes);

    if gpu_mode
        if ~net_info.ref.net_stay_on_gpu
            my_move_net(net_info, 'cpu') ;
        end
    end

end

function extra_data_info=do_forward(net_info, work_info_batch, data_info, net_run_config, extra_output_layer_idxes)

layer_num = numel(net_info.ref.layers) ;
gpu_mode = net_run_config.use_gpu;

if gpu_mode && net_run_config.sync
    wait(gpuDevice) ;
end

assert(check_valid_net_output(data_info.ref.output_info_layers{1}));

bp_turn_on_layer=-1;
disableDropout=true;
keep_layer_output=false;

do_bp_current_net=check_do_bp_current_net(work_info_batch, net_run_config, net_info);
if do_bp_current_net
    bp_start_layer=net_info.ref.bp_start_layer;
    bp_turn_on_layer=bp_start_layer;
end

data_info.ref.need_bp=do_bp_current_net;

extra_output_layer_flags=false(layer_num, 1);
if ~isempty(extra_output_layer_idxes)
    extra_output_layers=cell(layer_num, 1);
    extra_output_layer_flags(extra_output_layer_idxes)=true;
else
    extra_output_layers=[];
end

for layer_idx=1:layer_num

    input_info=data_info.ref.output_info_layers{layer_idx};
    l = net_info.ref.layers{layer_idx} ;
    is_simple_layer= ~strcmp(l.type, 'my_custom');

    if bp_turn_on_layer==layer_idx
        disableDropout=false;
        keep_layer_output=true;
    end

        if is_simple_layer
            output_info=data_info.ref.output_info_layers{layer_idx+1};
            assert(~input_info.is_group_data);
            assert(~output_info.is_group_data);
            switch l.type
                case 'conv'
                    input_size=size(input_info.x);
                    filter_size=size(l.filters);
                    if filter_size(3)~=input_size(3)

                        disp('filter_size:');
                        disp(filter_size);
                        disp('input_size:');
                        disp(input_size);
                        error('filter size not match input size!');
                    end
                    if any(filter_size(1:2)>input_size(1:2))
                        error('filter size larger than the input size!');
                    end
                  output_info.x = vl_nnconv(input_info.x, l.filters, l.biases, 'pad', l.pad, 'stride', l.stride) ;
                case 'pool'
                    input_size=size(input_info.x);
                    pool_size=l.pool;
                    if any(pool_size(1:2)>input_size(1:2))
                        error('pool size larger than the input size!');
                    end
                    output_info.x = vl_nnpool(input_info.x, l.pool, 'pad', l.pad, 'stride', l.stride, 'method', l.method) ;
                case 'normalize'
                  output_info.x = vl_nnnormalize(input_info.x, l.param) ;
                case 'softmax'
                  output_info.x = vl_nnsoftmax(input_info.x) ;
                case 'relu'
                  output_info.x = vl_nnrelu(input_info.x) ;
                case 'noffset'
                  output_info.x = vl_nnnoffset(input_info.x, l.param) ;
                case 'dropout'

                  if disableDropout
                    output_info.x = input_info.x ;
                  else
                    [output_info.x, output_info.aux] = vl_nndropout(input_info.x, 'rate', l.rate) ;
                  end

                otherwise
                    error('Unknown layer type %s', l.type) ;
            end
        else

            output_info= l.forward_fn(input_info, l, work_info_batch) ;

        end

        if isempty(output_info)
            break;
        end
        output_info.forward_finished=true;

    if ~keep_layer_output && layer_idx < layer_num - 1
      data_info.ref.output_info_layers{layer_idx}=[];
      input_info=[];
    end

    if gpu_mode
        if ~net_info.ref.data_stay_on_gpu
            if ~isempty(input_info)
                input_info=move_output_info_cpu(input_info);
                data_info.ref.output_info_layers{layer_idx}=input_info;
            end
        end
    end

    if gpu_mode && net_run_config.sync
        wait(gpuDevice) ;
    end

    data_info.ref.output_info_layers{layer_idx+1}=output_info;

    if extra_output_layer_flags(layer_idx)
        extra_output_layers{layer_idx}=output_info;
    end

end

if gpu_mode && ~net_info.ref.data_stay_on_gpu
    output_info=data_info.ref.output_info_layers{end};
    output_info=move_output_info_cpu(output_info);
    data_info.ref.output_info_layers{end}=output_info;
end

extra_data_info=[];
extra_data_info.output_layers=extra_output_layers;

end