-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshift.m
135 lines (110 loc) · 3.83 KB
/
shift.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
% shift.m
%
% usage: shift()
% by: justin gardner
% date: 04/25/17
% purpose:
%
function retval = shift()
% compute filters over the following x
x = d2r(0:0.1:180);
% desired stimulus value
stimVal1 = d2r(90);
[~,stimIndex1] = min(abs(x - stimVal1));
% actual stimulus value
stimVal2 = d2r(78);
[~,stimIndex2] = min(abs(x - stimVal2));
% basis filters for original and desired shift
exponent = 7;
[fun filterPref] = makeFilters(x,exponent,0);
nFilters = length(filterPref);
% compute response to stimulus
funResponse1 = fun(stimIndex1,:);
funResponseScaled1 = fun.*repmat(funResponse1,length(x),1);
funResponse2 = fun(stimIndex2,:);
funResponseScaled2 = fun.*repmat(funResponse2,length(x),1);
% where to recenter the response
recenterPos = stimVal1;
% make the preference difference matrix which is the difference in prefered filter preference
% from the desired position
prefDiffMatrix = mod(repmat(filterPref',1,nFilters) - repmat(filterPref,nFilters,1)-(stimVal1-stimVal2),pi);
prefDiffMatrix(prefDiffMatrix>pi/2) = pi-prefDiffMatrix(prefDiffMatrix>pi/2);
% compute a weight matrix which gives the linear weights to the two
% nearest neighbor filters. (e.g. should be 0.5 and 0.5 if the new
% location is inbetween the two).
filterSpacing = median(diff(filterPref));
weightMatrix = 1 - abs(prefDiffMatrix)/filterSpacing;
weightMatrix(abs(prefDiffMatrix)>=filterSpacing) = 0;
% now get the expected filter response for the original location
% and the shifted location
shiftedFilterResponse = interp1(x,fun,recenterPos);
originalFilterResponse = interp1(x,fun,stimVal2);
% the ratio is then the expectation for how the new locations response
% should depend on the original response
interpMatrix = repmat(shiftedFilterResponse,nFilters,1) ./ repmat(originalFilterResponse',1,nFilters);
% this interpation blows up whenever the filter vaules go to zero, so take those out
weightMatrix(isinf(interpMatrix)) = 0;
weightMatrix(isnan(interpMatrix)) = 0;
interpMatrix(isnan(interpMatrix)) = 0;
interpMatrix(isinf(interpMatrix)) = 0;
% this may take out some values that should have been weighted, so need to
% fix that so that the weights all sum to 1 in each column
sumOfWeights = sum(weightMatrix);
sumOfWeights(sumOfWeights==0) = 1;
weightMatrix = weightMatrix * 1./repmat(sumOfWeights,nFilters,1);
% the shift matrix is now just the linear weights of neigbors
% by how much each shoudl be scaled by
shiftMatrix = weightMatrix.*interpMatrix
% display
mlrSmartfig('shifttest','reuse');clf;
% display dimensions
xMax = 180;
yMin = 0;yMax = 1;
% the response we are trying to recreate
subplot(3,1,1);
plot(r2d(x),funResponseScaled1);hold on
yaxis(yMin,yMax);
vline(r2d(stimVal1));
title('Desired interpolation');
% the response we got for the stimulus
subplot(3,1,2);
plot(r2d(x),funResponseScaled2);
hold on
yaxis(yMin,yMax);
vline(r2d(stimVal2));
title('New stimulus');
ylabel('Filter response');
% the interpolated response
subplot(3,1,3);
plot(r2d(x),fun.*repmat(funResponse2*shiftMatrix,length(x),1));
yaxis(yMin,yMax);
title('Interpolated response');
xlabel('Orientation');
keyboard
%%%%%%%%%%%%%%%%%%%%%
% makeFilters %
%%%%%%%%%%%%%%%%%%%%%
function [fun filterPref] = makeFilters(x,exponent,phaseShift)
fun = [];
phaseVals = (0:2*pi/((exponent+1)):(2*pi-0.001))+phaseShift;
for iPhase = 1:length(phaseVals)
% cos function
fun(:,iPhase) = cos(2*x-phaseVals(iPhase));
% rectify
fun(fun(:,iPhase)<0,iPhase) = 0;
% exponent
fun(:,iPhase) = fun(:,iPhase).^exponent;
end
filterPref = phaseVals/2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% makeFiltersNonRect %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fun = makeFiltersNonRect(x,exponent,phaseShift)
fun = [];
phaseVals = (0:pi/(exponent+1):(pi-0.001))+phaseShift;
for iPhase = 1:length(phaseVals)
% cos function
fun(:,iPhase) = cos(x+phaseVals(iPhase));
% exponent
fun(:,iPhase) = fun(:,iPhase).^exponent;
end