spm_vb_Fn.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. function [F,L,KL] = spm_vb_Fn(Y,block)
  2. % Compute voxel-wise contributions to model evidence
  3. % FORMAT [F,L,KL] = spm_vb_Fn(Y,block)
  4. %
  5. % Y - [T x N] time series
  6. % block - data structure (see spm_vb_glmar)
  7. %
  8. % F - [N x 1] vector where nth entry is unique contribution to
  9. % model evidence from voxel n
  10. % L - [N x 1] Average Likelihood
  11. % KL.w - [N x 1] KL w - unique contribution
  12. % KL.a - [N x 1] KL a - unique contribution
  13. % KL.lam - [N x 1] KL Lambda
  14. % KL.alpha - Scalar
  15. % KL.beta - Scalar
  16. %__________________________________________________________________________
  17. % Copyright (C) 2005-2014 Wellcome Trust Centre for Neuroimaging
  18. % Will Penny
  19. % $Id: spm_vb_Fn.m 6079 2014-06-30 18:25:37Z spm $
  20. T = block.T;
  21. p = block.p;
  22. k = block.k;
  23. N = block.N;
  24. X = block.X;
  25. C2 = block.C2;
  26. Bk = kron(diag(block.mean_alpha),block.Dw);
  27. B = block.Hw*Bk*block.Hw';
  28. if p>0
  29. if ~strcmp(block.priors.A,'Discrete')
  30. Jk = kron(diag(block.mean_beta),block.Da);
  31. J = block.Ha*Jk*block.Ha';
  32. end
  33. end
  34. %-Get KL-alpha
  35. %--------------------------------------------------------------------------
  36. KL.alpha = 0;
  37. for j=1:k
  38. KL.alpha = KL.alpha + spm_kl_gamma(block.b_alpha(j),block.c_alpha(j),block.b_alpha_prior(j),block.c_alpha_prior(j));
  39. end
  40. % Get KL-beta
  41. %--------------------------------------------------------------------------
  42. KL.beta = 0;
  43. if p > 0
  44. if strcmp(block.priors.A,'Discrete')
  45. for j=1:p
  46. for s=1:block.priors.S
  47. KL.beta = KL.beta + spm_kl_gamma(block.b_beta(j,s),block.c_beta(j,s),block.b_beta_prior(j,s),block.c_beta_prior(j,s));
  48. end
  49. end
  50. else
  51. for j = 1:p
  52. KL.beta = KL.beta + spm_kl_gamma(block.b_beta(j),block.c_beta(j),block.b_beta_prior(j),block.c_beta_prior(j));
  53. end
  54. end
  55. end
  56. % Get average Likelihood, KL-Lambda and terms for KL-w, KL-a
  57. %--------------------------------------------------------------------------
  58. for n=1:N
  59. subblock_n = [(n-1)*k+1:n*k];
  60. if p>0
  61. Gn = spm_vb_get_Gn(Y,block,n);
  62. else
  63. wc = block.w_cov{n};
  64. en = (Y(:,n)-X*block.w_mean(subblock_n,1));
  65. Gn = trace(wc*block.XTX)+en'*en;
  66. end
  67. L(n) = -0.5*block.mean_lambda(n)*Gn;
  68. L(n) = L(n) + 0.5*(T-p)*(psi(block.c_lambda(n)) + log(block.b_lambda(n)));
  69. L(n) = L(n)-0.5*block.C2/N;
  70. KL.lam(n) = spm_kl_gamma(block.b_lambda(n),block.c_lambda(n),block.b_lambda_prior(n),block.c_lambda_prior(n));
  71. KL_w1 = -0.5*sum(log(block.mean_alpha))-0.5*log(det(block.w_cov{n}));
  72. KL_w1 = KL_w1-0.5*k*block.log_det_Dw/N;
  73. KL_w2 = 0.5*trace(B(subblock_n,subblock_n)*block.w_cov{n});
  74. subblock_ni = [1:N*k];
  75. subblock_ni(subblock_n) = [];
  76. Bnn = B(subblock_n,subblock_n);
  77. Bni = B(subblock_n,subblock_ni);
  78. Bin = B(subblock_ni,subblock_n);
  79. w_mean = block.w_mean(subblock_n,1);
  80. KL_w3 = 0.5*w_mean'*Bnn*w_mean+0.5*w_mean'*Bni*block.w_mean(subblock_ni,1);
  81. KL_w3 = KL_w3-0.5*k;
  82. KL.w(n) = KL_w1+KL_w2+KL_w3;
  83. if p>0
  84. asubblock_n = [(n-1)*p+1:n*p];
  85. a_mean = block.a_mean(asubblock_n,1);
  86. if strcmp(block.priors.A,'Discrete')
  87. ibeta_n = diag(block.priors.gamma(n,:)*(1./block.mean_beta'));
  88. a_n = block.priors.gamma(n,:)*block.as';
  89. KL.a(n) = spm_kl_normal(a_mean,block.a_cov{n},a_n,ibeta_n);
  90. % a_mean
  91. % sqrt(block.a_cov{n})
  92. % a_n
  93. % sqrt(ibeta_n)
  94. else
  95. asubblock_ni = [1:N*p];
  96. asubblock_ni(asubblock_n) = [];
  97. Jnn = J(asubblock_n,asubblock_n);
  98. Jni = J(asubblock_n,asubblock_ni);
  99. KL_a1 = -0.5*sum(log(block.mean_beta)) - 0.5*log(det(block.a_cov{n}));
  100. KL_a1 = KL_a1-0.5*p*block.log_det_Da/N;
  101. KL_a2 = 0.5*trace(Jnn*block.a_cov{n});
  102. KL_a3 = 0.5*a_mean'*Jnn*a_mean+0.5*a_mean'*Jni*block.a_mean(asubblock_ni,1);
  103. KL_a3 = KL_a3-0.5*p;
  104. KL.a(n) = KL_a1 + KL_a2 + KL_a3;
  105. end
  106. else
  107. KL.a(n) = 0;
  108. end
  109. end
  110. F = L -KL.w -KL.lam -KL.a -KL.alpha/N -KL.beta/N;