
% Odelia Schwartz
% simple examples with binding

dVectors = 1000;
shape = random('norm',0,sqrt(1/dVectors),1,dVectors);
square = random('norm',0,sqrt(1/dVectors),1,dVectors);
circle = random('norm',0,sqrt(1/dVectors),1,dVectors);

% Bind shape to circle in a vector called convshape
% Circular convolution is used for binding.
% We can think of this as holding a circle shape in memory (encoding)
nn = 50;
convshape = cconv_fft(shape,circle);

% Note that the circular convolution retains the same size
size(circle)
size(shape)
size(convshape)

% From bound vector convshape find what was bound to shape to obtain it
% This is the inverse operation that gives back a noisy circle.
% We will call this vector findshape. This is like decoding or 
% retrieving from memory.
findshape = ccorr_fft(convshape,shape);

% Let's compare the original circle to the decoded findshape
figure(1)
plot(circle(1:nn))
hold on;
plot(findshape(1:nn),'r')
legend('circle', 'decoded shape')

% Let's compare the square to the decoded findshape
figure(2)
plot(square(1:nn))
hold on;
plot(findshape(1:nn),'r')
hold off
legend('square', 'decoded shape')

% Is the decoded findshape more similar to the square or to the circle?
% We can take the inner product: Which is higher?
square*findshape'
circle*findshape'
% Note: This assumes we have the clean "circle" and "square"
% in memory and we want to compare each to the stored memory
% and use some metric - such as inner product or correlation - to compare.

% An equivalent way of undoing the convolution, which is what they use in
% the Raven's task code
shapeinv = [shape(1) fliplr(shape(2:end))];
findshape2 = cconv_fft(convshape,shapeinv);
% both of these undo the circular convolution
square*findshape2'
circle*findshape2'

% We can also bind a number together with the shape in "memory"
% For instance we want to hold "in memory" number one
number = random('norm',0,sqrt(1/dVectors),1,dVectors);
one = random('norm',0,sqrt(1/dVectors),1,dVectors);
convnumber = cconv_fft(number,one);

% We want this together with the circle shape we computed earlier
% (as if holding one circle in memory)
% We use summation of the convolutions
convsum = convshape + convnumber;

% From this sum, we again want to find what the shape was - square or circle
findshape_fromsum = ccorr_fft(convsum, shape);
figure(3)
plot(circle(1:nn))
hold on;
plot(findshape_fromsum(1:nn),'r')
hold off
legend('circle', 'decoded shape from sum')
square*findshape_fromsum'
circle*findshape_fromsum'

% The two decoded shapes are similar, whether we just convolved circle with
% shape, or if we summed to together the circle and the one convolutions
figure(4);
plot(findshape(1:nn),'r');
hold on;
plot(findshape_fromsum(1:nn),'m')
hold off

% We could also retrieve the number and compare it to "one"
findnumber_fromsum = ccorr_fft(convsum, number);
one*findnumber_fromsum'

