-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWidefield_crossValModel.m
117 lines (94 loc) · 3.63 KB
/
Widefield_crossValModel.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function [trialRsq, totalRsq, timeRsq, corrMap, corrMovie, Vm] = Widefield_crossValModel(Vc,fullR,U,ridgeFolds,frames, useGPU, makeMovie,randSampling)
if ~exist('useGPU','var')
useGPU = false; %flag to use GPU
end
if ~exist('makeMovie','var')
makeMovie = false; %flag to produce correlation movie
end
if ~exist('randSampling','var')
randSampling = false; %flag to use a random instead of linear index for cross-validation
end
%% run cross-validation
if randSampling
rng default %reset randum number generator
randIdx = randperm(size(Vc,2)); %generate randum number index if required
end
Vm = zeros(size(Vc),'single');
foldCnt = floor(size(Vc,2) / ridgeFolds);
tic
for iFolds = 1:ridgeFolds
tic
dataIdx = true(1,size(Vc,2));
if ridgeFolds > 1
if randSampling
dataIdx(randIdx(((iFolds - 1)*foldCnt) + (1:foldCnt))) = false; %index for training data
else
dataIdx(((iFolds - 1)*foldCnt) + (1:foldCnt)) = false; %index for training data
end
Y = Vc(:,dataIdx)';
Y = bsxfun(@minus,Y,mean(Y));
X = fullR(dataIdx,:);
Xm = fullR(~dataIdx,:);
X = bsxfun(@minus,X,mean(X));
Xm = bsxfun(@minus,Xm,mean(X));
[~, betas] = ridgeMML(Y, X); %get beta weights for current model
Vm(:,~dataIdx) = (Xm * betas)'; %predict remaining data
if rem(iFolds,ridgeFolds/5) == 0
fprintf(1, 'Current fold is %d out of %d\n', iFolds,ridgeFolds);
toc
end
else
Vc = bsxfun(@minus,Vc,mean(Vc));
fullR = bsxfun(@minus,fullR,mean(fullR));
[~, betas] = ridgeMML(Vc', fullR); %get beta weights for current model
Vm = (fullR * betas)'; %predict remaining data
disp('Ridgefold is <= 1, fit to complete dataset');
end
end
Vc = reshape(Vc,size(Vc,1),frames,[]);
Vm = reshape(Vm,size(Vm,1),frames,[]);
cError = (Vc-Vm).^2;
totalRsq = 1 - (mean(cError(:)) ./ var(Vc(:))); %total mean R^2
trialRsq = squeeze(1 - (mean(mean(cError),2) ./ mean(var(Vc,[],2),1))); %mean R^2 per trial
timeRsq = 1 - (squeeze(mean(mean(cError,3),1) ./ mean(var(Vc,[],3),1))); %mean R^2 per frame / trial
%% compute correlation between data and prediction over for all frames
if useGPU
Vc = gpuArray(Vc);
Vm = gpuArray(Vm);
U = gpuArray(U);
end
tic
Vc = reshape(Vc,size(Vc,1),[]);
Vm = reshape(Vm,size(Vm,1),[]);
covVc = cov(Vc'); % S x S
covVm = cov(Vm'); % S x S
cCovV = bsxfun(@minus, Vm, mean(Vm,2)) * Vc' / (size(Vc, 2) - 1); % S x S
covP = sum((U * cCovV) .* U, 2)'; % 1 x P
varP1 = sum((U * covVc) .* U, 2)'; % 1 x P
varP2 = sum((U * covVm) .* U, 2)'; % 1 x P
stdPxPy = varP1 .^ 0.5 .* varP2 .^ 0.5; % 1 x P
corrMap = gather((covP ./ stdPxPy)');
toc
if makeMovie
for iFrames = 1:frames
idx = iFrames:frames:size(Vc,2); %index for frame with lowest prediction error in each trial
tic
covVc = cov(Vc(:,idx)'); % S x S
covVm = cov(Vm(:,idx)'); % S x S
cCovV = bsxfun(@minus, Vm(:,idx), mean(Vm(:,idx),2)) * Vc(:,idx)' / (length(idx) - 1); % S x S
covP = sum((U * cCovV) .* U, 2)'; % 1 x P
varP1 = sum((U * covVc) .* U, 2)'; % 1 x P
varP2 = sum((U * covVm) .* U, 2)'; % 1 x P
stdPxPy = varP1 .^ 0.5 .* varP2 .^ 0.5; % 1 x P
corrMovie(:,iFrames) = (covP ./ stdPxPy)';
if rem(iFrames,frames/20) == 0
fprintf(1, 'Current frame is %d out of %d\n', iFrames,frames);
toc
end
end
corrMovie = gather(corrMovie);
else
corrMovie = corrMap;
end
fprintf('Run finished. RMSE: %f\n', mean(totalRsq));
end