clear all
close all

N = 100;
M = 500;

epochs = 1000;
k1 = 1;
k2 = 1;
r1 = 0.001;
r2 = 0.001;

counter = zeros(1,15);
period = 1;

for T = 10
    
    for trial = 1:1
    
        U = 0.001*randn(M,N);
        V = 0.001*randn(N,M);
        
        rep = 1;
    
        while (rep == 1)
            X = sign(randn(N,T));
            rep = 0;
            for i = 1:T
                for j = i+1:T
                    if sum(abs(X(:,i) - X(:,j))) == 0
                        rep = 1;
                    end
                end
            end
        end
    
        W = randn(M,N);
    
        err_u = zeros(1,epochs);
        err_v = zeros(1,epochs);
        
        for e = 1:epochs
            
            err = 0;
            for t = 1:T
        
                x1 = X(:,t);
        
                if t == T
                    x2 = X(:,1);
                else
                    x2 = X(:,t+1);             
                end
                    
                z = sign(W*x2);
                u = threshold(k1 - z .* (U*x1));
                U = U + r1 * (u.*z) * (x1)';
        
                y = sign(U*x1);
                v = threshold(k2 - x2 .* (V*y));
                V = V + r2 * (v.*x2)*    y';
    
                err_u(e) = err_u(e) + mean(u);
                err_v(e) = err_v(e) + mean(v);
        
                err = err + sum(abs(x2 - sign((V*sign(U*x1)))));
            end   
        end
        
        Y = zeros(N,5*T);
        Z = zeros(N,5*T);
        Y(:,1) = X(:,1);
        Z(:,1) = X(:,1);
    
        rp = randperm(N);
        for i = 1:10
            Y(rp(i),1) = -Y(rp(i),1);
        end
    
        for t = 1:5*T-1
            Y(:,t+1) = sign(V*sign(U*Y(:,t)));
            Z(:,t+1) = X(:,mod(t,T)+1);
        end
    
        match = 0;
        for i = 1:4*T
            if sum(sum(abs(X - Y(:,i+1:i+T)))) == 0
                match = 1;
                break;
            end        
        end
        
        counter(period) = counter(period) + match;
    
        disp(sprintf('%d %d %d', T, trial, counter(period)));
    end

    period = period + 1;
end

% h5create('random_seq_hist_one.h5', '/counter', size(counter));
% h5write('random_seq_hist_one.h5', '/counter', counter);


figure('Position',[100 100 1200 600]);
colormap(gray)
s = [N 5*T];
xrange = [1 5*T];
yrange = [1 N];

dx = diff(xrange)/(s(2)-1);
dy = diff(yrange)/(s(1)-1);
xg = linspace(xrange(1)-dx/2,xrange(2)+dx/2,s(2)+1);
yg = linspace(yrange(1)-dy/2,yrange(2)+dy/2,s(1)+1);
subplot(2,1,1),hi = imagesc(xrange,yrange,Z); hold on

hm = mesh(xg,yg,zeros(s+1));
hm.FaceColor = 'none';
hm.EdgeColor = 'k';
axis off;
axis equal;

subplot(2,1,2),hi = imagesc(xrange,yrange,Y); hold on
hm = mesh(xg,yg,zeros(s+1));
hm.FaceColor = 'none';
hm.EdgeColor = 'k';
axis off;
axis equal;

figure('Position',[100 100 1200 600]);
colormap(gray)
s = [20 5*T];
xrange = [1 5*T];
yrange = [1 20];

dx = diff(xrange)/(s(2)-1);
dy = diff(yrange)/(s(1)-1);
xg = linspace(xrange(1)-dx/2,xrange(2)+dx/2,s(2)+1);
yg = linspace(yrange(1)-dy/2,yrange(2)+dy/2,s(1)+1);
hi = imagesc(xrange,yrange,Z(1:20,:)); hold on
axis equal;
axis off;

ylabel('$\mathbf{x}(t)$', 'FontSize', 40, ...
       'interpreter','latex','Rotation',0, ...
       'VerticalAlignment','middle','HorizontalAlignment','right');
xlabel('$t$','FontSize', 40,'interpreter','latex',...
        'VerticalAlignment','bottom','HorizontalAlignment','center');
ax = gca;
ax.XLabel.Visible = 'on';
ax.YLabel.Visible = 'on';
set(gca,'LooseInset',get(gca,'TightInset'))

figure('Position',[100 100 1200 600]);
colormap(gray)
s = [20 5*T];
xrange = [1 5*T];
yrange = [1 20];

dx = diff(xrange)/(s(2)-1);
dy = diff(yrange)/(s(1)-1);
xg = linspace(xrange(1)-dx/2,xrange(2)+dx/2,s(2)+1);
yg = linspace(yrange(1)-dy/2,yrange(2)+dy/2,s(1)+1);
hi = imagesc(xrange,yrange,Y(1:20,:)); hold on
axis equal;
axis off;

ylabel('{\boldmath$\xi$}$(t)$', 'FontSize', 40, ...
       'interpreter','latex','Rotation',0, ...
       'VerticalAlignment','middle','HorizontalAlignment','right');
xlabel('$t$','FontSize', 40,'interpreter','latex',...
        'VerticalAlignment','bottom','HorizontalAlignment','center');
ax = gca;
ax.XLabel.Visible = 'on';
ax.YLabel.Visible = 'on';
set(gca,'LooseInset',get(gca,'TightInset'))
% 
% axis off;
% export_fig -pdf fig_random_one.pdf

% export_fig -pdf -transparent fig_random_gt.pdf