├── CODE FOR FIGURE 2 ├── IZFORCESINE.m ├── LIFFORCESINE.m ├── THETAFORCESAWTOOTH.m ├── THETAFORCESINE.m ├── THETAFORCEVDPHARMONIC.m ├── THETAFORCEVDPRELAX.m ├── THETALORENZ.m ├── THETANOISYPRODSINES.m ├── THETAPRODSINES.m ├── lorenz.m └── vanderpol.m ├── CODE FOR FIGURE 3 (ODE TO JOY) ├── IZFORCESONG.m ├── SONGGENERATOR.m └── ode2joyshort.mat ├── CODE FOR FIGURE 4 (USER SUPPLIED SUPERVISOR) └── IZSONGBIRDFORCE.m ├── CODE FOR FIGURE 5 (USER SUPPLIED SUPERVISOR) └── IZFORCEMOVIE.m ├── CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12 ├── IZFORCECLASSIFICATION.m ├── NETWORKSIM.m ├── WEIGHTCLASSLINEAR.mat ├── lineardata.mat ├── nonlineardata.mat └── testsetlinear.mat ├── CODE FOR SUPPLEMENTARY ODE TO JOY EXAMPLE ├── IZFORCESONG.m └── ode2joylong.mat ├── CODE FOR SUPPLEMENTARY OSCILLATOR PANEL ├── IZHIKEVICH 20 │ ├── IZFORCECOMPLEXOSCILLATOR1.m │ ├── IZFORCECOMPLEXOSCILLATOR2.m │ ├── IZFORCEPRODSINE.m │ ├── IZFORCEPRODSINENOISE.m │ ├── IZFORCESAWTOOTH.m │ ├── IZFORCESINE.m │ ├── IZFORCEVDPHARDMONIC.m │ ├── IZFORCEVDPRELAX.m │ └── vanderpol.m ├── LIF MODEL 10 │ ├── LIFFORCEPRODSINE.m │ └── LIFFORCEPRODSINENOISE.m ├── LIF MODEL 20 │ ├── LIFFORCEPRODSINE.m │ ├── LIFFORCEPRODSINENOISE.m │ ├── LIFFORCESAWTOOTH.m │ ├── LIFFORCESINE.m │ ├── LIFFORCEVDPHARMONIC.m │ ├── LIFFORCEVDPRELAXATION.m │ └── vanderpol.m ├── LIF MODEL 30 │ ├── LIFFORCEPRODSINE.m │ ├── LIFFORCEPRODSINENOISE.m │ ├── LIFFORCESAWTOOTH.m │ ├── LIFFORCESINE.m │ ├── LIFFORCEVDPHARMONIC.m │ ├── LIFFORCEVDPRELAXATION.m │ └── vanderpol.m ├── THETA MODEL 20 │ ├── THETANOISYPRODSINES.m │ └── THETAPRODSINES.m └── THETA MODEL 50 │ ├── THETAFORCEPRODSINE.m │ ├── THETAFORCEPRODSINENOISE.m │ ├── THETAFORCESAWTOOTH.m │ ├── THETAFORCESINE.m │ ├── THETAFORCEVDPHARMONIC.m │ ├── THETAFORCEVDPRELAX.m │ └── vanderpol.m └── readme.txt /CODE FOR FIGURE 2/IZFORCESINE.m: -------------------------------------------------------------------------------- 1 | %% Force Method with Izhikevich Network 2 | clear all 3 | close all 4 | clc 5 | 6 | T = 15000; %Total time in ms 7 | dt = 0.04; %Integration time step in ms 8 | nt = round(T/dt); %Time steps 9 | N = 2000; %Number of neurons 10 | %% Izhikevich Parameters 11 | C = 250; %capacitance 12 | vr = -60; %resting membrane 13 | b = -2; %resonance parameter 14 | ff = 2.5; %k parameter for Izhikevich, gain on v 15 | vpeak = 30; % peak voltage 16 | vreset = -65; % reset voltage 17 | vt = vr+40-(b/ff); %threshold %threshold 18 | u = zeros(N,1); %initialize adaptation 19 | a = 0.01; %adaptation reciprocal time constant 20 | d = 200; %adaptation jump current 21 | tr = 2; %synaptic rise time 22 | td = 20; %decay time 23 | p = 0.1; %sparsity 24 | G =5*10^3; %Gain on the static matrix with 1/sqrt(N) scaling weights. Note that the units of this have to be in pA. 25 | Q =5*10^3; %Gain on the rank-k perturbation modified by RLS. Note that the units of this have to be in pA 26 | Irh = 0.25*ff*(vt-vr)^2; 27 | 28 | %Storage variables for synapse integration 29 | IPSC = zeros(N,1); %post synaptic current 30 | h = zeros(N,1); 31 | r = zeros(N,1); 32 | hr = zeros(N,1); 33 | JD = zeros(N,1); 34 | 35 | %-----Initialization--------------------------------------------- 36 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 37 | v_ = v; %These are just used for Euler integration, previous time step storage 38 | rng(1) 39 | %% Target signal COMMENT OUT TEACHER YOU DONT WANT, COMMENT IN TEACHER YOU WANT. 40 | zx = (sin(2*5*pi*(1:1:nt)*dt/1000)); 41 | 42 | %% 43 | k = min(size(zx)); %used to get the dimensionality of the approximant correctly. Typically will be 1 unless you specify a k-dimensional target function. 44 | 45 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 73 | if length(index)>0 74 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 75 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %uncomment this 76 | %if you want to store spike times. Takes longer. 77 | ns = ns + length(index); 78 | end 79 | 80 | %synapse for single exponential 81 | if tr == 0 82 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 83 | r = r *exp(-dt/td) + (v>=vpeak)/td; 84 | else 85 | 86 | %synapse for double exponential 87 | IPSC = IPSC*exp(-dt/tr) + h*dt; 88 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 89 | 90 | r = r*exp(-dt/tr) + hr*dt; 91 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 92 | end 93 | 94 | 95 | z = BPhi'*r; %approximant 96 | err = z - zx(:,i); %error 97 | %% RLS 98 | if mod(i,step)==1 99 | if i > imin 100 | if i < icrit 101 | cd = Pinv*r; 102 | BPhi = BPhi - (cd*err'); 103 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 104 | end 105 | end 106 | end 107 | 108 | 109 | 110 | 111 | %% Store, and plot. 112 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 113 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 114 | v_ = v; % sets v(t-1) = v for the next itteration of loop 115 | REC(i,:) = [v(1:5)',u(1:5)']; 116 | current(i,:) = z'; 117 | RECB(i,:)=BPhi(1:5); 118 | 119 | 120 | if mod(i,round(100/dt))==1 121 | drawnow 122 | gg = max(1,i - round(3000/dt)); %only plot for last 3 seconds 123 | figure(2) 124 | plot(dt*(gg:1:i)/1000,zx(:,gg:1:i),'k','LineWidth',2), hold on 125 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:),'b--','LineWidth',2), hold off 126 | xlabel('Time (s)') 127 | ylabel('$\hat{x}(t)$','Interpreter','LaTeX') 128 | legend('Approximant','Target Signal') 129 | xlim([dt*i-3000,dt*i]/1000) 130 | figure(3) 131 | plot((1:1:i)*dt/1000,RECB(1:1:i,:)) 132 | figure(14) 133 | plot(tspike(1:ns,2),tspike(1:ns,1),'k.') 134 | ylim([0,100]) 135 | end 136 | 137 | end 138 | %% 139 | tspike = tspike(tspike(:,2)~=0,:); 140 | M = tspike(tspike(:,2)>dt*icrit); 141 | AverageFiringRate = 1000*length(M)/(N*(T-dt*icrit)) 142 | %% Plotting neurons before and after learning 143 | figure(30) 144 | for j = 1:1:5 145 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 146 | end 147 | xlim([T/1000-2,T/1000]) 148 | xlabel('Time (s)') 149 | ylabel('Neuron Index') 150 | title('Post Learning') 151 | figure(31) 152 | for j = 1:1:5 153 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 154 | end 155 | xlim([0,imin*dt/1000]) 156 | xlabel('Time (s)') 157 | ylabel('Neuron Index') 158 | title('Pre-Learning') 159 | figure(40) 160 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 161 | Z2 = eig(OMEGA); %eigenvalues before learning 162 | %% 163 | plot(Z2,'r.'), hold on 164 | plot(Z,'k.') 165 | legend('Pre-Learning','Post-Learning') 166 | xlabel('Re \lambda') 167 | ylabel('Im \lambda') 168 | 169 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/LIFFORCESINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | rng(1); 12 | td = 0.02; tr = 0.002; 13 | %% 14 | 15 | alpha = dt*0.1 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 16 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLMS 17 | p = 0.1; %Set the network sparsity 18 | 19 | %% Target Dynamics for Product of Sine Waves 20 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 10; G = 0.04; 21 | zx = (sin(2*pi*(1:1:nt)*dt*5)); 22 | 23 | 24 | 25 | %% 26 | k = min(size(zx)); 27 | IPSC = zeros(N,1); %post synaptic current storage variable 28 | h = zeros(N,1); %Storage variable for filtered firing rates 29 | r = zeros(N,1); %second storage variable for filtered rates 30 | hr = zeros(N,1); %Third variable for filtered rates 31 | JD = 0*IPSC; %storage variable required for each spike time 32 | tspike = zeros(4*nt,2); %Storage variable for spike times 33 | ns = 0; %Number of spikes, counts during simulation 34 | z = zeros(k,1); %Initialize the approximant 35 | 36 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 37 | v_ = v; %v_ is the voltage at previous time steps 38 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 39 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 45 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 46 | end 47 | 48 | 49 | E = (2*rand(N,k)-1)*Q; %n 50 | REC2 = zeros(nt,20); 51 | REC = zeros(nt,10); 52 | current = zeros(nt,k); %storage variable for output current/approximant 53 | i = 1; 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | tlast = zeros(N,1); %This vector is used to set the refractory times 70 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 71 | %% 72 | ilast = i; 73 | %icrit = ilast; 74 | for i = ilast:1:nt 75 | 76 | 77 | I = IPSC + E*z + BIAS; %Neuronal Current 78 | 79 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 80 | v = v + dt*(dv); 81 | 82 | index = find(v>=vpeak); %Find the neurons that have spiked 83 | 84 | 85 | %Store spike times, and get the weight matrix column sum of spikers 86 | if length(index)>0 87 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 88 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 89 | ns = ns + length(index); % total number of psikes so far 90 | end 91 | 92 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 93 | 94 | % Code if the rise time is 0, and if the rise time is positive 95 | if tr == 0 96 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 97 | r = r *exp(-dt/td) + (v>=vpeak)/td; 98 | else 99 | IPSC = IPSC*exp(-dt/tr) + h*dt; 100 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 101 | 102 | r = r*exp(-dt/tr) + hr*dt; 103 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 104 | end 105 | 106 | 107 | 108 | %Implement RLMS with the FORCE method 109 | z = BPhi'*r; %approximant 110 | err = z - zx(:,i); %error 111 | %% RLMS 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | v = v + (30 - v).*(v>=vpeak); 123 | 124 | REC(i,:) = v(1:10); %Record a random voltage 125 | 126 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 127 | current(i,:) = z; 128 | RECB(i,:) = BPhi(1:10); 129 | REC2(i,:) = r(1:20); 130 | 131 | 132 | 133 | if mod(i,round(0.5/dt))==1 134 | drawnow 135 | figure(1) 136 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 137 | xlim([dt*i-5,dt*i]) 138 | ylim([0,200]) 139 | figure(2) 140 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 141 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 142 | 143 | xlim([dt*i-5,dt*i]) 144 | %ylim([-0.5,0.5]) 145 | 146 | %xlim([dt*i,dt*i]) 147 | figure(5) 148 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 149 | end 150 | end 151 | time = 1:1:nt; 152 | %% 153 | TotNumSpikes = ns 154 | %tspike = tspike(1:1:ns,:); 155 | M = tspike(tspike(:,2)>dt*icrit,:); 156 | AverageRate = length(M)/(N*(T-dt*icrit)) 157 | 158 | %% Plot neurons pre- amd post- learning 159 | figure(30) 160 | for j = 1:1:5 161 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 162 | end 163 | xlim([T-2,T]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(31) 168 | for j = 1:1:5 169 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 170 | end 171 | xlim([0,2]) 172 | xlabel('Time (s)') 173 | ylabel('Neuron Index') 174 | title('Pre-Learning') 175 | %% 176 | Z = eig(OMEGA+E*BPhi'); %eigenvalues post learning 177 | Z2 = eig(OMEGA); %eigenvalues pre learning 178 | %% Plot eigenvalues 179 | figure(40) 180 | plot(Z2,'r.'), hold on 181 | plot(Z,'k.') 182 | legend('Pre-Learning','Post-Learning') 183 | xlabel('Re \lambda') 184 | ylabel('Im \lambda') 185 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETAFORCESAWTOOTH.m: -------------------------------------------------------------------------------- 1 | closclear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; tmin = 5; tcrit = 10; nt = round(T/dt); tx = (1:1:nt)*dt; xz = asin(sin(2*tx*pi*5))'; G = 10; Q = 10^4; 12 | 13 | %% 14 | m = min(size(xz)); %dimensionality of teacher 15 | E = Q*(2*rand(N,m)-1); %encoders 16 | BPhi = zeros(N,m); %Decoders 17 | %% Compute Neuronal Intercepts and Tuning Curves 18 | initial = 0; 19 | p = 0.1; %Sparse Coupling 20 | OMEGA = G*randn(N,N).*(rand(N,N)0); 26 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 27 | end 28 | 29 | %% Storage Matrices and Initialization 30 | store = 10; %don't store every time step, saves time. 31 | current = zeros(nt,m); %storage variable for output current 32 | IPSC = zeros(N,1); %post synaptic current 33 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 34 | JD = 0*IPSC; 35 | 36 | vpeak = pi; %peak and reset 37 | vreset = -pi; 38 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 39 | v_ = v; %temporary storage variable for integration 40 | 41 | j = 1; 42 | time = zeros(round(nt/store),1); 43 | RECB = zeros(5,round(2*round(nt/store))); 44 | REC = zeros(10,round(nt/store)); 45 | tspike = zeros(8*nt,2); 46 | ns = 0; 47 | tic 48 | SD = 0; 49 | BPhi = zeros(N,m); 50 | z = zeros(m,1); 51 | step = 50; %Sets the frequency of RLS 52 | imin = round(tmin/dt); %Start RLS 53 | icrit = round((tcrit/dt)); %Stop RLS 54 | 55 | Pinv = eye(N)*dt; 56 | i = 1; 57 | %% 58 | ilast = i; 59 | %icrit = ilast; 60 | for i = ilast :1:nt 61 | JX = IPSC + E*z; %current 62 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 63 | v = v_ + dt*(dv); %Euler integration plus refractory period. 64 | index = find(v>=vpeak); 65 | if length(index)>0 66 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 67 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 68 | ns = ns + length(index); 69 | end 70 | 71 | 72 | 73 | if tr == 0 74 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 75 | r = r *exp(-dt/td) + (v>=vpeak)/td; 76 | else 77 | IPSC = IPSC*exp(-dt/tr) + h*dt; 78 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 79 | 80 | r = r*exp(-dt/tr) + hr*dt; 81 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 82 | end 83 | 84 | 85 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 86 | v_ = v; 87 | %only store stuff every index variable. 88 | 89 | 90 | 91 | 92 | z = BPhi'*r; 93 | err = z - xz(i,:)'; 94 | 95 | 96 | if mod(i,step)==1 97 | if i > imin 98 | if i < icrit 99 | cd = Pinv*r; 100 | BPhi = BPhi - (cd*err'); 101 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 102 | end 103 | end 104 | end 105 | 106 | if mod(i,store) == 1; 107 | j = j + 1; 108 | time(j,:) = dt*i; 109 | current(j,:) = z; 110 | REC(:,j) = v(1:10); 111 | RECB(:,j) = BPhi(1:5,1); 112 | end 113 | 114 | 115 | if mod(i,round(0.1/dt))==1 116 | dt*i 117 | figure(1) 118 | drawnow 119 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 120 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 121 | xlim([dt*i-1,dt*i]) 122 | xlabel('Time') 123 | ylabel('x(t)') 124 | 125 | figure(2) 126 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 127 | xlabel('Time') 128 | ylabel('\phi_j') 129 | 130 | figure(3) 131 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 132 | ylim([0,100]) 133 | xlabel('Time') 134 | ylabel('Neuron Index') 135 | end 136 | 137 | end 138 | %% 139 | %ns 140 | current = current(1:1:j,:); 141 | REC = REC(:,1:1:j); 142 | %REC2 = REC2(:,1:1:j); 143 | nt = length(current); 144 | time = (1:1:nt)*T/nt; 145 | xhat = current; 146 | tspike = tspike(1:1:ns,:); 147 | M = tspike(tspike(:,2)>dt*icrit,:); 148 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 149 | %% 150 | Z = eig(OMEGA); %eigenvalues pre-learning 151 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues post-learning 152 | figure(42) 153 | plot(Z,'k.'), hold on 154 | plot(Z2,'r.') 155 | xlabel('Re\lambda') 156 | ylabel('Im\lambda') 157 | legend('Pre-Learning','Post-Learning') 158 | 159 | %% plot neurons pre- and post- learning 160 | figure(43) 161 | for z = 1:1:10 162 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 163 | end 164 | xlim([9,10]) 165 | xlabel('Time (s)') 166 | ylabel('Neuron Index') 167 | title('Post Learning') 168 | figure(66) 169 | for z = 1:1:10 170 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 171 | end 172 | xlim([0,1]) 173 | title('Pre-Learning') 174 | xlabel('Time (s)') 175 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETAFORCESINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; tmin = 5; tcrit = 10; nt = round(T/dt); tx = (1:1:nt)*dt; xz = sin(2*tx*pi*5)'; G = 10; Q = 10^4; 12 | 13 | %% 14 | m = min(size(xz)); %dimensionality of teacher 15 | E = Q*(2*rand(N,m)-1); %encoders 16 | BPhi = zeros(N,m); %Decoders 17 | %% Compute Neuronal Intercepts and Tuning Curves 18 | initial = 0; 19 | p = 0.1; %Sparse Coupling 20 | OMEGA = G*randn(N,N).*(rand(N,N)0); 26 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 27 | end 28 | 29 | %% Storage Matrices and Initialization 30 | store = 10; %don't store every time step, saves time. 31 | current = zeros(nt,m); %storage variable for output current 32 | IPSC = zeros(N,1); %post synaptic current 33 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 34 | JD = 0*IPSC; 35 | 36 | vpeak = pi; %peak and reset 37 | vreset = -pi; 38 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 39 | v_ = v; %temporary storage variable for integration 40 | 41 | j = 1; 42 | time = zeros(round(nt/store),1); 43 | RECB = zeros(5,round(2*round(nt/store))); 44 | REC = zeros(10,round(nt/store)); 45 | tspike = zeros(8*nt,2); 46 | ns = 0; 47 | tic 48 | SD = 0; 49 | BPhi = zeros(N,m); 50 | z = zeros(m,1); 51 | step = 50; %Sets the frequency of RLS 52 | imin = round(tmin/dt); %Start RLS 53 | icrit = round((tcrit/dt)); %Stop RLS 54 | 55 | Pinv = eye(N)*dt; 56 | i = 1; 57 | %% 58 | ilast = i; 59 | %icrit = ilast; 60 | for i = ilast :1:nt 61 | JX = IPSC + E*z; %current 62 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 63 | v = v_ + dt*(dv); %Euler integration plus refractory period. 64 | index = find(v>=vpeak); 65 | if length(index)>0 66 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 67 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 68 | ns = ns + length(index); 69 | end 70 | 71 | 72 | 73 | if tr == 0 74 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 75 | r = r *exp(-dt/td) + (v>=vpeak)/td; 76 | else 77 | IPSC = IPSC*exp(-dt/tr) + h*dt; 78 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 79 | 80 | r = r*exp(-dt/tr) + hr*dt; 81 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 82 | end 83 | 84 | 85 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 86 | v_ = v; 87 | %only store stuff every index variable. 88 | 89 | 90 | 91 | 92 | z = BPhi'*r; 93 | err = z - xz(i,:)'; 94 | 95 | 96 | if mod(i,step)==1 97 | if i > imin 98 | if i < icrit 99 | cd = Pinv*r; 100 | BPhi = BPhi - (cd*err'); 101 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 102 | end 103 | end 104 | end 105 | 106 | if mod(i,store) == 1; 107 | j = j + 1; 108 | time(j,:) = dt*i; 109 | current(j,:) = z; 110 | REC(:,j) = v(1:10); 111 | RECB(:,j) = BPhi(1:5,1); 112 | end 113 | 114 | 115 | if mod(i,round(0.1/dt))==1 116 | figure(1) 117 | drawnow 118 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 119 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 120 | xlim([dt*i-1,dt*i]) 121 | xlabel('Time') 122 | ylabel('x(t)') 123 | 124 | figure(2) 125 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 126 | xlabel('Time') 127 | ylabel('\phi_j') 128 | 129 | figure(3) 130 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 131 | ylim([0,100]) 132 | xlabel('Time') 133 | ylabel('Neuron Index') 134 | end 135 | 136 | end 137 | %% 138 | %ns 139 | current = current(1:1:j,:); 140 | REC = REC(:,1:1:j); 141 | %REC2 = REC2(:,1:1:j); 142 | nt = length(current); 143 | time = (1:1:nt)*T/nt; 144 | xhat = current; 145 | tspike = tspike(1:1:ns,:); 146 | M = tspike(tspike(:,2)>dt*icrit,:); 147 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 148 | %% 149 | Z = eig(OMEGA); %Eigenvalues pre-learning 150 | Z2 = eig(OMEGA+E*BPhi'); %Eigenvalues post-learning 151 | figure(42) 152 | plot(Z,'k.'), hold on 153 | plot(Z2,'r.') 154 | xlabel('Re\lambda') 155 | ylabel('Im\lambda') 156 | legend('Pre-Learning','Post-Learning') 157 | 158 | %% plot neurons pre- and post- learning 159 | figure(43) 160 | for z = 1:1:10 161 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 162 | end 163 | xlim([9,10]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(66) 168 | for z = 1:1:10 169 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 170 | end 171 | xlim([0,1]) 172 | title('Pre-Learning') 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | %% 176 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETAFORCEVDPHARMONIC.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; 12 | nt = round(T/dt); 13 | tx = (1:1:nt)*dt; 14 | 15 | %% Van der Pol 16 | T = 15; nt = round(T/dt); 17 | mu = 0.5; %Sets the behavior 18 | MD = 10; %Scale system in space 19 | TC = 20; %Scale system in time 20 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 21 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 22 | tx = (1:1:nt)*dt; 23 | xz(:,1) = interp1(t,y(:,1),tx); 24 | xz(:,2) = interp1(t,y(:,2),tx); 25 | G = 10; Q = 10^4; T = 15; tmin = 5; tcrit = 10; 26 | 27 | 28 | %% 29 | m = min(size(xz)); %dimensionality of teacher 30 | E = Q*(2*rand(N,m)-1); %encoders 31 | BPhi = zeros(N,m); %Decoders 32 | %% Compute Neuronal Intercepts and Tuning Curves 33 | initial = 0; 34 | p = 0.1; %Sparse Coupling 35 | OMEGA = G*randn(N,N).*(rand(N,N)0); 41 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 42 | end 43 | 44 | %% Storage Matrices and Initialization 45 | store = 10; %don't store every time step, saves time. 46 | current = zeros(nt,m); %storage variable for output current 47 | IPSC = zeros(N,1); %post synaptic current 48 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 49 | JD = 0*IPSC; 50 | 51 | vpeak = pi; %peak and reset 52 | vreset = -pi; 53 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 54 | v_ = v; %temporary storage variable for integration 55 | 56 | j = 1; 57 | time = zeros(round(nt/store),1); 58 | RECB = zeros(5,round(2*round(nt/store))); 59 | REC = zeros(10,round(nt/store)); 60 | tspike = zeros(8*nt,2); 61 | ns = 0; 62 | tic 63 | SD = 0; 64 | BPhi = zeros(N,m); 65 | z = zeros(m,1); 66 | step = 50; %Sets the frequency of RLS 67 | imin = round(tmin/dt); %Start RLS 68 | icrit = round((tcrit/dt)); %Stop RLS 69 | 70 | Pinv = eye(N)*dt; 71 | i = 1; 72 | %% 73 | ilast = i; 74 | %icrit = ilast; 75 | for i = ilast :1:nt 76 | JX = IPSC + E*z; %current 77 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 78 | v = v_ + dt*(dv); %Euler integration plus refractory period. 79 | index = find(v>=vpeak); 80 | if length(index)>0 81 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 82 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 83 | ns = ns + length(index); 84 | end 85 | 86 | 87 | 88 | if tr == 0 89 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 90 | r = r *exp(-dt/td) + (v>=vpeak)/td; 91 | else 92 | IPSC = IPSC*exp(-dt/tr) + h*dt; 93 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 94 | 95 | r = r*exp(-dt/tr) + hr*dt; 96 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 97 | end 98 | 99 | 100 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 101 | v_ = v; 102 | %only store stuff every index variable. 103 | 104 | 105 | 106 | 107 | z = BPhi'*r; 108 | err = z - xz(i,:)'; 109 | 110 | 111 | if mod(i,step)==1 112 | if i > imin 113 | if i < icrit 114 | cd = Pinv*r; 115 | BPhi = BPhi - (cd*err'); 116 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 117 | end 118 | end 119 | end 120 | 121 | if mod(i,store) == 1; 122 | j = j + 1; 123 | time(j,:) = dt*i; 124 | current(j,:) = z; 125 | REC(:,j) = v(1:10); 126 | RECB(:,j) = BPhi(1:5,1); 127 | end 128 | 129 | 130 | if mod(i,round(0.1/dt))==1 131 | 132 | figure(1) 133 | drawnow 134 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 135 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 136 | xlim([dt*i-1,dt*i]) 137 | xlabel('Time') 138 | ylabel('x(t)') 139 | 140 | figure(2) 141 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 142 | xlabel('Time') 143 | ylabel('\phi_j') 144 | 145 | figure(3) 146 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 147 | ylim([0,100]) 148 | xlabel('Time') 149 | ylabel('Neuron Index') 150 | end 151 | 152 | end 153 | %% 154 | %ns 155 | current = current(1:1:j,:); 156 | REC = REC(:,1:1:j); 157 | %REC2 = REC2(:,1:1:j); 158 | nt = length(current); 159 | time = (1:1:nt)*T/nt; 160 | xhat = current; 161 | tspike = tspike(1:1:ns,:); 162 | M = tspike(tspike(:,2)>dt*icrit,:); 163 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 164 | %% 165 | Z = eig(OMEGA); %eigenvalues pre-learning 166 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues post-learning 167 | figure(42) 168 | plot(Z,'k.'), hold on 169 | plot(Z2,'r.') 170 | xlabel('Re\lambda') 171 | ylabel('Im\lambda') 172 | legend('Pre-Learning','Post-Learning') 173 | 174 | %% Plot neurons pre- and post- learning 175 | figure(43) 176 | for z = 1:1:10 177 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 178 | end 179 | xlim([9,10]) 180 | xlabel('Time (s)') 181 | ylabel('Neuron Index') 182 | title('Post Learning') 183 | figure(66) 184 | for z = 1:1:10 185 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 186 | end 187 | xlim([0,1]) 188 | title('Pre-Learning') 189 | xlabel('Time (s)') 190 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETAFORCEVDPRELAX.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | 11 | %% 12 | T = 15; 13 | nt = round(T/dt); 14 | tx = (1:1:nt)*dt; 15 | 16 | %% Van der Pol 17 | T = 15; nt = round(T/dt); 18 | mu = 5; %Sets the behavior 19 | MD = 10; %Scale system in space 20 | TC = 20; %Scale system in time 21 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 22 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 23 | tx = (1:1:nt)*dt; 24 | xz(:,1) = interp1(t,y(:,1),tx); 25 | xz(:,2) = interp1(t,y(:,2),tx); 26 | G = 15; Q = 10^4; T = 15; tmin = 5; tcrit = 10; 27 | 28 | 29 | %% 30 | m = min(size(xz)); %dimensionality of teacher 31 | E = Q*(2*rand(N,m)-1); %encoders 32 | BPhi = zeros(N,m); %Decoders 33 | %% Compute Neuronal Intercepts and Tuning Curves 34 | initial = 0; 35 | p = 0.1; %Sparse Coupling 36 | OMEGA = G*randn(N,N).*(rand(N,N)0); 42 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 43 | end 44 | 45 | %% Storage Matrices and Initialization 46 | store = 10; %don't store every time step, saves time. 47 | current = zeros(nt,m); %storage variable for output current 48 | IPSC = zeros(N,1); %post synaptic current 49 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 50 | JD = 0*IPSC; 51 | 52 | vpeak = pi; %peak and reset 53 | vreset = -pi; 54 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 55 | v_ = v; %temporary storage variable for integration 56 | 57 | j = 1; 58 | time = zeros(round(nt/store),1); 59 | RECB = zeros(5,round(2*round(nt/store))); 60 | REC = zeros(10,round(nt/store)); 61 | tspike = zeros(8*nt,2); 62 | ns = 0; 63 | tic 64 | SD = 0; 65 | BPhi = zeros(N,m); 66 | z = zeros(m,1); 67 | step = 50; %Sets the frequency of RLS 68 | imin = round(tmin/dt); %Start RLS 69 | icrit = round((tcrit/dt)); %Stop RLS 70 | 71 | Pinv = eye(N)*dt; 72 | i = 1; 73 | %% 74 | ilast = i; 75 | %icrit = ilast; 76 | for i = ilast :1:nt 77 | JX = IPSC + E*z; %current 78 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 79 | v = v_ + dt*(dv); %Euler integration plus refractory period. 80 | index = find(v>=vpeak); 81 | if length(index)>0 82 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 83 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 84 | ns = ns + length(index); 85 | end 86 | 87 | 88 | 89 | if tr == 0 90 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 91 | r = r *exp(-dt/td) + (v>=vpeak)/td; 92 | else 93 | IPSC = IPSC*exp(-dt/tr) + h*dt; 94 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 95 | 96 | r = r*exp(-dt/tr) + hr*dt; 97 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 98 | end 99 | 100 | 101 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 102 | v_ = v; 103 | %only store stuff every index variable. 104 | 105 | 106 | 107 | 108 | z = BPhi'*r; 109 | err = z - xz(i,:)'; 110 | 111 | 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | if mod(i,store) == 1; 123 | j = j + 1; 124 | time(j,:) = dt*i; 125 | current(j,:) = z; 126 | REC(:,j) = v(1:10); 127 | RECB(:,j) = BPhi(1:5,1); 128 | end 129 | 130 | 131 | if mod(i,round(0.1/dt))==1 132 | figure(1) 133 | drawnow 134 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 135 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 136 | xlim([dt*i-1,dt*i]) 137 | xlabel('Time') 138 | ylabel('x(t)') 139 | 140 | figure(2) 141 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 142 | xlabel('Time') 143 | ylabel('\phi_j') 144 | 145 | figure(3) 146 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 147 | ylim([0,100]) 148 | xlabel('Time') 149 | ylabel('Neuron Index') 150 | end 151 | 152 | end 153 | %% 154 | %ns 155 | current = current(1:1:j,:); 156 | REC = REC(:,1:1:j); 157 | %REC2 = REC2(:,1:1:j); 158 | nt = length(current); 159 | time = (1:1:nt)*T/nt; 160 | xhat = current; 161 | tspike = tspike(1:1:ns,:); 162 | M = tspike(tspike(:,2)>dt*icrit,:); 163 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 164 | %% 165 | Z = eig(OMEGA); 166 | Z2 = eig(OMEGA+E*BPhi'); 167 | figure(42) 168 | plot(Z,'k.'), hold on %eigenvalues pre-learning 169 | plot(Z2,'r.') %eigenvalues post-learning 170 | xlabel('Re\lambda') 171 | ylabel('Im\lambda') 172 | legend('Pre-Learning','Post-Learning') 173 | 174 | %% Plot neurons pre and post-learning 175 | figure(43) 176 | for z = 1:1:10 177 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 178 | end 179 | xlim([9,10]) 180 | xlabel('Time (s)') 181 | ylabel('Neuron Index') 182 | title('Post Learning') 183 | figure(66) 184 | for z = 1:1:10 185 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 186 | end 187 | xlim([0,1]) 188 | title('Pre-Learning') 189 | xlabel('Time (s)') 190 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETALORENZ.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | T = 100; %total time 6 | dt = 0.00001; %time step 7 | N = 5000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | nt = round(T/dt); 11 | tx = (1:1:nt)*dt; 12 | rng(1) 13 | %% Lorenz 14 | tmin = 5; tcrit = 50; G = 15; Q = 10^4; 15 | tx = (1:1:nt)*dt; 16 | MD = 70; 17 | rho = 28; 18 | sigma = 10; 19 | beta = 8/3; 20 | TC = 1; %Alter the time scale of the Lorenz system 21 | 22 | [t,y] = ode45(@(t,y) lorenz(TC,sigma,rho,beta,MD,t,y) ,[0,T],[0.1;0.1;0.1]); 23 | xz(:,1) = interp1(t,y(:,1),tx); 24 | xz(:,2) = interp1(t,y(:,2),tx); 25 | xz(:,3) = interp1(t,y(:,3),tx); 26 | %xz = xz'; 27 | 28 | 29 | 30 | %% 31 | m = min(size(xz)); %dimensionality of teacher 32 | E = Q*(2*rand(N,m)-1); %encoders 33 | BPhi = zeros(N,m); %Decoders 34 | %% Compute Neuronal Intercepts and Tuning Curves 35 | initial = 0; 36 | p = 0.1; %Sparse Coupling 37 | OMEGA = G*randn(N,N).*(rand(N,N)0); 43 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 44 | end 45 | 46 | %% Storage Matrices and Initialization 47 | store = 10; %don't store every time step, saves time. 48 | current = zeros(nt,m); %storage variable for output current 49 | IPSC = zeros(N,1); %post synaptic current 50 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 51 | JD = 0*IPSC; 52 | 53 | vpeak = pi; %peak and reset 54 | vreset = -pi; 55 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 56 | v_ = v; %temporary storage variable for integration 57 | 58 | j = 1; 59 | time = zeros(round(nt/store),1); 60 | RECB = zeros(5,round(2*round(nt/store))); 61 | REC = zeros(10,round(nt/store)); 62 | tspike = zeros(8*nt,2); 63 | ns = 0; 64 | tic 65 | SD = 0; 66 | BPhi = zeros(N,m); 67 | z = zeros(m,1); 68 | step = 50; %Sets the frequency of RLS 69 | imin = round(tmin/dt); %Start RLS 70 | icrit = round((tcrit/dt)); %Stop RLS 71 | 72 | 73 | Pinv = eye(N)*dt; 74 | i = 1; 75 | %% 76 | ilast = i; 77 | %icrit = ilast; 78 | for i = ilast :1:nt 79 | JX = IPSC + E*z; %current 80 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 81 | v = v_ + dt*(dv); %Euler integration plus refractory period. 82 | index = find(v>=vpeak); 83 | if length(index)>0 84 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 85 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 86 | ns = ns + length(index); 87 | end 88 | 89 | 90 | if tr == 0 91 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 92 | r = r *exp(-dt/td) + (v>=vpeak)/td; 93 | else 94 | IPSC = IPSC*exp(-dt/tr) + h*dt; 95 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 96 | 97 | r = r*exp(-dt/tr) + hr*dt; 98 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 99 | end 100 | 101 | 102 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 103 | v_ = v; 104 | %only store stuff every index variable. 105 | 106 | 107 | 108 | 109 | z = BPhi'*r; 110 | err = z - xz(i,:)'; 111 | 112 | 113 | if mod(i,step)==1 114 | if i > imin 115 | if i < icrit 116 | cd = Pinv*r; 117 | BPhi = BPhi - (cd*err'); 118 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 119 | end 120 | end 121 | end 122 | 123 | if mod(i,store) == 1; 124 | j = j + 1; 125 | time(j,:) = dt*i; 126 | current(j,:) = z; 127 | REC(:,j) = v(1:10); 128 | RECB(:,j) = BPhi(1:5,1); 129 | end 130 | 131 | 132 | if mod(i,round(0.1/dt))==1 133 | figure(1) 134 | drawnow 135 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 136 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 137 | xlabel('Time') 138 | ylabel('x(t)') 139 | 140 | figure(2) 141 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 142 | xlabel('Time') 143 | ylabel('\phi_j') 144 | 145 | figure(3) 146 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 147 | ylim([0,100]) 148 | xlabel('Time') 149 | ylabel('Neuron Index') 150 | end 151 | 152 | end 153 | %% 154 | 155 | tspike = tspike(1:1:ns,:); 156 | M = tspike(tspike(:,2)>tcrit,:); 157 | AverageFiringRate = length(M)/(N*(T-tcrit)) 158 | 159 | current = current(1:1:j,:); 160 | REC = REC(:,1:1:j); 161 | %REC2 = REC2(:,1:1:j); 162 | nt = length(current); 163 | time = (1:1:nt)*T/nt; 164 | xhat = current; 165 | 166 | 167 | %% 168 | Z = eig(OMEGA); %eigenvalues pre-learning 169 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues post-learning 170 | figure(42) 171 | plot(Z,'k.'), hold on 172 | plot(Z2,'r.') 173 | xlabel('Re\lambda') 174 | ylabel('Im\lambda') 175 | legend('Pre-Learning','Post-Learning') 176 | 177 | %% plot the neurons pre and post-learning 178 | figure(43) 179 | for z = 1:1:10 180 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 181 | end 182 | xlim([9,10]) 183 | xlabel('Time (s)') 184 | ylabel('Neuron Index') 185 | title('Post Learning') 186 | figure(66) 187 | for z = 1:1:10 188 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 189 | end 190 | xlim([0,1]) 191 | title('Pre-Learning') 192 | xlabel('Time (s)') 193 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETANOISYPRODSINES.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | rng(1) 11 | %% Product of sinusoids 12 | T = 80; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = ((sin(2*tx*pi*4).*sin(2*tx*pi*6))+ 0.05*randn(1,nt))'; G = 15; Q = 1*10^4; %Scaling Weight for BPhi 13 | 14 | %% 15 | m = min(size(xz)); %dimensionality of teacher 16 | E = Q*(2*rand(N,m)-1); %encoders 17 | BPhi = zeros(N,m); %Decoders 18 | %% Compute Neuronal Intercepts and Tuning Curves 19 | initial = 0; 20 | p = 0.1; %Sparse Coupling 21 | OMEGA = G*randn(N,N).*(rand(N,N)0); 27 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 28 | end 29 | 30 | %% Storage Matrices and Initialization 31 | store = 10; %don't store every time step, saves time. 32 | current = zeros(nt,m); %storage variable for output current 33 | IPSC = zeros(N,1); %post synaptic current 34 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 35 | JD = 0*IPSC; 36 | 37 | vpeak = pi; %peak and reset 38 | vreset = -pi; 39 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 40 | v_ = v; %temporary storage variable for integration 41 | 42 | j = 1; 43 | time = zeros(round(nt/store),1); 44 | RECB = zeros(5,round(2*round(nt/store))); 45 | REC = zeros(10,round(nt/store)); 46 | tspike = zeros(8*nt,2); 47 | ns = 0; 48 | tic 49 | SD = 0; 50 | BPhi = zeros(N,m); 51 | z = zeros(m,1); 52 | step = 50; %Sets the frequency of RLMS 53 | imin = round(tmin/dt); %Start RLMS 54 | icrit = round((tcrit/dt)); %Stop RLMS 55 | 56 | 57 | Pinv = eye(N)*dt; 58 | i = 1; 59 | %% 60 | ilast = i; 61 | %icrit = ilast; 62 | for i = ilast :1:nt 63 | JX = IPSC + E*z; %current 64 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 65 | v = v_ + dt*(dv); %Euler integration plus refractory period. 66 | index = find(v>=vpeak); 67 | if length(index)>0 68 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 69 | ns = ns + length(index); 70 | end 71 | 72 | index2 = find(v(1:100)>vpeak); 73 | if length(index2>0) 74 | tspike(ns+1:ns+length(index2),:) = [index2,0*index2+dt*i]; 75 | end 76 | 77 | if tr == 0 78 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 79 | r = r *exp(-dt/td) + (v>=vpeak)/td; 80 | else 81 | IPSC = IPSC*exp(-dt/tr) + h*dt; 82 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 83 | 84 | r = r*exp(-dt/tr) + hr*dt; 85 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 86 | end 87 | 88 | 89 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 90 | v_ = v; 91 | %only store stuff every index variable. 92 | 93 | 94 | 95 | 96 | z = BPhi'*r; 97 | err = z - xz(i,:)'; 98 | 99 | 100 | if mod(i,step)==1 101 | if i > imin 102 | if i < icrit 103 | cd = Pinv*r; 104 | BPhi = BPhi - (cd*err'); 105 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 106 | end 107 | end 108 | end 109 | 110 | if mod(i,store) == 1; 111 | j = j + 1; 112 | time(j,:) = dt*i; 113 | current(j,:) = z; 114 | REC(:,j) = v(1:10); 115 | RECB(:,j) = BPhi(1:5,1); 116 | end 117 | 118 | 119 | %% plotting 120 | if mod(i,round(0.1/dt))==1 121 | figure(1) 122 | drawnow 123 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 124 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 125 | xlabel('Time') 126 | ylabel('x(t)') 127 | 128 | figure(2) 129 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 130 | xlabel('Time') 131 | ylabel('\phi_j') 132 | 133 | figure(3) 134 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 135 | xlabel('Time') 136 | ylabel('Neuron Index') 137 | end 138 | 139 | end 140 | %% 141 | %ns 142 | current = current(1:1:j,:); 143 | REC = REC(:,1:1:j); 144 | nt = length(current); 145 | time = (1:1:nt)*T/nt; 146 | xhat = current; 147 | 148 | %% 149 | Z = eig(OMEGA); %eigenvalues Prelearning 150 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues post-learning 151 | figure(42) 152 | plot(Z,'k.'), hold on 153 | plot(Z2,'r.') 154 | xlabel('Re\lambda') 155 | ylabel('Im\lambda') 156 | legend('Pre-Learning','Post-Learning') 157 | 158 | %% Plot the neurons pre and post learning 159 | figure(43) 160 | for z = 1:1:10 161 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 162 | end 163 | xlim([9,10]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(66) 168 | for z = 1:1:10 169 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 170 | end 171 | xlim([0,1]) 172 | title('Pre-Learning') 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/THETAPRODSINES.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | rng(1) 11 | %% Product of sinusoids 12 | T = 80; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = ((sin(2*tx*pi*4).*sin(2*tx*pi*6)))'; G = 25; Q = 1*10^4; %Scaling Weight for BPhi 13 | 14 | %% 15 | m = min(size(xz)); %dimensionality of teacher 16 | E = Q*(2*rand(N,m)-1); %encoders 17 | BPhi = zeros(N,m); %Decoders 18 | %% Compute Neuronal Intercepts and Tuning Curves 19 | initial = 0; 20 | p = 0.1; %Sparse Coupling 21 | OMEGA = G*randn(N,N).*(rand(N,N)0); 27 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 28 | end 29 | 30 | %% Storage Matrices and Initialization 31 | store = 10; %don't store every time step, saves time. 32 | current = zeros(nt,m); %storage variable for output current 33 | IPSC = zeros(N,1); %post synaptic current 34 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 35 | JD = 0*IPSC; 36 | 37 | vpeak = pi; %peak and reset 38 | vreset = -pi; 39 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 40 | v_ = v; %temporary storage variable for integration 41 | 42 | j = 1; 43 | time = zeros(round(nt/store),1); 44 | RECB = zeros(5,round(2*round(nt/store))); 45 | REC = zeros(10,round(nt/store)); 46 | tspike = zeros(8*nt,2); 47 | ns = 0; 48 | tic 49 | SD = 0; 50 | BPhi = zeros(N,m); 51 | z = zeros(m,1); 52 | step = 50; %Sets the frequency of RLS 53 | imin = round(tmin/dt); %Start RLS 54 | icrit = round((tcrit/dt)); %Stop RLS 55 | 56 | 57 | Pinv = eye(N)*dt; 58 | i = 1; 59 | %% 60 | ilast = i; 61 | %icrit = ilast; 62 | for i = ilast :1:nt 63 | JX = IPSC + E*z; %current 64 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 65 | v = v_ + dt*(dv); %Euler integration plus refractory period. 66 | index = find(v>=vpeak); 67 | if length(index)>0 68 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 69 | ns = ns + length(index); 70 | end 71 | 72 | index2 = find(v(1:100)>vpeak); 73 | if length(index2>0) 74 | tspike(ns+1:ns+length(index2),:) = [index2,0*index2+dt*i]; 75 | end 76 | 77 | if tr == 0 78 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 79 | r = r *exp(-dt/td) + (v>=vpeak)/td; 80 | else 81 | IPSC = IPSC*exp(-dt/tr) + h*dt; 82 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 83 | 84 | r = r*exp(-dt/tr) + hr*dt; 85 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 86 | end 87 | 88 | 89 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 90 | v_ = v; 91 | %only store stuff every index variable. 92 | 93 | 94 | 95 | 96 | z = BPhi'*r; 97 | err = z - xz(i,:)'; 98 | 99 | 100 | if mod(i,step)==1 101 | if i > imin 102 | if i < icrit 103 | cd = Pinv*r; 104 | BPhi = BPhi - (cd*err'); 105 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 106 | end 107 | end 108 | end 109 | 110 | if mod(i,store) == 1; 111 | j = j + 1; 112 | time(j,:) = dt*i; 113 | current(j,:) = z; 114 | REC(:,j) = v(1:10); 115 | RECB(:,j) = BPhi(1:5,1); 116 | end 117 | 118 | 119 | %% plotting code. 120 | if mod(i,round(0.1/dt))==1 121 | figure(1) 122 | drawnow 123 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 124 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 125 | xlabel('Time') 126 | ylabel('x(t)') 127 | 128 | figure(2) 129 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 130 | xlabel('Time') 131 | ylabel('\phi_j') 132 | 133 | figure(3) 134 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 135 | xlabel('Time') 136 | ylabel('Neuron Index') 137 | end 138 | 139 | end 140 | %% 141 | %ns 142 | current = current(1:1:j,:); 143 | REC = REC(:,1:1:j); 144 | %REC2 = REC2(:,1:1:j); 145 | nt = length(current); 146 | time = (1:1:nt)*T/nt; 147 | xhat = current; 148 | 149 | %% 150 | Z = eig(OMEGA); %eigenvalues prelearning 151 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues postlearning 152 | figure(42) 153 | plot(Z,'k.'), hold on 154 | plot(Z2,'r.') 155 | xlabel('Re\lambda') 156 | ylabel('Im\lambda') 157 | legend('Pre-Learning','Post-Learning') 158 | 159 | %% Plot the neurons pre and post-learning 160 | figure(43) 161 | for z = 1:1:10 162 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 163 | end 164 | xlim([9,10]) 165 | xlabel('Time (s)') 166 | ylabel('Neuron Index') 167 | title('Post Learning') 168 | figure(66) 169 | for z = 1:1:10 170 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 171 | end 172 | xlim([0,1]) 173 | title('Pre-Learning') 174 | xlabel('Time (s)') 175 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/lorenz.m: -------------------------------------------------------------------------------- 1 | function dy = lorenz(TC,sigma,rho,beta,MD,t,y) 2 | 3 | dy(1,1) = sigma*(y(2,1) - y(1,1)); 4 | dy(2,1) = rho*y(1,1)-MD*y(1,1)*y(3,1)-y(2,1); 5 | dy(3,1) = MD*y(1,1)*y(2,1)-beta*y(3,1); 6 | dy = TC*dy; 7 | end -------------------------------------------------------------------------------- /CODE FOR FIGURE 2/vanderpol.m: -------------------------------------------------------------------------------- 1 | function dy = vanderpol(mu,MD,TC,t,y) 2 | dy(1,1) = mu*(y(1,1)-(y(1,1).^3)*(MD*MD/3) - y(2,1)); 3 | dy(2,1) = y(1,1)/mu; 4 | dy = dy*TC; 5 | end -------------------------------------------------------------------------------- /CODE FOR FIGURE 3 (ODE TO JOY)/IZFORCESONG.m: -------------------------------------------------------------------------------- 1 | % Network of Izhikevich Neurons learns the first bar of Ode to Joy 2 | % song note data is located in the file ode2joy.mat. 3 | 4 | clear all 5 | clc 6 | 7 | T = 1000000; %Network parameters and total simulation time 8 | dt = 0.04; %Time step 9 | nt = round(T/dt); %number of time steps 10 | N = 5000; %number of neurons 11 | %% Izhikevich Parameters 12 | C = 250; 13 | vr = -60; 14 | b = 0; 15 | ff = 2.5; 16 | vpeak = 30; 17 | vreset = -65; 18 | vt = vr+40-(b/ff); 19 | Er = 0; 20 | u = zeros(N,1); 21 | a = 0.01; 22 | d = 200; 23 | tr = 2; 24 | td = 20; 25 | p = 0.1; 26 | G =1*10^4; %Controls the magnitude of chaos 27 | Q = 4*10^3; %Controls the magnitude of the perturbation. 28 | %% Initialize post synaptic currents, and voltages 29 | IPSC = zeros(N,1); %post synaptic current 30 | h = zeros(N,1); 31 | r = zeros(N,1); 32 | hr = zeros(N,1); 33 | JD = zeros(N,1); 34 | 35 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 36 | v_ = v; %These are just used for Euler integration, previous time step storage 37 | 38 | 39 | %% Convert the sequence of notes and half notes in the ode2joyshort.mat into a teaching signal. 40 | % the file ode2joy short.mat contains 2 matrices, J and HN. The matrix 41 | % length corresponds to the number of notes while the matrix width 42 | % corresponds to the note type and is the dimension of the teaching signal. 43 | % J indicates the presence of a note while HN indicates the presence of a 44 | % half note. 45 | freq = 4; 46 | load ode2joyshort.mat; 47 | nnotes = length(J); 48 | nchord = min(size(J)); 49 | ds = (1000/freq)*nnotes; n1 = round(ds/dt); 50 | ZS = abs(sin(pi*(1:1:n1)*dt*nnotes/(ds))); 51 | ZS = repmat(ZS,nchord,1); 52 | song = J'; 53 | nn = size(song); 54 | 55 | j = 1 ; 56 | for i = 1:1:n1 57 | if mod(i,round(1000/(freq*dt)))==0; 58 | j = j + 1; 59 | if j > nn(2); break; end 60 | end 61 | ZS(:,i) = ZS(:,i).*song(:,j); 62 | end 63 | 64 | for i = 1:1:15; 65 | if HN(i,1) > 0 66 | q = length((i-1)*(1000/(freq*dt)):(i+1)*(1000/(freq*dt))); 67 | w = find(J(i,:)>0); 68 | ZS(w,(i-1)*(1000/(freq*dt)):(i+1)*(1000/(freq*dt)))= sin(pi*(1:1:q)/q); 69 | end 70 | end 71 | zx = repmat(ZS,1,ceil(T/ds)); 72 | 73 | 74 | 75 | 76 | 77 | %% 78 | E = (2*rand(N,nchord)-1)*Q; %Rank-nchord perturbation 79 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 107 | if length(index)>0 108 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 109 | %tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %Store spike 110 | %times, but takes longer to simulate. 111 | ns = ns + length(index); %total number of spikes 112 | end 113 | 114 | % implement the synapse, either single or double exponential 115 | if tr == 0 116 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 117 | r = r *exp(-dt/td) + (v>=vpeak)/td; 118 | else 119 | IPSC = IPSC*exp(-dt/tr) + h*dt; 120 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 121 | 122 | r = r*exp(-dt/tr) + hr*dt; 123 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 124 | end 125 | 126 | %Compute the approximant and error 127 | z = BPhi'*r; 128 | err = z - zx(:,i); 129 | zz(:,i) = zx(:,i) + cumsum(ones(nchord,1)); 130 | 131 | %% Implement RLS. 132 | if mod(i,step)==1 133 | if i > imin 134 | if i < icrit 135 | cd = Pinv*r; 136 | BPhi = BPhi - (cd*err'); 137 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 138 | end 139 | end 140 | end 141 | 142 | %Record the decoders periodically. 143 | if mod(i,1/dt)==1 144 | ss = ss + 1; 145 | RECB(ss,:)=BPhi(1:5); 146 | end 147 | 148 | 149 | % apply the resets and store stuff 150 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 151 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 152 | v_ = v; % sets v(t-1) = v for the next itteration of loop 153 | REC(i,:) = [v(1:5)',u(1:5)']; 154 | current(i,:) = z'+ cumsum(ones(1,nchord)); 155 | 156 | %Plot progress 157 | if mod(i,round(100/dt))==1 158 | drawnow 159 | %figure(1) 160 | %plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 161 | %ylim([0,100]) 162 | gg = max(1,i-round(3000/dt)); 163 | 164 | figure(2) 165 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:)), hold on 166 | plot(dt*(gg:1:i)/1000,zz(:,gg:1:i),'k--'), hold off 167 | xlim([dt*i/1000-3,dt*i/1000]) 168 | xlabel('Time (s)') 169 | ylabel('Note') 170 | figure(5) 171 | plot(0.001*dt*i*(1:1:ss)/ss,RECB(1:1:ss,:),'.'), hold off 172 | xlabel('Time (s)') 173 | ylabel('Decoder') 174 | 175 | end 176 | 177 | end 178 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 3 (ODE TO JOY)/SONGGENERATOR.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | %% Script converts network output into .wave file. 4 | clear ZS note; 5 | QD = current'; %Need to use the current file. 6 | T1 = T/1000; 7 | n = length(QD); % carrier frequency (Hz) 8 | sf = 8192; 9 | nt = T1*8192; 10 | Time = (1:1:nt)/8192; 11 | 12 | for i = 1:1:5 13 | QD(i,:) = (QD(i,:)-i)*2; 14 | ZS(i,:) = interp1((1:1:n)*T1/n,QD(i,:),Time); 15 | end 16 | 17 | d = round(n/sf); % duration (s) % number of samples 18 | s = Time; % sound data preparation 19 | 20 | 21 | f(1) = 261; 22 | f(2) = 293.6; 23 | f(3) = 329.6; 24 | f(4) = 349.23; 25 | f(5) = 392; 26 | j = 0; 27 | for ns = 1:1:5 28 | note(ns,:) = sin(2*pi*f(ns)*Time); 29 | end 30 | 31 | %% 32 | songF = sum(ZS.*note); 33 | q = length(songF); 34 | %% 35 | filename = 'SONG.wav'; 36 | audiowrite(filename,songF(0.9*q:q),sf); 37 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 3 (ODE TO JOY)/ode2joyshort.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR FIGURE 3 (ODE TO JOY)/ode2joyshort.mat -------------------------------------------------------------------------------- /CODE FOR FIGURE 4 (USER SUPPLIED SUPERVISOR)/IZSONGBIRDFORCE.m: -------------------------------------------------------------------------------- 1 | % Network of Izhikevich Neurons learns a song bird signal with a clock 2 | % input. Note that you have to supply your own supervisor here due to file 3 | % size limitations. The supervisor, zx should be a matrix of m x nt dimensional, where 4 | % m is the dimension of the supervisor and nt is the number of time steps. 5 | % RLS is applied until time T/2. The HDTS is stored as variable z2. Note 6 | % that the code is written for a 5 second supervisor, nt should equal the 7 | % length of z2. 8 | 9 | 10 | 11 | clear all 12 | clc 13 | 14 | T = 100000; %Network parameters and total simulation time 15 | dt = 0.04; %Time step 16 | nt = round(T/dt); %number of time steps 17 | N = 1000; %number of neurons 18 | %% Izhikevich Parameters 19 | C = 250; 20 | vr = -60; 21 | b = 0; 22 | ff = 2.5; 23 | vpeak = 30; 24 | vreset = -65; 25 | vt = -40; 26 | Er = 0; 27 | u = zeros(N,1); 28 | a = 0.002; 29 | d = 100; 30 | tr = 2; 31 | td = 20; 32 | p = 0.1; 33 | G = 1.3*10^4; 34 | Q = 1*10^3; 35 | WE2 = 8*10^3; 36 | 37 | %% Initialize post synaptic currents, and voltages 38 | IPSC = zeros(N,1); %post synaptic current 39 | h = zeros(N,1); 40 | r = zeros(N,1); 41 | hr = zeros(N,1); 42 | JD = zeros(N,1); 43 | 44 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 45 | v_ = v; %These are just used for Euler integration, previous time step storage 46 | 47 | %% User has to supply supervisor signal, zx 48 | load songsup4.mat 49 | dd = size(zx); 50 | m1 = dd(1); 51 | m2 = 500; %number of upstates in the supervisor signal duration of 5 seconds. 100 per second. 52 | zx = zx/(max(max(zx))); 53 | zx(isnan(zx)==1)=0; 54 | %% Generate HDTS 55 | temp1 = abs(sin(m2*pi*((1:1:5000/dt)*dt)/5000)); 56 | for qw = 1:1:m2 57 | z2(qw,:) = temp1.*((1:1:5000/dt)*dt(qw-1)*5000/m2); 58 | end 59 | %% 60 | dd(2) = max(size(zx)); 61 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 95 | if length(index)>0 96 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 97 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %Store spike 98 | %times, but takes longer to simulate. 99 | ns = ns + length(index); %total number of spikes 100 | 101 | end 102 | 103 | % implement the synapse, either single or double exponential 104 | if tr == 0 105 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 106 | r = r *exp(-dt/td) + (v>=vpeak)/td; 107 | else 108 | IPSC = IPSC*exp(-dt/tr) + h*dt; 109 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 110 | 111 | r = r*exp(-dt/tr) + hr*dt; 112 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 113 | end 114 | 115 | %Compute the approximant and error 116 | z1 = BPhi1'*r; 117 | if qq>=dd(2) 118 | qq = 1; 119 | end 120 | err = z1 - zx(:,qq); 121 | qq = qq + 1; 122 | 123 | %% Implement RLS. 124 | if mod(i,step)==1 125 | if i > imin 126 | if i < icrit 127 | cd1 = Pinv1*r; 128 | BPhi1 = BPhi1 - (cd1*err'); 129 | Pinv1 = Pinv1 -((cd1)*(cd1'))/( 1 + (r')*(cd1)); 130 | end 131 | end 132 | end 133 | 134 | %Record the decoders periodically. 135 | if mod(i,1/dt)==1 136 | ss = ss + 1; 137 | RECB(ss,1:10)=BPhi1(1:10); 138 | end 139 | 140 | 141 | % apply the resets and store stuff 142 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 143 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 144 | v_ = v; % sets v(t-1) = v for the next itteration of loop 145 | REC(i,:) = [v(1:5)',u(1:5)']; 146 | 147 | 148 | if mod(i,100) ==1 %don't store every time step, saves time. 149 | k2 = k2 + 1; 150 | current(k2,:) = z1'; 151 | end 152 | 153 | 154 | %Plot progress 155 | if mod(i,round(100/dt))==1 156 | drawnow 157 | %figure(1) 158 | %plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 159 | %ylim([0,100]) 160 | gg = max(1,i-round(3000/dt)); 161 | 162 | figure(32) 163 | plot(0.001*(1:1:k2)*dt*i/k2,current(1:1:k2,1:20:m1)) 164 | xlabel('Time') 165 | ylabel('Network Output') 166 | xlim([dt*i/1000-5,dt*i/1000]) 167 | ylim([0,0.4]) 168 | 169 | 170 | figure(5) 171 | plot(0.001*dt*i*(1:1:ss)/ss,RECB(1:1:ss,1:10),'r.') 172 | xlabel('Time (s)') 173 | ylabel('Decoder') 174 | 175 | end 176 | 177 | end 178 | -------------------------------------------------------------------------------- /CODE FOR FIGURE 5 (USER SUPPLIED SUPERVISOR)/IZFORCEMOVIE.m: -------------------------------------------------------------------------------- 1 | % Network of Izhikevich Neurons learns a song bird signal with a clock 2 | % input. Note that you have to supply your own supervisor here due to file 3 | % size limitations. The supervisor, zx should be a matrix of m x nt dimensional, where 4 | % m is the dimension of the supervisor and nt is the number of time steps. 5 | % RLS is applied until time T/2. The HDTS is stored as variable z2. Note 6 | % that the code is written for an 8 second supervisor, nt should equal the 7 | % length of z2. 8 | 9 | clear all 10 | clc 11 | 12 | T = 100000; %Network parameters and total simulation time 13 | dt = 0.04; %Time step 14 | nt = round(T/dt); %number of time steps 15 | N = 1000; %number of neurons 16 | %% Izhikevich Parameters 17 | C = 250; 18 | vr = -60; 19 | b = 0; 20 | ff = 2.5; 21 | vpeak = 30; 22 | vreset = -65; 23 | vt = -40; 24 | Er = 0; 25 | u = zeros(N,1); 26 | a = 0.002; 27 | d = 100; 28 | tr = 2; 29 | td = 20; 30 | p = 0.1; 31 | G = 5*10^3; 32 | Q = 4*10^2; 33 | WE2 = 4*10^3; 34 | 35 | %% Initialize post synaptic currents, and voltages 36 | IPSC = zeros(N,1); %post synaptic current 37 | h = zeros(N,1); 38 | r = zeros(N,1); 39 | hr = zeros(N,1); 40 | JD = zeros(N,1); 41 | 42 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 43 | v_ = v; %These are just used for Euler integration, previous time step storage 44 | 45 | %% User has to supply supervisor signal, zx 46 | zx = vz; 47 | dd = size(zx); 48 | m1 = dd(1); 49 | m2 = 32; %number of upstates in the supervisor signal duration of 5 seconds. 100 per second. 50 | zx = zx/(max(max(zx))); 51 | zx(isnan(zx)==1)=0; 52 | %% generate HDTS signal 53 | temp1 = abs(sin(m2*pi*((1:1:8000/dt)*dt)/8000)); 54 | for qw = 1:1:m2 55 | z2(qw,:) = temp1.*((1:1:8000/dt)*dt(qw-1)*8000/m2); 56 | end 57 | %% 58 | dd(2) = max(size(zx)); 59 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 93 | if length(index)>0 94 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 95 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %Store spike 96 | %times, but takes longer to simulate. 97 | ns = ns + length(index); %total number of spikes 98 | 99 | end 100 | 101 | % implement the synapse, either single or double exponential 102 | if tr == 0 103 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 104 | r = r *exp(-dt/td) + (v>=vpeak)/td; 105 | else 106 | IPSC = IPSC*exp(-dt/tr) + h*dt; 107 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 108 | 109 | r = r*exp(-dt/tr) + hr*dt; 110 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 111 | end 112 | 113 | %Compute the approximant and error 114 | z1 = BPhi1'*r; 115 | if qq>=dd(2) 116 | qq = 1; 117 | end 118 | err = z1 - zx(:,qq); 119 | qq = qq + 1; 120 | 121 | %% Implement RLS. 122 | if mod(i,step)==1 123 | if i > imin 124 | if i < icrit 125 | 126 | cd1 = Pinv1*r; 127 | BPhi1 = BPhi1 - (cd1*err'); 128 | Pinv1 = Pinv1 -((cd1)*(cd1'))/( 1 + (r')*(cd1)); 129 | end 130 | end 131 | end 132 | 133 | %Record the decoders periodically. 134 | if mod(i,1/dt)==1 135 | ss = ss + 1; 136 | RECB(ss,1:10)=BPhi1(1:10); 137 | end 138 | 139 | 140 | % apply the resets and store stuff 141 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 142 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 143 | v_ = v; % sets v(t-1) = v for the next itteration of loop 144 | REC(i,:) = [v(1:5)',u(1:5)']; 145 | if mod(i,100) ==1 146 | k2 = k2 + 1; 147 | current(k2,:) = z1'; 148 | end 149 | %Plot progress 150 | if mod(i,round(100/dt))==1 151 | dt*i 152 | drawnow 153 | %figure(1) 154 | %plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 155 | %ylim([0,100]) 156 | gg = max(1,i-round(3000/dt)); 157 | 158 | figure(32) 159 | plot(0.001*(1:1:k2)*dt*i/k2,current(1:1:k2,1:20:m1)) 160 | xlabel('Time') 161 | ylabel('Network Output') 162 | xlim([dt*i/1000-5,dt*i/1000]) 163 | ylim([0,0.4]) 164 | 165 | figure(5) 166 | plot(0.001*dt*i*(1:1:ss)/ss,RECB(1:1:ss,1:10),'r.') 167 | xlabel('Time (s)') 168 | ylabel('Decoder') 169 | 170 | end 171 | 172 | end 173 | -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/IZFORCECLASSIFICATION.m: -------------------------------------------------------------------------------- 1 | %% IZFORCE CLASSIFIER WITH ADAPTATION 2 | clear all 3 | clc 4 | 5 | T = 1000000; %Total time 6 | dt = 0.04; %integration time step 7 | nt = round(T/dt); 8 | N = 2000; %number of neurons 9 | %% Izhikevich Parameters 10 | C = 250; 11 | vr = -60; 12 | b = 0; 13 | k = 2.5; 14 | vpeak = 30; 15 | vreset = -65; 16 | vt = vr+40-(b/k); %threshold 17 | Er = 0; %Reversal Potential 18 | u = zeros(N,1); 19 | a = 0.01; 20 | d = 200; 21 | tr = 2; 22 | td = 20; 23 | p = 0.1; %sparsity 24 | G =6*10^3; %scale weight matrix 25 | BIAS = 1000; %Bias current 26 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 93 | if length(index)>0 94 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 95 | %tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 96 | ns = ns + length(index); 97 | end 98 | 99 | 100 | if tr == 0 101 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 102 | r = r *exp(-dt/td) + (v>=vpeak)/td; 103 | else 104 | IPSC = IPSC*exp(-dt/tr) + h*dt; 105 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 106 | 107 | r = r*exp(-dt/tr) + hr*dt; 108 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 109 | end 110 | 111 | 112 | %% Apply RLS 113 | z = BPhi'*r; 114 | err = z - zx(i); 115 | if mod(i,step)==1 116 | if i > imin 117 | if i < icrit 118 | cd = Pinv*r; 119 | BPhi = BPhi - (cd*err'); 120 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 121 | end 122 | end 123 | end 124 | 125 | 126 | 127 | 128 | %% COMPUTE S, APPLY RESETS 129 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 130 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 131 | v_ = v; % sets v(t-1) = v for the next itteration of loop 132 | REC(i,:) = [v(1:5)',u(1:5)']; 133 | current(i,:) = z; 134 | RECB(i,:)=BPhi(1:5); 135 | if mod(i,round(100/dt))==1 136 | drawnow 137 | 138 | figure(2) 139 | plot(dt*(1:1:i),current(1:1:i,1)), hold on 140 | plot(dt*(1:1:i),zx(1:1:i),'k--'), hold off 141 | ylim([-0.6,0.6]) 142 | xlim([dt*i-1000,dt*i]) 143 | xlabel('Time') 144 | ylabel('Network Response') 145 | legend('Network Output','Target Signal') 146 | 147 | 148 | end 149 | end 150 | %% -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/NETWORKSIM.m: -------------------------------------------------------------------------------- 1 | %% IZFORCE WITH ADAPTATION, Load a Pre-trained weight matrix and test data. 2 | clear all 3 | clc 4 | %% 5 | T = 10000; 6 | dt = 0.04; 7 | nt = round(T/dt); 8 | N = 2000; %number of neurons 9 | load WEIGHTCLASSLINEAR.mat %Load trained weight data 10 | %% Izhikevich Parameters 11 | C = 250; 12 | vr = -60; 13 | b = 0; 14 | k = 2.5; 15 | vpeak = 30; 16 | vreset = -65; 17 | vt = vr+40-(b/k); %threshold 18 | Er = 0; %Reversal Potential 19 | u = zeros(N,1); 20 | a = 0.01; 21 | d = 200; 22 | tr = 2; 23 | td = 20; 24 | p = 0.1; 25 | 26 | %% Initalize currents all to be 0 27 | IPSC = zeros(N,1); %post synaptic current 28 | h = zeros(N,1); 29 | r = zeros(N,1); 30 | hr = zeros(N,1); 31 | JD = zeros(N,1); 32 | 33 | 34 | %-----Initialization--------------------------------------------- 35 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 36 | v_ = v; %These are just used for Euler integration, previous time step storage 37 | 38 | 39 | %% 40 | % Load a test data set for classification. 41 | load testsetlinear.mat; 42 | inputfreq = 4; %Present a data point at a specific frequency, 4 Hz. 43 | Xin = zeros(nt,2); 44 | zx = zeros(nt,1); 45 | nx = round(1000/(dt*inputfreq)); 46 | zx = 0.5*abs(sin(2*pi*(1:1:nt)*dt*inputfreq/2000)); 47 | 48 | 49 | %% Construct input and correct response. 50 | j = 1; 51 | k2 = 0; 52 | for i =1:1:nt 53 | zx(i) = zx(i)*(2*P(j)-1)*mod(k2,2); 54 | Xin(i,:) = [z(j,1),z(j,2)]*mod(k2,2); 55 | if mod(i,nx)==1 56 | k2 = k2 + 1; 57 | j = ceil(rand*2000); 58 | end 59 | end 60 | clear z P 61 | 62 | 63 | 64 | 65 | 66 | 67 | %% initialize network output and spike times. 68 | z = 0; 69 | tspike = zeros(nt,2); 70 | ns = 0; 71 | 72 | 73 | %% 74 | current = zeros(nt,1); 75 | REC = zeros(nt,10); 76 | i=1; 77 | %% SIMULATION 78 | tic 79 | ilast = i ; 80 | for i = ilast:1:nt; 81 | %% EULER INTEGRATE 82 | I = IPSC + E*z + Ein*(Xin(i,:)') + BIAS; 83 | v = v + dt*(( k.*(v-vr).*(v-vt) - u + I))/C ; % v(t) = v(t-1)+dt*v'(t-1) 84 | u = u + dt*(a*(b*(v_-vr)-u)); %same with u, the v_ term makes it so that the integration of u uses v(t-1), instead of the updated v(t) 85 | 86 | %% 87 | index = find(v>=vpeak); 88 | if length(index)>0 89 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 90 | %tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 91 | ns = ns + length(index); 92 | end 93 | 94 | if tr == 0 95 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 96 | r = r *exp(-dt/td) + (v>=vpeak)/td; 97 | else 98 | IPSC = IPSC*exp(-dt/tr) + h*dt; 99 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 100 | 101 | r = r*exp(-dt/tr) + hr*dt; 102 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 103 | end 104 | 105 | 106 | z = BPhi'*r; 107 | 108 | 109 | %% COMPUTE S, APPLY RESETS 110 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 111 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 112 | v_ = v; % sets v(t-1) = v for the next itteration of loop 113 | REC(i,:) = [v(1:5)',u(1:5)']; 114 | current(i,:) = z; 115 | if mod(i,round(100/dt))==1 116 | drawnow 117 | figure(2) 118 | plot(dt*(1:1:i),current(1:1:i,1)), hold on 119 | plot(dt*(1:1:i),zx(1:1:i),'k--'), hold off 120 | ylim([-0.6,0.6]) 121 | xlim([dt*i-3000,dt*i]) 122 | xlabel('Time') 123 | ylabel('Network Response') 124 | legend('Network','Correct Response') 125 | 126 | end 127 | 128 | 129 | 130 | end 131 | AverageFiringRate = 1000*ns/(N*T) 132 | -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/WEIGHTCLASSLINEAR.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/WEIGHTCLASSLINEAR.mat -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/lineardata.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/lineardata.mat -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/nonlineardata.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/nonlineardata.mat -------------------------------------------------------------------------------- /CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/testsetlinear.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR FIGURE SUPPLEMENTARY CLASSIFICATION FIGURES 10-12/testsetlinear.mat -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY ODE TO JOY EXAMPLE/IZFORCESONG.m: -------------------------------------------------------------------------------- 1 | % Network of Izhikevich Neurons learns the first bar of Ode to Joy 2 | % song note data is located in the file ode2joy.mat. 3 | clear all 4 | clc 5 | 6 | T = 1000000; %Network parameters and total simulation time 7 | dt = 0.04; %Time step 8 | nt = round(T/dt); %number of time steps 9 | N = 5000; %number of neurons 10 | %% Izhikevich Parameters 11 | C = 250; 12 | vr = -60; 13 | b = 0; 14 | ff = 2.5; 15 | vpeak = 30; 16 | vreset = -65; 17 | vt = vr+40-(b/ff); 18 | Er = 0; 19 | u = zeros(N,1); 20 | a = 0.01; 21 | d = 200; 22 | tr = 2; 23 | td = 20; 24 | p = 0.1; 25 | G =1*10^4; %Controls the magnitude of chaos 26 | Q = 4*10^3; %Controls the magnitude of the perturbation. 27 | %% Initialize post synaptic currents, and voltages 28 | IPSC = zeros(N,1); %post synaptic current 29 | h = zeros(N,1); 30 | r = zeros(N,1); 31 | hr = zeros(N,1); 32 | JD = zeros(N,1); 33 | 34 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 35 | v_ = v; %These are just used for Euler integration, previous time step storage 36 | 37 | 38 | %% Convert the sequence of notes and half notes in the ode2joyshort.mat into a teaching signal. 39 | % the file ode2joy short.mat contains 2 matrices, J and HN. The matrix 40 | % length corresponds to the number of notes while the matrix width 41 | % corresponds to the note type and is the dimension of the teaching signal. 42 | % J indicates the presence of a note while HN indicates the presence of a 43 | % half note. Note that the HDTS is encoded into the supervisor here, as 44 | % the last 64 components. 45 | freq = 4; 46 | load ode2joylong.mat; 47 | dd = size(J); 48 | nnotes = dd(1); 49 | nchord = dd(2); 50 | ds = (1000/freq)*nnotes; n1 = round(ds/dt); 51 | ZS = abs(sin(pi*(1:1:n1)*dt*nnotes/(ds))); 52 | ZS = repmat(ZS,nchord,1); 53 | song = J'; 54 | nn = size(song); 55 | 56 | j = 1 ; 57 | for i = 1:1:n1 % quarter notes 58 | if mod(i,round(1000/(freq*dt)))==0; 59 | j = j + 1; 60 | if j > nn(2); break; end 61 | end 62 | ZS(:,i) = ZS(:,i).*song(:,j); 63 | end 64 | 65 | for i = 1:1:63; %% Half Notes 66 | if HN(i,1) > 0 67 | q = length((i-1)*(1000/(freq*dt)):(i+1)*(1000/(freq*dt))); 68 | w = find(J(i,1:5)>0); 69 | ZS(w,(i-1)*(1000/(freq*dt)):(i+1)*(1000/(freq*dt)))= sin(pi*(1:1:q)/q); 70 | end 71 | end 72 | zx = repmat(ZS,1,ceil(T/ds)); 73 | 74 | 75 | 76 | 77 | 78 | %% 79 | E = (2*rand(N,nchord)-1)*Q; %Rank-nchord perturbation 80 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 108 | if length(index)>0 109 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 110 | %tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %Store spike 111 | %times, but takes longer to simulate. 112 | ns = ns + length(index); %total number of spikes 113 | end 114 | 115 | % implement the synapse, either single or double exponential 116 | if tr == 0 117 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td);close 118 | r = r *exp(-dt/td) + (v>=vpeak)/td; 119 | else 120 | IPSC = IPSC*exp(-dt/tr) + h*dt; 121 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 122 | 123 | r = r*exp(-dt/tr) + hr*dt; 124 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 125 | end 126 | 127 | %Compute the approximant and error 128 | z = BPhi'*r; 129 | err = z - zx(:,i); 130 | zz(:,i) = zx(:,i) + cumsum(ones(nchord,1)); 131 | 132 | %% Implement RLS. 133 | if mod(i,step)==1 134 | if i > imin 135 | if i < icrit 136 | cd = Pinv*r; 137 | BPhi = BPhi - (cd*err'); 138 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 139 | end 140 | end 141 | end 142 | 143 | %Record the decoders periodically. 144 | if mod(i,1/dt)==1 145 | ss = ss + 1; 146 | RECB(ss,:)=BPhi(1:5); 147 | end 148 | 149 | 150 | % apply the resets and store stuff 151 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 152 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 153 | v_ = v; % sets v(t-1) = v for the next itteration of loop 154 | REC(i,:) = [v(1:5)',u(1:5)']; 155 | current(i,:) = z'+ cumsum(ones(1,nchord)); 156 | 157 | %Plot progress 158 | if mod(i,round(100/dt))==1 159 | drawnow 160 | %figure(1) 161 | %plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 162 | %ylim([0,100]) 163 | gg = max(1,i-round(3000/dt)); 164 | 165 | figure(2) 166 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:)), hold on 167 | plot(dt*(gg:1:i)/1000,zz(:,gg:1:i),'k--'), hold off 168 | ylim([0,10]) 169 | xlim([dt*i/1000-3,dt*i/1000]) 170 | xlabel('Time (s)') 171 | ylabel('Note') 172 | 173 | figure(5) 174 | plot(0.001*dt*i*(1:1:ss)/ss,RECB(1:1:ss,:),'.'), hold off 175 | xlabel('Time (s)') 176 | ylabel('Decoder') 177 | 178 | end 179 | 180 | end 181 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY ODE TO JOY EXAMPLE/ode2joylong.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ModelDBRepository/190565/1da414fab280f0e7abe0447ef0aba89e98da65b1/CODE FOR SUPPLEMENTARY ODE TO JOY EXAMPLE/ode2joylong.mat -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/IZHIKEVICH 20/IZFORCEPRODSINE.m: -------------------------------------------------------------------------------- 1 | %% Force Method with Izhikevich Network 2 | clear all 3 | close all 4 | clc 5 | 6 | 7 | T = 20000; %Total time in ms 8 | dt = 0.04; %Integration time step in ms 9 | nt = round(T/dt); %Time steps 10 | N = 2000; %Number of neurons 11 | %% Izhikevich Parameters 12 | C = 250; %capacitance 13 | vr = -60; %resting membrane 14 | b = -2; %resonance parameter 15 | ff = 2.5; %k parameter for Izhikevich, gain on v 16 | vpeak = 30; % peak voltage 17 | vreset = -65; % reset voltage 18 | vt = vr+40-(b/ff); %threshold %threshold 19 | u = zeros(N,1); %initialize adaptation 20 | a = 0.01; %adaptation reciprocal time constant 21 | d = 200; %adaptation jump current 22 | tr = 2; %synaptic rise time 23 | td = 20; %decay time 24 | p = 0.1; %sparsity 25 | G =1*10^4; %Gain on the static matrix with 1/sqrt(N) scaling weights. 26 | Q =9*10^3; %Gain on the rank-k perturbation modified by RLS. 27 | Irh = 0.25*ff*(vt-vr)^2; 28 | 29 | %Storage variables for synapse integration 30 | IPSC = zeros(N,1); %post synaptic current 31 | h = zeros(N,1); 32 | r = zeros(N,1); 33 | hr = zeros(N,1); 34 | JD = zeros(N,1); 35 | 36 | %-----Initialization--------------------------------------------- 37 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 38 | v_ = v; %These are just used for Euler integration, previous time step storage 39 | %% Target signal COMMENT OUT TEACHER YOU DONT WANT, COMMENT IN TEACHER YOU WANT. 40 | zx = (sin(2*4*pi*(1:1:nt)*dt/1000)).*(sin(2*6*pi*(1:1:nt)*dt/1000)); 41 | 42 | %% 43 | k = min(size(zx)); %used to get the dimensionality of the approximant correctly. Typically will be 1 unless you specify a k-dimensional target function. 44 | 45 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 73 | if length(index)>0 74 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 75 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %uncomment this 76 | %if you want to store spike times. Takes longer. 77 | ns = ns + length(index); 78 | end 79 | 80 | %synapse for single exponential 81 | if tr == 0 82 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 83 | r = r *exp(-dt/td) + (v>=vpeak)/td; 84 | else 85 | 86 | %synapse for double exponential 87 | IPSC = IPSC*exp(-dt/tr) + h*dt; 88 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 89 | 90 | r = r*exp(-dt/tr) + hr*dt; 91 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 92 | end 93 | 94 | 95 | z = BPhi'*r; %approximant 96 | err = z - zx(:,i); %error 97 | %% RLS 98 | if mod(i,step)==1 99 | if i > imin 100 | if i < icrit 101 | cd = Pinv*r; 102 | BPhi = BPhi - (cd*err'); 103 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 104 | end 105 | end 106 | end 107 | 108 | 109 | 110 | 111 | %% Store, and plot. 112 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 113 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 114 | v_ = v; % sets v(t-1) = v for the next itteration of loop 115 | REC(i,:) = [v(1:5)',u(1:5)']; 116 | current(i,:) = z'; 117 | RECB(i,:)=BPhi(1:5); 118 | 119 | 120 | if mod(i,round(100/dt))==1 121 | dt*i 122 | drawnow 123 | gg = max(1,i - round(3000/dt)); %only plot for last 3 seconds 124 | figure(2) 125 | plot(dt*(gg:1:i)/1000,zx(:,gg:1:i),'k','LineWidth',2), hold on 126 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:),'b--','LineWidth',2), hold off 127 | xlabel('Time (s)') 128 | ylabel('$\hat{x}(t)$','Interpreter','LaTeX') 129 | legend('Approximant','Target Signal') 130 | xlim([dt*i-3000,dt*i]/1000) 131 | figure(3) 132 | plot((1:1:i)*dt/1000,RECB(1:1:i,:)) 133 | figure(14) 134 | plot(tspike(1:ns,2),tspike(1:ns,1),'k.') 135 | ylim([0,100]) 136 | end 137 | 138 | end 139 | %% 140 | tspike = tspike(tspike(:,2)~=0,:); 141 | M = tspike(tspike(:,2)>dt*icrit); 142 | AverageFiringRate = 1000*length(M)/(N*(T-dt*icrit)) 143 | %% Plotting 144 | figure(30) 145 | for j = 1:1:5 146 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 147 | end 148 | xlim([T/1000-2,T/1000]) 149 | xlabel('Time (s)') 150 | ylabel('Neuron Index') 151 | title('Post Learning') 152 | figure(31) 153 | for j = 1:1:5 154 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 155 | end 156 | xlim([0,imin*dt/1000]) 157 | xlabel('Time (s)') 158 | ylabel('Neuron Index') 159 | title('Pre-Learning') 160 | figure(40) 161 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 162 | Z2 = eig(OMEGA); %eigenvalues before learning 163 | %% plot eigenvalues before and after learning 164 | plot(Z2,'r.'), hold on 165 | plot(Z,'k.') 166 | legend('Pre-Learning','Post-Learning') 167 | xlabel('Re \lambda') 168 | ylabel('Im \lambda') 169 | 170 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/IZHIKEVICH 20/IZFORCESAWTOOTH.m: -------------------------------------------------------------------------------- 1 | %% Force Method with Izhikevich Network 2 | clear all 3 | close all 4 | clc 5 | 6 | T = 15000; %Total time in ms 7 | dt = 0.04; %Integration time step in ms 8 | nt = round(T/dt); %Time steps 9 | N = 2000; %Number of neurons 10 | %% Izhikevich Parameters 11 | C = 250; %capacitance 12 | vr = -60; %resting membrane 13 | b = -2; %resonance parameter 14 | ff = 2.5; %k parameter for Izhikevich, gain on v 15 | vpeak = 30; % peak voltage 16 | vreset = -65; % reset voltage 17 | vt = vr+40-(b/ff); %threshold %threshold 18 | u = zeros(N,1); %initialize adaptation 19 | a = 0.01; %adaptation reciprocal time constant 20 | d = 200; %adaptation jump current 21 | tr = 2; %synaptic rise time 22 | td = 20; %decay time 23 | p = 0.1; %sparsity 24 | G =5*10^3; %Gain on the static matrix with 1/sqrt(N) scaling weights. 25 | Q =4*10^3; %Gain on the rank-k perturbation modified by RLS. 26 | Irh = 0.25*ff*(vt-vr)^2; 27 | 28 | %Storage variables for synapse integration 29 | IPSC = zeros(N,1); %post synaptic current 30 | h = zeros(N,1); 31 | r = zeros(N,1); 32 | hr = zeros(N,1); 33 | JD = zeros(N,1); 34 | 35 | %-----Initialization--------------------------------------------- 36 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 37 | v_ = v; %These are just used for Euler integration, previous time step storage 38 | rng(1) 39 | %% Target signal COMMENT OUT TEACHER YOU DONT WANT, COMMENT IN TEACHER YOU WANT. 40 | zx = asin(sin(2*5*pi*(1:1:nt)*dt/1000)); 41 | 42 | %% 43 | k = min(size(zx)); %used to get the dimensionality of the approximant correctly. Typically will be 1 unless you specify a k-dimensional target function. 44 | 45 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 73 | if length(index)>0 74 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 75 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %uncomment this 76 | %if you want to store spike times. Takes longer. 77 | ns = ns + length(index); 78 | end 79 | 80 | %synapse for single exponential 81 | if tr == 0 82 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 83 | r = r *exp(-dt/td) + (v>=vpeak)/td; 84 | else 85 | 86 | %synapse for double exponential 87 | IPSC = IPSC*exp(-dt/tr) + h*dt; 88 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 89 | 90 | r = r*exp(-dt/tr) + hr*dt; 91 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 92 | end 93 | 94 | 95 | z = BPhi'*r; %approximant 96 | err = z - zx(:,i); %error 97 | %% RLS 98 | if mod(i,step)==1 99 | if i > imin 100 | if i < icrit 101 | cd = Pinv*r; 102 | BPhi = BPhi - (cd*err'); 103 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 104 | end 105 | end 106 | end 107 | 108 | 109 | 110 | 111 | %% Store, and plot. 112 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 113 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 114 | v_ = v; % sets v(t-1) = v for the next itteration of loop 115 | REC(i,:) = [v(1:5)',u(1:5)']; 116 | current(i,:) = z'; 117 | RECB(i,:)=BPhi(1:5); 118 | 119 | 120 | if mod(i,round(100/dt))==1 121 | dt*i 122 | drawnow 123 | gg = max(1,i - round(3000/dt)); %only plot for last 3 seconds 124 | figure(2) 125 | plot(dt*(gg:1:i)/1000,zx(:,gg:1:i),'k','LineWidth',2), hold on 126 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:),'b--','LineWidth',2), hold off 127 | xlabel('Time (s)') 128 | ylabel('$\hat{x}(t)$','Interpreter','LaTeX') 129 | legend('Approximant','Target Signal') 130 | xlim([dt*i-3000,dt*i]/1000) 131 | figure(3) 132 | plot((1:1:i)*dt/1000,RECB(1:1:i,:)) 133 | figure(14) 134 | plot(tspike(1:ns,2),tspike(1:ns,1),'k.') 135 | ylim([0,100]) 136 | end 137 | 138 | end 139 | %% 140 | tspike = tspike(tspike(:,2)~=0,:); 141 | M = tspike(tspike(:,2)>dt*icrit); 142 | AverageFiringRate = 1000*length(M)/(N*(T-dt*icrit)) 143 | %% Plotting 144 | figure(30) 145 | for j = 1:1:5 146 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 147 | end 148 | xlim([T/1000-2,T/1000]) 149 | xlabel('Time (s)') 150 | ylabel('Neuron Index') 151 | title('Post Learning') 152 | figure(31) 153 | for j = 1:1:5 154 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 155 | end 156 | xlim([0,imin*dt/1000]) 157 | xlabel('Time (s)') 158 | ylabel('Neuron Index') 159 | title('Pre-Learning') 160 | figure(40) 161 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 162 | Z2 = eig(OMEGA); %eigenvalues before learning 163 | %% plot eigenvalues before and after learning 164 | plot(Z2,'r.'), hold on 165 | plot(Z,'k.') 166 | legend('Pre-Learning','Post-Learning') 167 | xlabel('Re \lambda') 168 | ylabel('Im \lambda') 169 | 170 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/IZHIKEVICH 20/IZFORCESINE.m: -------------------------------------------------------------------------------- 1 | %% Force Method with Izhikevich Network 2 | clear all 3 | close all 4 | clc 5 | 6 | 7 | T = 15000; %Total time in ms 8 | dt = 0.04; %Integration time step in ms 9 | nt = round(T/dt); %Time steps 10 | N = 2000; %Number of neurons 11 | %% Izhikevich Parameters 12 | C = 250; %capacitance 13 | vr = -60; %resting membrane 14 | b = -2; %resonance parameter 15 | ff = 2.5; %k parameter for Izhikevich, gain on v 16 | vpeak = 30; % peak voltage 17 | vreset = -65; % reset voltage 18 | vt = vr+40-(b/ff); %threshold %threshold 19 | u = zeros(N,1); %initialize adaptation 20 | a = 0.01; %adaptation reciprocal time constant 21 | d = 200; %adaptation jump current 22 | tr = 2; %synaptic rise time 23 | td = 20; %decay time 24 | p = 0.1; %sparsity 25 | G =5*10^3; %Gain on the static matrix with 1/sqrt(N) scaling weights. 26 | Q =5*10^3; %Gain on the rank-k perturbation modified by RLS. 27 | Irh = 0.25*ff*(vt-vr)^2; 28 | 29 | %Storage variables for synapse integration 30 | IPSC = zeros(N,1); %post synaptic current 31 | h = zeros(N,1); 32 | r = zeros(N,1); 33 | hr = zeros(N,1); 34 | JD = zeros(N,1); 35 | 36 | %-----Initialization--------------------------------------------- 37 | v = vr+(vpeak-vr)*rand(N,1); %initial distribution 38 | v_ = v; %These are just used for Euler integration, previous time step storage 39 | 40 | %% Target signal COMMENT OUT TEACHER YOU DONT WANT, COMMENT IN TEACHER YOU WANT. 41 | zx = (sin(2*5*pi*(1:1:nt)*dt/1000)); 42 | 43 | %% 44 | k = min(size(zx)); %used to get the dimensionality of the approximant correctly. Typically will be 1 unless you specify a k-dimensional target function. 45 | 46 | OMEGA = G*(randn(N,N)).*(rand(N,N)=vpeak); 74 | if length(index)>0 75 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 76 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; %uncomment this 77 | %if you want to store spike times. Takes longer. 78 | ns = ns + length(index); 79 | end 80 | 81 | %synapse for single exponential 82 | if tr == 0 83 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 84 | r = r *exp(-dt/td) + (v>=vpeak)/td; 85 | else 86 | 87 | %synapse for double exponential 88 | IPSC = IPSC*exp(-dt/tr) + h*dt; 89 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 90 | 91 | r = r*exp(-dt/tr) + hr*dt; 92 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 93 | end 94 | 95 | 96 | z = BPhi'*r; %approximant 97 | err = z - zx(:,i); %error 98 | %% RLS 99 | if mod(i,step)==1 100 | if i > imin 101 | if i < icrit 102 | cd = Pinv*r; 103 | BPhi = BPhi - (cd*err'); 104 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 105 | end 106 | end 107 | end 108 | 109 | 110 | 111 | 112 | %% Store, and plot. 113 | u = u + d*(v>=vpeak); %implements set u to u+d if v>vpeak, component by component. 114 | v = v+(vreset-v).*(v>=vpeak); %implements v = c if v>vpeak add 0 if false, add c-v if true, v+c-v = c 115 | v_ = v; % sets v(t-1) = v for the next itteration of loop 116 | REC(i,:) = [v(1:5)',u(1:5)']; 117 | current(i,:) = z'; 118 | RECB(i,:)=BPhi(1:5); 119 | 120 | 121 | if mod(i,round(100/dt))==1 122 | dt*i 123 | drawnow 124 | gg = max(1,i - round(3000/dt)); %only plot for last 3 seconds 125 | figure(2) 126 | plot(dt*(gg:1:i)/1000,zx(:,gg:1:i),'k','LineWidth',2), hold on 127 | plot(dt*(gg:1:i)/1000,current(gg:1:i,:),'b--','LineWidth',2), hold off 128 | xlabel('Time (s)') 129 | ylabel('$\hat{x}(t)$','Interpreter','LaTeX') 130 | legend('Approximant','Target Signal') 131 | xlim([dt*i-3000,dt*i]/1000) 132 | figure(3) 133 | plot((1:1:i)*dt/1000,RECB(1:1:i,:)) 134 | figure(14) 135 | plot(tspike(1:ns,2),tspike(1:ns,1),'k.') 136 | ylim([0,100]) 137 | end 138 | 139 | end 140 | %% 141 | tspike = tspike(tspike(:,2)~=0,:); 142 | M = tspike(tspike(:,2)>dt*icrit); 143 | AverageFiringRate = 1000*length(M)/(N*(T-dt*icrit)) 144 | %% Plotting 145 | figure(30) 146 | for j = 1:1:5 147 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 148 | end 149 | xlim([T/1000-2,T/1000]) 150 | xlabel('Time (s)') 151 | ylabel('Neuron Index') 152 | title('Post Learning') 153 | figure(31) 154 | for j = 1:1:5 155 | plot((1:1:i)*dt/1000,REC(1:1:i,j)/(vpeak-vreset)+j), hold on 156 | end 157 | xlim([0,imin*dt/1000]) 158 | xlabel('Time (s)') 159 | ylabel('Neuron Index') 160 | title('Pre-Learning') 161 | figure(40) 162 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 163 | Z2 = eig(OMEGA); %eigenvalues before learning 164 | %% plot eigenvalues before and after learning 165 | plot(Z2,'r.'), hold on 166 | plot(Z,'k.') 167 | legend('Pre-Learning','Post-Learning') 168 | xlabel('Re \lambda') 169 | ylabel('Im \lambda') 170 | 171 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/IZHIKEVICH 20/vanderpol.m: -------------------------------------------------------------------------------- 1 | function dy = vanderpol(mu,MD,TC,t,y) 2 | dy(1,1) = mu*(y(1,1)-(y(1,1).^3)*(MD*MD/3) - y(2,1)); 3 | dy(2,1) = y(1,1)/mu; 4 | dy = dy*TC; 5 | end -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 10/LIFFORCEPRODSINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.01; 12 | tr = 0.002; 13 | %% 14 | 15 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 16 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 17 | p = 0.1; %Set the network sparsity 18 | 19 | %% Target Dynamics for Product of Sine Waves 20 | T = 60; imin = round(5/dt); icrit = round(30/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 21 | tx = (1:1:nt)*dt; 22 | zx = sin(8*pi*tx).*sin(12*pi*tx); 23 | 24 | 25 | 26 | %% 27 | k = min(size(zx)); 28 | IPSC = zeros(N,1); %post synaptic current storage variable 29 | h = zeros(N,1); %Storage variable for filtered firing rates 30 | r = zeros(N,1); %second storage variable for filtered rates 31 | hr = zeros(N,1); %Third variable for filtered rates 32 | JD = 0*IPSC; %storage variable required for each spike time 33 | tspike = zeros(4*nt,2); %Storage variable for spike times 34 | ns = 0; %Number of spikes, counts during simulation 35 | z = zeros(k,1); %Initialize the approximant 36 | 37 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 38 | v_ = v; %v_ is the voltage at previous time steps 39 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 40 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 46 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 47 | end 48 | 49 | 50 | E = (2*rand(N,k)-1)*Q; 51 | REC2 = zeros(nt,20); 52 | REC = zeros(nt,10); 53 | current = zeros(nt,k); %storage variable for output current/approximant 54 | i = 1; 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | tlast = zeros(N,1); %This vector is used to set the refractory times 71 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 72 | %% 73 | ilast = i; 74 | %icrit = ilast; 75 | for i = ilast:1:nt 76 | 77 | 78 | I = IPSC + E*z + BIAS; %Neuronal Current 79 | 80 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 81 | v = v + dt*(dv); 82 | 83 | index = find(v>=vpeak); %Find the neurons that have spiked 84 | 85 | 86 | %Store spike times, and get the weight matrix column sum of spikers 87 | if length(index)>0 88 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 89 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 90 | ns = ns + length(index); % total number of psikes so far 91 | end 92 | 93 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 94 | 95 | % Code if the rise time is 0, and if the rise time is positive 96 | if tr == 0 97 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 98 | r = r *exp(-dt/td) + (v>=vpeak)/td; 99 | else 100 | IPSC = IPSC*exp(-dt/tr) + h*dt; 101 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 102 | 103 | r = r*exp(-dt/tr) + hr*dt; 104 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 105 | end 106 | 107 | 108 | 109 | %Implement RLS with the FORCE method 110 | z = BPhi'*r; %approximant 111 | err = z - zx(:,i); %error 112 | %% RLS 113 | if mod(i,step)==1 114 | if i > imin 115 | if i < icrit 116 | cd = Pinv*r; 117 | BPhi = BPhi - (cd*err'); 118 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 119 | end 120 | end 121 | end 122 | 123 | v = v + (30 - v).*(v>=vpeak); 124 | 125 | REC(i,:) = v(1:10); %Record a random voltage 126 | 127 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 128 | current(i,:) = z; 129 | RECB(i,:) = BPhi(1:10); 130 | REC2(i,:) = r(1:20); 131 | 132 | 133 | 134 | if mod(i,round(0.5/dt))==1 135 | dt*i 136 | drawnow 137 | figure(1) 138 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 139 | xlim([dt*i-5,dt*i]) 140 | ylim([0,200]) 141 | figure(2) 142 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 143 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 144 | 145 | xlim([dt*i-5,dt*i]) 146 | %ylim([-0.5,0.5]) 147 | 148 | %xlim([dt*i,dt*i]) 149 | figure(5) 150 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 151 | end 152 | end 153 | time = 1:1:nt; 154 | %% 155 | TotNumSpikes = ns 156 | tspike = tspike(1:1:ns,:); 157 | M = tspike(tspike(:,2)>dt*icrit,:); 158 | AverageRate = length(M)/(N*(T-dt*icrit)) 159 | 160 | %% Plotting 161 | figure(30) 162 | for j = 1:1:5 163 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 164 | end 165 | xlim([T-2,T]) 166 | xlabel('Time (s)') 167 | ylabel('Neuron Index') 168 | title('Post Learning') 169 | figure(31) 170 | for j = 1:1:5 171 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 172 | end 173 | xlim([0,2]) 174 | xlabel('Time (s)') 175 | ylabel('Neuron Index') 176 | title('Pre-Learning') 177 | %% 178 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 179 | Z2 = eig(OMEGA); %eigenvalues before learning 180 | %% Plot eigenvalues before and after learning 181 | figure(40) 182 | plot(Z2,'r.'), hold on 183 | plot(Z,'k.') 184 | legend('Pre-Learning','Post-Learning') 185 | xlabel('Re \lambda') 186 | ylabel('Im \lambda') 187 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 10/LIFFORCEPRODSINENOISE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.01; 12 | tr = 0.002; 13 | %% 14 | 15 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 16 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 17 | p = 0.1; %Set the network sparsity 18 | 19 | %% Target Dynamics for Product of Sine Waves 20 | T = 60; imin = round(5/dt); icrit = round(30/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 21 | tx = (1:1:nt)*dt; 22 | zx = sin(8*pi*tx).*sin(12*pi*tx)+0.05*rand(1,nt); 23 | 24 | 25 | 26 | 27 | %% 28 | k = min(size(zx)); 29 | IPSC = zeros(N,1); %post synaptic current storage variable 30 | h = zeros(N,1); %Storage variable for filtered firing rates 31 | r = zeros(N,1); %second storage variable for filtered rates 32 | hr = zeros(N,1); %Third variable for filtered rates 33 | JD = 0*IPSC; %storage variable required for each spike time 34 | tspike = zeros(4*nt,2); %Storage variable for spike times 35 | ns = 0; %Number of spikes, counts during simulation 36 | z = zeros(k,1); %Initialize the approximant 37 | 38 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 39 | v_ = v; %v_ is the voltage at previous time steps 40 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 41 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 47 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 48 | end 49 | 50 | 51 | E = (2*rand(N,k)-1)*Q; %n 52 | REC2 = zeros(nt,20); 53 | REC = zeros(nt,10); 54 | current = zeros(nt,k); %storage variable for output current/approximant 55 | i = 1; 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | tlast = zeros(N,1); %This vector is used to set the refractory times 72 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 73 | %% 74 | ilast = i; 75 | %icrit = ilast; 76 | for i = ilast:1:nt 77 | 78 | 79 | I = IPSC + E*z + BIAS; %Neuronal Current 80 | 81 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 82 | v = v + dt*(dv); 83 | 84 | index = find(v>=vpeak); %Find the neurons that have spiked 85 | 86 | 87 | %Store spike times, and get the weight matrix column sum of spikers 88 | if length(index)>0 89 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 90 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 91 | ns = ns + length(index); % total number of psikes so far 92 | end 93 | 94 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 95 | 96 | % Code if the rise time is 0, and if the rise time is positive 97 | if tr == 0 98 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 99 | r = r *exp(-dt/td) + (v>=vpeak)/td; 100 | else 101 | IPSC = IPSC*exp(-dt/tr) + h*dt; 102 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 103 | 104 | r = r*exp(-dt/tr) + hr*dt; 105 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 106 | end 107 | 108 | 109 | 110 | %Implement RLS with the FORCE method 111 | z = BPhi'*r; %approximant 112 | err = z - zx(:,i); %error 113 | %% RLS 114 | if mod(i,step)==1 115 | if i > imin 116 | if i < icrit 117 | cd = Pinv*r; 118 | BPhi = BPhi - (cd*err'); 119 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 120 | end 121 | end 122 | end 123 | 124 | v = v + (30 - v).*(v>=vpeak); 125 | 126 | REC(i,:) = v(1:10); %Record a random voltage 127 | 128 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 129 | current(i,:) = z; 130 | RECB(i,:) = BPhi(1:10); 131 | REC2(i,:) = r(1:20); 132 | 133 | 134 | 135 | if mod(i,round(0.5/dt))==1 136 | dt*i 137 | drawnow 138 | figure(1) 139 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 140 | xlim([dt*i-5,dt*i]) 141 | ylim([0,200]) 142 | figure(2) 143 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 144 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 145 | 146 | xlim([dt*i-5,dt*i]) 147 | %ylim([-0.5,0.5]) 148 | 149 | %xlim([dt*i,dt*i]) 150 | figure(5) 151 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 152 | end 153 | end 154 | time = 1:1:nt; 155 | %% 156 | TotNumSpikes = ns 157 | tspike = tspike(1:1:ns,:); 158 | M = tspike(tspike(:,2)>dt*icrit,:); 159 | AverageRate = length(M)/(N*(T-dt*icrit)) 160 | 161 | %% Plotting 162 | figure(30) 163 | for j = 1:1:5 164 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 165 | end 166 | xlim([T-2,T]) 167 | xlabel('Time (s)') 168 | ylabel('Neuron Index') 169 | title('Post Learning') 170 | figure(31) 171 | for j = 1:1:5 172 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 173 | end 174 | xlim([0,2]) 175 | xlabel('Time (s)') 176 | ylabel('Neuron Index') 177 | title('Pre-Learning') 178 | %% 179 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 180 | Z2 = eig(OMEGA); %eigenvalues before learning 181 | %% plot eigenvalues before and after learning 182 | figure(40) 183 | plot(Z2,'r.'), hold on 184 | plot(Z,'k.') 185 | legend('Pre-Learning','Post-Learning') 186 | xlabel('Re \lambda') 187 | ylabel('Im \lambda') 188 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCEPRODSINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.02; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 60; imin = round(5/dt); icrit = round(30/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 20 | tx = (1:1:nt)*dt; 21 | zx = sin(8*pi*tx).*sin(12*pi*tx); 22 | 23 | 24 | 25 | %% 26 | k = min(size(zx)); 27 | IPSC = zeros(N,1); %post synaptic current storage variable 28 | h = zeros(N,1); %Storage variable for filtered firing rates 29 | r = zeros(N,1); %second storage variable for filtered rates 30 | hr = zeros(N,1); %Third variable for filtered rates 31 | JD = 0*IPSC; %storage variable required for each spike time 32 | tspike = zeros(4*nt,2); %Storage variable for spike times 33 | ns = 0; %Number of spikes, counts during simulation 34 | z = zeros(k,1); %Initialize the approximant 35 | 36 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 37 | v_ = v; %v_ is the voltage at previous time steps 38 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 39 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 45 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 46 | end 47 | 48 | 49 | E = (2*rand(N,k)-1)*Q; %n 50 | REC2 = zeros(nt,20); 51 | REC = zeros(nt,10); 52 | current = zeros(nt,k); %storage variable for output current/approximant 53 | i = 1; 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | tlast = zeros(N,1); %This vector is used to set the refractory times 70 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 71 | %% 72 | ilast = i; 73 | %icrit = ilast; 74 | for i = ilast:1:nt 75 | 76 | 77 | I = IPSC + E*z + BIAS; %Neuronal Current 78 | 79 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 80 | v = v + dt*(dv); 81 | 82 | index = find(v>=vpeak); %Find the neurons that have spiked 83 | 84 | 85 | %Store spike times, and get the weight matrix column sum of spikers 86 | if length(index)>0 87 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 88 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 89 | ns = ns + length(index); % total number of psikes so far 90 | end 91 | 92 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 93 | 94 | % Code if the rise time is 0, and if the rise time is positive 95 | if tr == 0 96 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 97 | r = r *exp(-dt/td) + (v>=vpeak)/td; 98 | else 99 | IPSC = IPSC*exp(-dt/tr) + h*dt; 100 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 101 | 102 | r = r*exp(-dt/tr) + hr*dt; 103 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 104 | end 105 | 106 | 107 | 108 | %Implement RLS with the FORCE method 109 | z = BPhi'*r; %approximant 110 | err = z - zx(:,i); %error 111 | %% RLS 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | v = v + (30 - v).*(v>=vpeak); 123 | 124 | REC(i,:) = v(1:10); %Record a random voltage 125 | 126 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 127 | current(i,:) = z; 128 | RECB(i,:) = BPhi(1:10); 129 | REC2(i,:) = r(1:20); 130 | 131 | 132 | 133 | if mod(i,round(0.5/dt))==1 134 | dt*i 135 | drawnow 136 | figure(1) 137 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 138 | xlim([dt*i-5,dt*i]) 139 | ylim([0,200]) 140 | figure(2) 141 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 142 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 143 | 144 | xlim([dt*i-5,dt*i]) 145 | %ylim([-0.5,0.5]) 146 | 147 | %xlim([dt*i,dt*i]) 148 | figure(5) 149 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 150 | end 151 | end 152 | time = 1:1:nt; 153 | %% 154 | TotNumSpikes = ns 155 | tspike = tspike(1:1:ns,:); 156 | M = tspike(tspike(:,2)>dt*icrit,:); 157 | AverageRate = length(M)/(N*(T-dt*icrit)) 158 | 159 | %% Plotting 160 | figure(30) 161 | for j = 1:1:5 162 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 163 | end 164 | xlim([T-2,T]) 165 | xlabel('Time (s)') 166 | ylabel('Neuron Index') 167 | title('Post Learning') 168 | figure(31) 169 | for j = 1:1:5 170 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 171 | end 172 | xlim([0,2]) 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | title('Pre-Learning') 176 | %% 177 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 178 | Z2 = eig(OMEGA); %eigenvalues before learning 179 | %% Plotting Eigenvalues before and after learning 180 | figure(40) 181 | plot(Z2,'r.'), hold on 182 | plot(Z,'k.') 183 | legend('Pre-Learning','Post-Learning') 184 | xlabel('Re \lambda') 185 | ylabel('Im \lambda') 186 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCEPRODSINENOISE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.02; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 60; imin = round(5/dt); icrit = round(30/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 20 | tx = (1:1:nt)*dt; 21 | zx = sin(8*pi*tx).*sin(12*pi*tx)+0.05*randn(1,nt); 22 | 23 | 24 | 25 | 26 | %% 27 | k = min(size(zx)); 28 | IPSC = zeros(N,1); %post synaptic current storage variable 29 | h = zeros(N,1); %Storage variable for filtered firing rates 30 | r = zeros(N,1); %second storage variable for filtered rates 31 | hr = zeros(N,1); %Third variable for filtered rates 32 | JD = 0*IPSC; %storage variable required for each spike time 33 | tspike = zeros(4*nt,2); %Storage variable for spike times 34 | ns = 0; %Number of spikes, counts during simulation 35 | z = zeros(k,1); %Initialize the approximant 36 | 37 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 38 | v_ = v; %v_ is the voltage at previous time steps 39 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 40 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 46 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 47 | end 48 | 49 | 50 | E = (2*rand(N,k)-1)*Q; %n 51 | REC2 = zeros(nt,20); 52 | REC = zeros(nt,10); 53 | current = zeros(nt,k); %storage variable for output current/approximant 54 | i = 1; 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | tlast = zeros(N,1); %This vector is used to set the refractory times 71 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 72 | %% 73 | ilast = i; 74 | %icrit = ilast; 75 | for i = ilast:1:nt 76 | 77 | 78 | I = IPSC + E*z + BIAS; %Neuronal Current 79 | 80 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 81 | v = v + dt*(dv); 82 | 83 | index = find(v>=vpeak); %Find the neurons that have spiked 84 | 85 | 86 | %Store spike times, and get the weight matrix column sum of spikers 87 | if length(index)>0 88 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 89 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 90 | ns = ns + length(index); % total number of psikes so far 91 | end 92 | 93 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 94 | 95 | % Code if the rise time is 0, and if the rise time is positive 96 | if tr == 0 97 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 98 | r = r *exp(-dt/td) + (v>=vpeak)/td; 99 | else 100 | IPSC = IPSC*exp(-dt/tr) + h*dt; 101 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 102 | 103 | r = r*exp(-dt/tr) + hr*dt; 104 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 105 | end 106 | 107 | 108 | 109 | %Implement RLS with the FORCE method 110 | z = BPhi'*r; %approximant 111 | err = z - zx(:,i); %error 112 | %% RLS 113 | if mod(i,step)==1 114 | if i > imin 115 | if i < icrit 116 | cd = Pinv*r; 117 | BPhi = BPhi - (cd*err'); 118 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 119 | end 120 | end 121 | end 122 | 123 | v = v + (30 - v).*(v>=vpeak); 124 | 125 | REC(i,:) = v(1:10); %Record a random voltage 126 | 127 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 128 | current(i,:) = z; 129 | RECB(i,:) = BPhi(1:10); 130 | REC2(i,:) = r(1:20); 131 | 132 | 133 | 134 | if mod(i,round(0.5/dt))==1 135 | dt*i 136 | drawnow 137 | figure(1) 138 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 139 | xlim([dt*i-5,dt*i]) 140 | ylim([0,200]) 141 | figure(2) 142 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 143 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 144 | 145 | xlim([dt*i-5,dt*i]) 146 | %ylim([-0.5,0.5]) 147 | 148 | %xlim([dt*i,dt*i]) 149 | figure(5) 150 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 151 | end 152 | end 153 | time = 1:1:nt; 154 | %% 155 | TotNumSpikes = ns 156 | tspike = tspike(1:1:ns,:); 157 | M = tspike(tspike(:,2)>dt*icrit,:); 158 | AverageRate = length(M)/(N*(T-dt*icrit)) 159 | 160 | %% Plotting 161 | figure(30) 162 | for j = 1:1:5 163 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 164 | end 165 | xlim([T-2,T]) 166 | xlabel('Time (s)') 167 | ylabel('Neuron Index') 168 | title('Post Learning') 169 | figure(31) 170 | for j = 1:1:5 171 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 172 | end 173 | xlim([0,2]) 174 | xlabel('Time (s)') 175 | ylabel('Neuron Index') 176 | title('Pre-Learning') 177 | %% 178 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 179 | Z2 = eig(OMEGA); %eigenvalues before learning 180 | %% Plot eigenvalues before and after learning 181 | figure(40) 182 | plot(Z2,'r.'), hold on 183 | plot(Z,'k.') 184 | legend('Pre-Learning','Post-Learning') 185 | xlabel('Re \lambda') 186 | ylabel('Im \lambda') 187 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCESAWTOOTH.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.02; 12 | tr = 0.002; 13 | %% 14 | 15 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 16 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 17 | p = 0.1; %Set the network sparsity 18 | 19 | %% Target Dynamics for Product of Sine Waves 20 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 21 | zx = asin(sin(2*pi*(1:1:nt)*dt*5)); 22 | 23 | 24 | 25 | %% 26 | k = min(size(zx)); 27 | IPSC = zeros(N,1); %post synaptic current storage variable 28 | h = zeros(N,1); %Storage variable for filtered firing rates 29 | r = zeros(N,1); %second storage variable for filtered rates 30 | hr = zeros(N,1); %Third variable for filtered rates 31 | JD = 0*IPSC; %storage variable required for each spike time 32 | tspike = zeros(4*nt,2); %Storage variable for spike times 33 | ns = 0; %Number of spikes, counts during simulation 34 | z = zeros(k,1); %Initialize the approximant 35 | 36 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 37 | v_ = v; %v_ is the voltage at previous time steps 38 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 39 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 45 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 46 | end 47 | 48 | 49 | E = (2*rand(N,k)-1)*Q; %n 50 | REC2 = zeros(nt,20); 51 | REC = zeros(nt,10); 52 | current = zeros(nt,k); %storage variable for output current/approximant 53 | i = 1; 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | tlast = zeros(N,1); %This vector is used to set the refractory times 70 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 71 | %% 72 | ilast = i; 73 | %icrit = ilast; 74 | for i = ilast:1:nt 75 | 76 | 77 | I = IPSC + E*z + BIAS; %Neuronal Current 78 | 79 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 80 | v = v + dt*(dv); 81 | 82 | index = find(v>=vpeak); %Find the neurons that have spiked 83 | 84 | 85 | %Store spike times, and get the weight matrix column sum of spikers 86 | if length(index)>0 87 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 88 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 89 | ns = ns + length(index); % total number of psikes so far 90 | end 91 | 92 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 93 | 94 | % Code if the rise time is 0, and if the rise time is positive 95 | if tr == 0 96 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 97 | r = r *exp(-dt/td) + (v>=vpeak)/td; 98 | else 99 | IPSC = IPSC*exp(-dt/tr) + h*dt; 100 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 101 | 102 | r = r*exp(-dt/tr) + hr*dt; 103 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 104 | end 105 | 106 | 107 | 108 | %Implement RLS with the FORCE method 109 | z = BPhi'*r; %approximant 110 | err = z - zx(:,i); %error 111 | %% RLS 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | v = v + (30 - v).*(v>=vpeak); 123 | 124 | REC(i,:) = v(1:10); %Record a random voltage 125 | 126 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 127 | current(i,:) = z; 128 | RECB(i,:) = BPhi(1:10); 129 | REC2(i,:) = r(1:20); 130 | 131 | 132 | 133 | if mod(i,round(0.5/dt))==1 134 | dt*i 135 | drawnow 136 | figure(1) 137 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 138 | xlim([dt*i-5,dt*i]) 139 | ylim([0,200]) 140 | figure(2) 141 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 142 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 143 | 144 | xlim([dt*i-5,dt*i]) 145 | %ylim([-0.5,0.5]) 146 | 147 | %xlim([dt*i,dt*i]) 148 | figure(5) 149 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 150 | end 151 | end 152 | time = 1:1:nt; 153 | %% 154 | TotNumSpikes = ns 155 | tspike = tspike(1:1:ns,:); 156 | M = tspike(tspike(:,2)>dt*icrit,:); 157 | AverageRate = length(M)/(N*(T-dt*icrit)) 158 | 159 | %% Plotting 160 | figure(30) 161 | for j = 1:1:5 162 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 163 | end 164 | xlim([T-2,T]) 165 | xlabel('Time (s)') 166 | ylabel('Neuron Index') 167 | title('Post Learning') 168 | figure(31) 169 | for j = 1:1:5 170 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 171 | end 172 | xlim([0,2]) 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | title('Pre-Learning') 176 | %% 177 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 178 | Z2 = eig(OMEGA); %eigenvalues before learning 179 | %% Plot eigenvalues before and after learning 180 | figure(40) 181 | plot(Z2,'r.'), hold on 182 | plot(Z,'k.') 183 | legend('Pre-Learning','Post-Learning') 184 | xlabel('Re \lambda') 185 | ylabel('Im \lambda') 186 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCESINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.02; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 20 | zx = (sin(2*pi*(1:1:nt)*dt*5)); 21 | 22 | 23 | 24 | %% 25 | k = min(size(zx)); 26 | IPSC = zeros(N,1); %post synaptic current storage variable 27 | h = zeros(N,1); %Storage variable for filtered firing rates 28 | r = zeros(N,1); %second storage variable for filtered rates 29 | hr = zeros(N,1); %Third variable for filtered rates 30 | JD = 0*IPSC; %storage variable required for each spike time 31 | tspike = zeros(4*nt,2); %Storage variable for spike times 32 | ns = 0; %Number of spikes, counts during simulation 33 | z = zeros(k,1); %Initialize the approximant 34 | 35 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 36 | v_ = v; %v_ is the voltage at previous time steps 37 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 38 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 44 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 45 | end 46 | 47 | 48 | E = (2*rand(N,k)-1)*Q; 49 | REC2 = zeros(nt,20); 50 | REC = zeros(nt,10); 51 | current = zeros(nt,k); %storage variable for output current/approximant 52 | i = 1; 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | tlast = zeros(N,1); %This vector is used to set the refractory times 69 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 70 | %% 71 | ilast = i; 72 | %icrit = ilast; 73 | for i = ilast:1:nt 74 | 75 | 76 | I = IPSC + E*z + BIAS; %Neuronal Current 77 | 78 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 79 | v = v + dt*(dv); 80 | 81 | index = find(v>=vpeak); %Find the neurons that have spiked 82 | 83 | 84 | %Store spike times, and get the weight matrix column sum of spikers 85 | if length(index)>0 86 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 87 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 88 | ns = ns + length(index); % total number of psikes so far 89 | end 90 | 91 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 92 | 93 | % Code if the rise time is 0, and if the rise time is positive 94 | if tr == 0 95 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 96 | r = r *exp(-dt/td) + (v>=vpeak)/td; 97 | else 98 | IPSC = IPSC*exp(-dt/tr) + h*dt; 99 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 100 | 101 | r = r*exp(-dt/tr) + hr*dt; 102 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 103 | end 104 | 105 | 106 | 107 | %Implement RLS with the FORCE method 108 | z = BPhi'*r; %approximant 109 | err = z - zx(:,i); %error 110 | %% RLS 111 | if mod(i,step)==1 112 | if i > imin 113 | if i < icrit 114 | cd = Pinv*r; 115 | BPhi = BPhi - (cd*err'); 116 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 117 | end 118 | end 119 | end 120 | 121 | v = v + (30 - v).*(v>=vpeak); 122 | 123 | REC(i,:) = v(1:10); %Record a random voltage 124 | 125 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 126 | current(i,:) = z; 127 | RECB(i,:) = BPhi(1:10); 128 | REC2(i,:) = r(1:20); 129 | 130 | 131 | 132 | if mod(i,round(0.5/dt))==1 133 | dt*i 134 | drawnow 135 | figure(1) 136 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 137 | xlim([dt*i-5,dt*i]) 138 | ylim([0,200]) 139 | figure(2) 140 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 141 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 142 | 143 | xlim([dt*i-5,dt*i]) 144 | %ylim([-0.5,0.5]) 145 | 146 | %xlim([dt*i,dt*i]) 147 | figure(5) 148 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 149 | end 150 | end 151 | time = 1:1:nt; 152 | %% 153 | TotNumSpikes = ns 154 | %tspike = tspike(1:1:ns,:); 155 | M = tspike(tspike(:,2)>dt*icrit,:); 156 | AverageRate = length(M)/(N*(T-dt*icrit)) 157 | 158 | %% Plotting 159 | figure(30) 160 | for j = 1:1:5 161 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 162 | end 163 | xlim([T-2,T]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(31) 168 | for j = 1:1:5 169 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 170 | end 171 | xlim([0,2]) 172 | xlabel('Time (s)') 173 | ylabel('Neuron Index') 174 | title('Pre-Learning') 175 | %% 176 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 177 | Z2 = eig(OMEGA); %eigenvalues before learning 178 | %% Plot eigenvalues before and after learning 179 | figure(40) 180 | plot(Z2,'r.'), hold on 181 | plot(Z,'k.') 182 | legend('Pre-Learning','Post-Learning') 183 | xlabel('Re \lambda') 184 | ylabel('Im \lambda') 185 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCEVDPHARMONIC.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.02; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.05; 20 | mu = 0.5; %Sets the behavior 21 | MD = 10; %Scale system in space 22 | TC = 20; %Scale system in time 23 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 24 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 25 | tx = (1:1:nt)*dt; 26 | zx(:,1) = interp1(t,y(:,1),tx); 27 | zx(:,2) = interp1(t,y(:,2),tx); 28 | zx = zx'; 29 | 30 | 31 | 32 | 33 | %% 34 | k = min(size(zx)); 35 | IPSC = zeros(N,1); %post synaptic current storage variable 36 | h = zeros(N,1); %Storage variable for filtered firing rates 37 | r = zeros(N,1); %second storage variable for filtered rates 38 | hr = zeros(N,1); %Third variable for filtered rates 39 | JD = 0*IPSC; %storage variable required for each spike time 40 | tspike = zeros(4*nt,2); %Storage variable for spike times 41 | ns = 0; %Number of spikes, counts during simulation 42 | z = zeros(k,1); %Initialize the approximant 43 | 44 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 45 | v_ = v; %v_ is the voltage at previous time steps 46 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 47 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 53 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 54 | end 55 | 56 | 57 | E = (2*rand(N,k)-1)*Q; %n 58 | REC2 = zeros(nt,20); 59 | REC = zeros(nt,10); 60 | current = zeros(nt,k); %storage variable for output current/approximant 61 | i = 1; 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | tlast = zeros(N,1); %This vector is used to set the refractory times 78 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 79 | %% 80 | ilast = i; 81 | %icrit = ilast; 82 | for i = ilast:1:nt 83 | 84 | 85 | I = IPSC + E*z + BIAS; %Neuronal Current 86 | 87 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 88 | v = v + dt*(dv); 89 | 90 | index = find(v>=vpeak); %Find the neurons that have spiked 91 | 92 | 93 | %Store spike times, and get the weight matrix column sum of spikers 94 | if length(index)>0 95 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 96 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 97 | ns = ns + length(index); % total number of psikes so far 98 | end 99 | 100 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 101 | 102 | % Code if the rise time is 0, and if the rise time is positive 103 | if tr == 0 104 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 105 | r = r *exp(-dt/td) + (v>=vpeak)/td; 106 | else 107 | IPSC = IPSC*exp(-dt/tr) + h*dt; 108 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 109 | 110 | r = r*exp(-dt/tr) + hr*dt; 111 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 112 | end 113 | 114 | 115 | 116 | %Implement RLS with the FORCE method 117 | z = BPhi'*r; %approximant 118 | err = z - zx(:,i); %error 119 | %% RLS 120 | if mod(i,step)==1 121 | if i > imin 122 | if i < icrit 123 | cd = Pinv*r; 124 | BPhi = BPhi - (cd*err'); 125 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 126 | end 127 | end 128 | end 129 | 130 | v = v + (30 - v).*(v>=vpeak); 131 | 132 | REC(i,:) = v(1:10); %Record a random voltage 133 | 134 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 135 | current(i,:) = z; 136 | RECB(i,:) = BPhi(1:10); 137 | REC2(i,:) = r(1:20); 138 | 139 | 140 | 141 | if mod(i,round(0.5/dt))==1 142 | dt*i 143 | drawnow 144 | figure(1) 145 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 146 | xlim([dt*i-5,dt*i]) 147 | ylim([0,200]) 148 | figure(2) 149 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 150 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 151 | 152 | xlim([dt*i-5,dt*i]) 153 | %ylim([-0.5,0.5]) 154 | 155 | %xlim([dt*i,dt*i]) 156 | figure(5) 157 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 158 | end 159 | end 160 | time = 1:1:nt; 161 | %% 162 | TotNumSpikes = ns 163 | tspike = tspike(1:1:ns,:); 164 | M = tspike(tspike(:,2)>dt*icrit,:); 165 | AverageRate = length(M)/(N*(T-dt*icrit)) 166 | 167 | %% Plotting 168 | figure(30) 169 | for j = 1:1:5 170 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 171 | end 172 | xlim([T-2,T]) 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | title('Post Learning') 176 | figure(31) 177 | for j = 1:1:5 178 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 179 | end 180 | xlim([0,2]) 181 | xlabel('Time (s)') 182 | ylabel('Neuron Index') 183 | title('Pre-Learning') 184 | %% 185 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 186 | Z2 = eig(OMEGA); %eigenvalues before learning 187 | %% Plot eigenvalues before and after learning 188 | figure(40) 189 | plot(Z2,'r.'), hold on 190 | plot(Z,'k.') 191 | legend('Pre-Learning','Post-Learning') 192 | xlabel('Re \lambda') 193 | ylabel('Im \lambda') 194 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/LIFFORCEVDPRELAXATION.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | 12 | td = 0.02; 13 | tr = 0.002; 14 | %% 15 | 16 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 17 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 18 | p = 0.1; %Set the network sparsity 19 | 20 | %% Target Dynamics for Product of Sine Waves 21 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.05; 22 | mu = 5; %Sets the behavior 23 | MD = 10; %Scale system in space 24 | TC = 20; %Scale system in time 25 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 26 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 27 | tx = (1:1:nt)*dt; 28 | zx(:,1) = interp1(t,y(:,1),tx); 29 | zx(:,2) = interp1(t,y(:,2),tx); 30 | zx = zx'; 31 | 32 | 33 | 34 | 35 | %% 36 | k = min(size(zx)); 37 | IPSC = zeros(N,1); %post synaptic current storage variable 38 | h = zeros(N,1); %Storage variable for filtered firing rates 39 | r = zeros(N,1); %second storage variable for filtered rates 40 | hr = zeros(N,1); %Third variable for filtered rates 41 | JD = 0*IPSC; %storage variable required for each spike time 42 | tspike = zeros(4*nt,2); %Storage variable for spike times 43 | ns = 0; %Number of spikes, counts during simulation 44 | z = zeros(k,1); %Initialize the approximant 45 | 46 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 47 | v_ = v; %v_ is the voltage at previous time steps 48 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 49 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 55 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 56 | end 57 | 58 | 59 | E = (2*rand(N,k)-1)*Q; %n 60 | REC2 = zeros(nt,20); 61 | REC = zeros(nt,10); 62 | current = zeros(nt,k); %storage variable for output current/approximant 63 | i = 1; 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | tlast = zeros(N,1); %This vector is used to set the refractory times 80 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 81 | %% 82 | ilast = i; 83 | %icrit = ilast; 84 | for i = ilast:1:nt 85 | 86 | 87 | I = IPSC + E*z + BIAS; %Neuronal Current 88 | 89 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 90 | v = v + dt*(dv); 91 | 92 | index = find(v>=vpeak); %Find the neurons that have spiked 93 | 94 | 95 | %Store spike times, and get the weight matrix column sum of spikers 96 | if length(index)>0 97 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 98 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 99 | ns = ns + length(index); % total number of psikes so far 100 | end 101 | 102 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 103 | 104 | % Code if the rise time is 0, and if the rise time is positive 105 | if tr == 0 106 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 107 | r = r *exp(-dt/td) + (v>=vpeak)/td; 108 | else 109 | IPSC = IPSC*exp(-dt/tr) + h*dt; 110 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 111 | 112 | r = r*exp(-dt/tr) + hr*dt; 113 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 114 | end 115 | 116 | 117 | 118 | %Implement RLS with the FORCE method 119 | z = BPhi'*r; %approximant 120 | err = z - zx(:,i); %error 121 | %% RLS 122 | if mod(i,step)==1 123 | if i > imin 124 | if i < icrit 125 | cd = Pinv*r; 126 | BPhi = BPhi - (cd*err'); 127 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 128 | end 129 | end 130 | end 131 | 132 | v = v + (30 - v).*(v>=vpeak); 133 | 134 | REC(i,:) = v(1:10); %Record a random voltage 135 | 136 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 137 | current(i,:) = z; 138 | RECB(i,:) = BPhi(1:10); 139 | REC2(i,:) = r(1:20); 140 | 141 | 142 | 143 | if mod(i,round(0.5/dt))==1 144 | dt*i 145 | drawnow 146 | figure(1) 147 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 148 | xlim([dt*i-5,dt*i]) 149 | ylim([0,200]) 150 | figure(2) 151 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 152 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 153 | 154 | xlim([dt*i-5,dt*i]) 155 | %ylim([-0.5,0.5]) 156 | 157 | %xlim([dt*i,dt*i]) 158 | figure(5) 159 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 160 | end 161 | end 162 | time = 1:1:nt; 163 | %% 164 | TotNumSpikes = ns 165 | tspike = tspike(1:1:ns,:); 166 | M = tspike(tspike(:,2)>dt*icrit,:); 167 | AverageRate = length(M)/(N*(T-dt*icrit)) 168 | 169 | %% Plotting 170 | figure(30) 171 | for j = 1:1:5 172 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 173 | end 174 | xlim([T-2,T]) 175 | xlabel('Time (s)') 176 | ylabel('Neuron Index') 177 | title('Post Learning') 178 | figure(31) 179 | for j = 1:1:5 180 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 181 | end 182 | xlim([0,2]) 183 | xlabel('Time (s)') 184 | ylabel('Neuron Index') 185 | title('Pre-Learning') 186 | %% 187 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 188 | Z2 = eig(OMEGA); %eigenvalues before learning 189 | %% Plot eigenvalues before and after learning 190 | figure(40) 191 | plot(Z2,'r.'), hold on 192 | plot(Z,'k.') 193 | legend('Pre-Learning','Post-Learning') 194 | xlabel('Re \lambda') 195 | ylabel('Im \lambda') 196 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 20/vanderpol.m: -------------------------------------------------------------------------------- 1 | function dy = vanderpol(mu,MD,TC,t,y) 2 | dy(1,1) = mu*(y(1,1)-(y(1,1).^3)*(MD*MD/3) - y(2,1)); 3 | dy(2,1) = y(1,1)/mu; 4 | dy = dy*TC; 5 | end -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCEPRODSINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | 12 | td = 0.03; 13 | tr = 0.002; 14 | %% 15 | 16 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 17 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLMS 18 | p = 0.1; %Set the network sparsity 19 | 20 | %% Target Dynamics for Product of Sine Waves 21 | T = 60; imin = round(5/dt); icrit = round(25/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.1; 22 | tx = (1:1:nt)*dt; 23 | zx = sin(8*pi*tx).*sin(12*pi*tx); 24 | 25 | 26 | 27 | %% 28 | k = min(size(zx)); 29 | IPSC = zeros(N,1); %post synaptic current storage variable 30 | h = zeros(N,1); %Storage variable for filtered firing rates 31 | r = zeros(N,1); %second storage variable for filtered rates 32 | hr = zeros(N,1); %Third variable for filtered rates 33 | JD = 0*IPSC; %storage variable required for each spike time 34 | tspike = zeros(4*nt,2); %Storage variable for spike times 35 | ns = 0; %Number of spikes, counts during simulation 36 | z = zeros(k,1); %Initialize the approximant 37 | 38 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 39 | v_ = v; %v_ is the voltage at previous time steps 40 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 41 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 47 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 48 | end 49 | 50 | 51 | E = (2*rand(N,k)-1)*Q; %n 52 | REC2 = zeros(nt,20); 53 | REC = zeros(nt,10); 54 | current = zeros(nt,k); %storage variable for output current/approximant 55 | i = 1; 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | tlast = zeros(N,1); %This vector is used to set the refractory times 72 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 73 | %% 74 | ilast = i; 75 | %icrit = ilast; 76 | for i = ilast:1:nt 77 | 78 | 79 | I = IPSC + E*z + BIAS; %Neuronal Current 80 | 81 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 82 | v = v + dt*(dv); 83 | 84 | index = find(v>=vpeak); %Find the neurons that have spiked 85 | 86 | 87 | %Store spike times, and get the weight matrix column sum of spikers 88 | if length(index)>0 89 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 90 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 91 | ns = ns + length(index); % total number of psikes so far 92 | end 93 | 94 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 95 | 96 | % Code if the rise time is 0, and if the rise time is positive 97 | if tr == 0 98 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 99 | r = r *exp(-dt/td) + (v>=vpeak)/td; 100 | else 101 | IPSC = IPSC*exp(-dt/tr) + h*dt; 102 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 103 | 104 | r = r*exp(-dt/tr) + hr*dt; 105 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 106 | end 107 | 108 | 109 | 110 | %Implement RLMS with the FORCE method 111 | z = BPhi'*r; %approximant 112 | err = z - zx(:,i); %error 113 | %% RLMS 114 | if mod(i,step)==1 115 | if i > imin 116 | if i < icrit 117 | cd = Pinv*r; 118 | BPhi = BPhi - (cd*err'); 119 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 120 | end 121 | end 122 | end 123 | 124 | v = v + (30 - v).*(v>=vpeak); 125 | 126 | REC(i,:) = v(1:10); %Record a random voltage 127 | 128 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 129 | current(i,:) = z; 130 | RECB(i,:) = BPhi(1:10); 131 | REC2(i,:) = r(1:20); 132 | 133 | 134 | 135 | if mod(i,round(0.5/dt))==1 136 | dt*i 137 | drawnow 138 | figure(1) 139 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 140 | xlim([dt*i-5,dt*i]) 141 | ylim([0,200]) 142 | figure(2) 143 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 144 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 145 | 146 | xlim([dt*i-5,dt*i]) 147 | %ylim([-0.5,0.5]) 148 | 149 | %xlim([dt*i,dt*i]) 150 | figure(5) 151 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 152 | end 153 | end 154 | time = 1:1:nt; 155 | %% 156 | TotNumSpikes = ns 157 | tspike = tspike(1:1:ns,:); 158 | M = tspike(tspike(:,2)>dt*icrit,:); 159 | AverageRate = length(M)/(N*(T-dt*icrit)) 160 | 161 | %% Plotting 162 | figure(30) 163 | for j = 1:1:5 164 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 165 | end 166 | xlim([T-2,T]) 167 | xlabel('Time (s)') 168 | ylabel('Neuron Index') 169 | title('Post Learning') 170 | figure(31) 171 | for j = 1:1:5 172 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 173 | end 174 | xlim([0,2]) 175 | xlabel('Time (s)') 176 | ylabel('Neuron Index') 177 | title('Pre-Learning') 178 | %% 179 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 180 | Z2 = eig(OMEGA); %eigenvalues before learning 181 | %% Plot eigenvalues before and after learning 182 | figure(40) 183 | plot(Z2,'r.'), hold on 184 | plot(Z,'k.') 185 | legend('Pre-Learning','Post-Learning') 186 | xlabel('Re \lambda') 187 | ylabel('Im \lambda') 188 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCEPRODSINENOISE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.03; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 60; imin = round(5/dt); icrit = round(30/dt); step = 50; nt = round(T/dt);Q = 30; G = 0.1; 20 | tx = (1:1:nt)*dt; 21 | zx = sin(8*pi*tx).*sin(12*pi*tx)+0.05*randn(1,nt); 22 | 23 | 24 | 25 | 26 | %% 27 | k = min(size(zx)); 28 | IPSC = zeros(N,1); %post synaptic current storage variable 29 | h = zeros(N,1); %Storage variable for filtered firing rates 30 | r = zeros(N,1); %second storage variable for filtered rates 31 | hr = zeros(N,1); %Third variable for filtered rates 32 | JD = 0*IPSC; %storage variable required for each spike time 33 | tspike = zeros(4*nt,2); %Storage variable for spike times 34 | ns = 0; %Number of spikes, counts during simulation 35 | z = zeros(k,1); %Initialize the approximant 36 | 37 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 38 | v_ = v; %v_ is the voltage at previous time steps 39 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 40 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 46 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 47 | end 48 | 49 | 50 | E = (2*rand(N,k)-1)*Q; %n 51 | REC2 = zeros(nt,20); 52 | REC = zeros(nt,10); 53 | current = zeros(nt,k); %storage variable for output current/approximant 54 | i = 1; 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | tlast = zeros(N,1); %This vector is used to set the refractory times 71 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 72 | %% 73 | ilast = i; 74 | %icrit = ilast; 75 | for i = ilast:1:nt 76 | 77 | 78 | I = IPSC + E*z + BIAS; %Neuronal Current 79 | 80 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 81 | v = v + dt*(dv); 82 | 83 | index = find(v>=vpeak); %Find the neurons that have spiked 84 | 85 | 86 | %Store spike times, and get the weight matrix column sum of spikers 87 | if length(index)>0 88 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 89 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 90 | ns = ns + length(index); % total number of psikes so far 91 | end 92 | 93 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 94 | 95 | % Code if the rise time is 0, and if the rise time is positive 96 | if tr == 0 97 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 98 | r = r *exp(-dt/td) + (v>=vpeak)/td; 99 | else 100 | IPSC = IPSC*exp(-dt/tr) + h*dt; 101 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 102 | 103 | r = r*exp(-dt/tr) + hr*dt; 104 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 105 | end 106 | 107 | 108 | 109 | %Implement RLS with the FORCE method 110 | z = BPhi'*r; %approximant 111 | err = z - zx(:,i); %error 112 | %% RLS 113 | if mod(i,step)==1 114 | if i > imin 115 | if i < icrit 116 | cd = Pinv*r; 117 | BPhi = BPhi - (cd*err'); 118 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 119 | end 120 | end 121 | end 122 | 123 | v = v + (30 - v).*(v>=vpeak); 124 | 125 | REC(i,:) = v(1:10); %Record a random voltage 126 | 127 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 128 | current(i,:) = z; 129 | RECB(i,:) = BPhi(1:10); 130 | REC2(i,:) = r(1:20); 131 | 132 | 133 | 134 | if mod(i,round(0.5/dt))==1 135 | dt*i 136 | drawnow 137 | figure(1) 138 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 139 | xlim([dt*i-5,dt*i]) 140 | ylim([0,200]) 141 | figure(2) 142 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 143 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 144 | 145 | xlim([dt*i-5,dt*i]) 146 | %ylim([-0.5,0.5]) 147 | 148 | %xlim([dt*i,dt*i]) 149 | figure(5) 150 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 151 | end 152 | end 153 | time = 1:1:nt; 154 | %% 155 | TotNumSpikes = ns 156 | tspike = tspike(1:1:ns,:); 157 | M = tspike(tspike(:,2)>dt*icrit,:); 158 | AverageRate = length(M)/(N*(T-dt*icrit)) 159 | 160 | %% Plotting 161 | figure(30) 162 | for j = 1:1:5 163 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 164 | end 165 | xlim([T-2,T]) 166 | xlabel('Time (s)') 167 | ylabel('Neuron Index') 168 | title('Post Learning') 169 | figure(31) 170 | for j = 1:1:5 171 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 172 | end 173 | xlim([0,2]) 174 | xlabel('Time (s)') 175 | ylabel('Neuron Index') 176 | title('Pre-Learning') 177 | %% 178 | Z = eig(OMEGA+E*BPhi'); 179 | Z2 = eig(OMEGA); 180 | %% 181 | figure(40) 182 | plot(Z2,'r.'), hold on 183 | plot(Z,'k.') 184 | legend('Pre-Learning','Post-Learning') 185 | xlabel('Re \lambda') 186 | ylabel('Im \lambda') 187 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCESAWTOOTH.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.03; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 20; G = 0.1; 20 | zx = asin(sin(2*pi*(1:1:nt)*dt*5)); 21 | 22 | 23 | 24 | %% 25 | k = min(size(zx)); 26 | IPSC = zeros(N,1); %post synaptic current storage variable 27 | h = zeros(N,1); %Storage variable for filtered firing rates 28 | r = zeros(N,1); %second storage variable for filtered rates 29 | hr = zeros(N,1); %Third variable for filtered rates 30 | JD = 0*IPSC; %storage variable required for each spike time 31 | tspike = zeros(4*nt,2); %Storage variable for spike times 32 | ns = 0; %Number of spikes, counts during simulation 33 | z = zeros(k,1); %Initialize the approximant 34 | 35 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 36 | v_ = v; %v_ is the voltage at previous time steps 37 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 38 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 44 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 45 | end 46 | 47 | 48 | E = (2*rand(N,k)-1)*Q; %n 49 | REC2 = zeros(nt,20); 50 | REC = zeros(nt,10); 51 | current = zeros(nt,k); %storage variable for output current/approximant 52 | i = 1; 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | tlast = zeros(N,1); %This vector is used to set the refractory times 69 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 70 | %% 71 | ilast = i; 72 | %icrit = ilast; 73 | for i = ilast:1:nt 74 | 75 | 76 | I = IPSC + E*z + BIAS; %Neuronal Current 77 | 78 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 79 | v = v + dt*(dv); 80 | 81 | index = find(v>=vpeak); %Find the neurons that have spiked 82 | 83 | 84 | %Store spike times, and get the weight matrix column sum of spikers 85 | if length(index)>0 86 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 87 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 88 | ns = ns + length(index); % total number of psikes so far 89 | end 90 | 91 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 92 | 93 | % Code if the rise time is 0, and if the rise time is positive 94 | if tr == 0 95 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 96 | r = r *exp(-dt/td) + (v>=vpeak)/td; 97 | else 98 | IPSC = IPSC*exp(-dt/tr) + h*dt; 99 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 100 | 101 | r = r*exp(-dt/tr) + hr*dt; 102 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 103 | end 104 | 105 | 106 | 107 | %Implement RLS with the FORCE method 108 | z = BPhi'*r; %approximant 109 | err = z - zx(:,i); %error 110 | %% RLS 111 | if mod(i,step)==1 112 | if i > imin 113 | if i < icrit 114 | cd = Pinv*r; 115 | BPhi = BPhi - (cd*err'); 116 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 117 | end 118 | end 119 | end 120 | 121 | v = v + (30 - v).*(v>=vpeak); 122 | 123 | REC(i,:) = v(1:10); %Record a random voltage 124 | 125 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 126 | current(i,:) = z; 127 | RECB(i,:) = BPhi(1:10); 128 | REC2(i,:) = r(1:20); 129 | 130 | 131 | 132 | if mod(i,round(0.5/dt))==1 133 | dt*i 134 | drawnow 135 | figure(1) 136 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 137 | xlim([dt*i-5,dt*i]) 138 | ylim([0,200]) 139 | figure(2) 140 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 141 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 142 | 143 | xlim([dt*i-5,dt*i]) 144 | %ylim([-0.5,0.5]) 145 | 146 | %xlim([dt*i,dt*i]) 147 | figure(5) 148 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 149 | end 150 | end 151 | time = 1:1:nt; 152 | %% 153 | TotNumSpikes = ns 154 | tspike = tspike(1:1:ns,:); 155 | M = tspike(tspike(:,2)>dt*icrit,:); 156 | AverageRate = length(M)/(N*(T-dt*icrit)) 157 | 158 | %% Plotting 159 | figure(30) 160 | for j = 1:1:5 161 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 162 | end 163 | xlim([T-2,T]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(31) 168 | for j = 1:1:5 169 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 170 | end 171 | xlim([0,2]) 172 | xlabel('Time (s)') 173 | ylabel('Neuron Index') 174 | title('Pre-Learning') 175 | %% 176 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 177 | Z2 = eig(OMEGA); %eigenvalues before learning 178 | %% Plot eigenvalues before and after learning 179 | figure(40) 180 | plot(Z2,'r.'), hold on 181 | plot(Z,'k.') 182 | legend('Pre-Learning','Post-Learning') 183 | xlabel('Re \lambda') 184 | ylabel('Im \lambda') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCESINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.03; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.1 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLMS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 10; G = 0.05; 20 | zx = (sin(2*pi*(1:1:nt)*dt*5)); 21 | 22 | 23 | 24 | %% 25 | k = min(size(zx)); 26 | IPSC = zeros(N,1); %post synaptic current storage variable 27 | h = zeros(N,1); %Storage variable for filtered firing rates 28 | r = zeros(N,1); %second storage variable for filtered rates 29 | hr = zeros(N,1); %Third variable for filtered rates 30 | JD = 0*IPSC; %storage variable required for each spike time 31 | tspike = zeros(4*nt,2); %Storage variable for spike times 32 | ns = 0; %Number of spikes, counts during simulation 33 | z = zeros(k,1); %Initialize the approximant 34 | 35 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 36 | v_ = v; %v_ is the voltage at previous time steps 37 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 38 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 44 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 45 | end 46 | 47 | 48 | E = (2*rand(N,k)-1)*Q; %n 49 | REC2 = zeros(nt,20); 50 | REC = zeros(nt,10); 51 | current = zeros(nt,k); %storage variable for output current/approximant 52 | i = 1; 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | tlast = zeros(N,1); %This vector is used to set the refractory times 69 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 70 | %% 71 | ilast = i; 72 | %icrit = ilast; 73 | for i = ilast:1:nt 74 | 75 | 76 | I = IPSC + E*z + BIAS; %Neuronal Current 77 | 78 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 79 | v = v + dt*(dv); 80 | 81 | index = find(v>=vpeak); %Find the neurons that have spiked 82 | 83 | 84 | %Store spike times, and get the weight matrix column sum of spikers 85 | if length(index)>0 86 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 87 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 88 | ns = ns + length(index); % total number of psikes so far 89 | end 90 | 91 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 92 | 93 | % Code if the rise time is 0, and if the rise time is positive 94 | if tr == 0 95 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 96 | r = r *exp(-dt/td) + (v>=vpeak)/td; 97 | else 98 | IPSC = IPSC*exp(-dt/tr) + h*dt; 99 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 100 | 101 | r = r*exp(-dt/tr) + hr*dt; 102 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 103 | end 104 | 105 | 106 | 107 | %Implement RLMS with the FORCE method 108 | z = BPhi'*r; %approximant 109 | err = z - zx(:,i); %error 110 | %% RLMS 111 | if mod(i,step)==1 112 | if i > imin 113 | if i < icrit 114 | cd = Pinv*r; 115 | BPhi = BPhi - (cd*err'); 116 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 117 | end 118 | end 119 | end 120 | 121 | v = v + (30 - v).*(v>=vpeak); 122 | 123 | REC(i,:) = v(1:10); %Record a random voltage 124 | 125 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 126 | current(i,:) = z; 127 | RECB(i,:) = BPhi(1:10); 128 | REC2(i,:) = r(1:20); 129 | 130 | 131 | 132 | if mod(i,round(0.5/dt))==1 133 | dt*i 134 | drawnow 135 | figure(1) 136 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 137 | xlim([dt*i-5,dt*i]) 138 | ylim([0,200]) 139 | figure(2) 140 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 141 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 142 | 143 | xlim([dt*i-5,dt*i]) 144 | %ylim([-0.5,0.5]) 145 | 146 | %xlim([dt*i,dt*i]) 147 | figure(5) 148 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 149 | end 150 | end 151 | time = 1:1:nt; 152 | %% 153 | TotNumSpikes = ns 154 | tspike = tspike(1:1:ns,:); 155 | M = tspike(tspike(:,2)>dt*icrit,:); 156 | AverageRate = length(M)/(N*(T-dt*icrit)) 157 | 158 | %% Plotting 159 | figure(30) 160 | for j = 1:1:5 161 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 162 | end 163 | xlim([T-2,T]) 164 | xlabel('Time (s)') 165 | ylabel('Neuron Index') 166 | title('Post Learning') 167 | figure(31) 168 | for j = 1:1:5 169 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 170 | end 171 | xlim([0,2]) 172 | xlabel('Time (s)') 173 | ylabel('Neuron Index') 174 | title('Pre-Learning') 175 | %% 176 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 177 | Z2 = eig(OMEGA); %eigenvalues before learning 178 | %% Plot eigenvalues before and after learning 179 | figure(40) 180 | plot(Z2,'r.'), hold on 181 | plot(Z,'k.') 182 | legend('Pre-Learning','Post-Learning') 183 | xlabel('Re \lambda') 184 | ylabel('Im \lambda') 185 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCEVDPHARMONIC.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.03; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.05; 20 | mu = 0.5; %Sets the behavior 21 | MD = 10; %Scale system in space 22 | TC = 20; %Scale system in time 23 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 24 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 25 | tx = (1:1:nt)*dt; 26 | zx(:,1) = interp1(t,y(:,1),tx); 27 | zx(:,2) = interp1(t,y(:,2),tx); 28 | zx = zx'; 29 | 30 | 31 | 32 | 33 | %% 34 | k = min(size(zx)); 35 | IPSC = zeros(N,1); %post synaptic current storage variable 36 | h = zeros(N,1); %Storage variable for filtered firing rates 37 | r = zeros(N,1); %second storage variable for filtered rates 38 | hr = zeros(N,1); %Third variable for filtered rates 39 | JD = 0*IPSC; %storage variable required for each spike time 40 | tspike = zeros(4*nt,2); %Storage variable for spike times 41 | ns = 0; %Number of spikes, counts during simulation 42 | z = zeros(k,1); %Initialize the approximant 43 | 44 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 45 | v_ = v; %v_ is the voltage at previous time steps 46 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 47 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 53 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 54 | end 55 | 56 | 57 | E = (2*rand(N,k)-1)*Q; %n 58 | REC2 = zeros(nt,20); 59 | REC = zeros(nt,10); 60 | current = zeros(nt,k); %storage variable for output current/approximant 61 | i = 1; 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | tlast = zeros(N,1); %This vector is used to set the refractory times 78 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 79 | %% 80 | ilast = i; 81 | %icrit = ilast; 82 | for i = ilast:1:nt 83 | 84 | 85 | I = IPSC + E*z + BIAS; %Neuronal Current 86 | 87 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 88 | v = v + dt*(dv); 89 | 90 | index = find(v>=vpeak); %Find the neurons that have spiked 91 | 92 | 93 | %Store spike times, and get the weight matrix column sum of spikers 94 | if length(index)>0 95 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 96 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 97 | ns = ns + length(index); % total number of psikes so far 98 | end 99 | 100 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 101 | 102 | % Code if the rise time is 0, and if the rise time is positive 103 | if tr == 0 104 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 105 | r = r *exp(-dt/td) + (v>=vpeak)/td; 106 | else 107 | IPSC = IPSC*exp(-dt/tr) + h*dt; 108 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 109 | 110 | r = r*exp(-dt/tr) + hr*dt; 111 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 112 | end 113 | 114 | 115 | 116 | %Implement RLS with the FORCE method 117 | z = BPhi'*r; %approximant 118 | err = z - zx(:,i); %error 119 | %% RLS 120 | if mod(i,step)==1 121 | if i > imin 122 | if i < icrit 123 | cd = Pinv*r; 124 | BPhi = BPhi - (cd*err'); 125 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 126 | end 127 | end 128 | end 129 | 130 | v = v + (30 - v).*(v>=vpeak); 131 | 132 | REC(i,:) = v(1:10); %Record a random voltage 133 | 134 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 135 | current(i,:) = z; 136 | RECB(i,:) = BPhi(1:10); 137 | REC2(i,:) = r(1:20); 138 | 139 | 140 | 141 | if mod(i,round(0.5/dt))==1 142 | dt*i 143 | drawnow 144 | figure(1) 145 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 146 | xlim([dt*i-5,dt*i]) 147 | ylim([0,200]) 148 | figure(2) 149 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 150 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 151 | 152 | xlim([dt*i-5,dt*i]) 153 | %ylim([-0.5,0.5]) 154 | 155 | %xlim([dt*i,dt*i]) 156 | figure(5) 157 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 158 | end 159 | end 160 | time = 1:1:nt; 161 | %% 162 | TotNumSpikes = ns 163 | tspike = tspike(1:1:ns,:); 164 | M = tspike(tspike(:,2)>dt*icrit,:); 165 | AverageRate = length(M)/(N*(T-dt*icrit)) 166 | 167 | %% Plotting 168 | figure(30) 169 | for j = 1:1:5 170 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 171 | end 172 | xlim([T-2,T]) 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | title('Post Learning') 176 | figure(31) 177 | for j = 1:1:5 178 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 179 | end 180 | xlim([0,2]) 181 | xlabel('Time (s)') 182 | ylabel('Neuron Index') 183 | title('Pre-Learning') 184 | %% 185 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 186 | Z2 = eig(OMEGA); %eigenvalues before learning 187 | %% Plot eigenvalues before and after learning 188 | figure(40) 189 | plot(Z2,'r.'), hold on 190 | plot(Z,'k.') 191 | legend('Pre-Learning','Post-Learning') 192 | xlabel('Re \lambda') 193 | ylabel('Im \lambda') 194 | -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/LIFFORCEVDPRELAXATION.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | 4 | %% 5 | N = 2000; %Number of neurons 6 | dt = 0.00005; 7 | tref = 0.002; %Refractory time constant in seconds 8 | tm = 0.01; %Membrane time constant 9 | vreset = -65; %Voltage reset 10 | vpeak = -40; %Voltage peak. 11 | td = 0.03; tr = 0.002; 12 | %% 13 | 14 | alpha = dt*0.05 ; %Sets the rate of weight change, too fast is unstable, too slow is bad as well. 15 | Pinv = eye(N)*alpha; %initialize the correlation weight matrix for RLMS 16 | p = 0.1; %Set the network sparsity 17 | 18 | %% Target Dynamics for Product of Sine Waves 19 | T = 15; imin = round(5/dt); icrit = round(10/dt); step = 50; nt = round(T/dt); Q = 30; G = 0.05; 20 | mu = 5; %Sets the behavior 21 | MD = 10; %Scale system in space 22 | TC = 20; %Scale system in time 23 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 24 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 25 | tx = (1:1:nt)*dt; 26 | zx(:,1) = interp1(t,y(:,1),tx); 27 | zx(:,2) = interp1(t,y(:,2),tx); 28 | zx = zx'; 29 | 30 | 31 | 32 | 33 | %% 34 | k = min(size(zx)); 35 | IPSC = zeros(N,1); %post synaptic current storage variable 36 | h = zeros(N,1); %Storage variable for filtered firing rates 37 | r = zeros(N,1); %second storage variable for filtered rates 38 | hr = zeros(N,1); %Third variable for filtered rates 39 | JD = 0*IPSC; %storage variable required for each spike time 40 | tspike = zeros(4*nt,2); %Storage variable for spike times 41 | ns = 0; %Number of spikes, counts during simulation 42 | z = zeros(k,1); %Initialize the approximant 43 | 44 | v = vreset + rand(N,1)*(30-vreset); %Initialize neuronal voltage with random distribtuions 45 | v_ = v; %v_ is the voltage at previous time steps 46 | RECB = zeros(nt,10); %Storage matrix for the synaptic weights (a subset of them) 47 | OMEGA = G*(randn(N,N)).*(rand(N,N)0); 53 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 54 | end 55 | 56 | 57 | E = (2*rand(N,k)-1)*Q; %n 58 | REC2 = zeros(nt,20); 59 | REC = zeros(nt,10); 60 | current = zeros(nt,k); %storage variable for output current/approximant 61 | i = 1; 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | tlast = zeros(N,1); %This vector is used to set the refractory times 78 | BIAS = vpeak; %Set the BIAS current, can help decrease/increase firing rates. 0 is fine. 79 | %% 80 | ilast = i; 81 | %icrit = ilast; 82 | for i = ilast:1:nt 83 | 84 | 85 | I = IPSC + E*z + BIAS; %Neuronal Current 86 | 87 | dv = (dt*i>tlast + tref).*(-v+I)/tm; %Voltage equation with refractory period 88 | v = v + dt*(dv); 89 | 90 | index = find(v>=vpeak); %Find the neurons that have spiked 91 | 92 | 93 | %Store spike times, and get the weight matrix column sum of spikers 94 | if length(index)>0 95 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 96 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 97 | ns = ns + length(index); % total number of psikes so far 98 | end 99 | 100 | tlast = tlast + (dt*i -tlast).*(v>=vpeak); %Used to set the refractory period of LIF neurons 101 | 102 | % Code if the rise time is 0, and if the rise time is positive 103 | if tr == 0 104 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 105 | r = r *exp(-dt/td) + (v>=vpeak)/td; 106 | else 107 | IPSC = IPSC*exp(-dt/tr) + h*dt; 108 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 109 | 110 | r = r*exp(-dt/tr) + hr*dt; 111 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 112 | end 113 | 114 | 115 | 116 | %Implement RLMS with the FORCE method 117 | z = BPhi'*r; %approximant 118 | err = z - zx(:,i); %error 119 | %% RLMS 120 | if mod(i,step)==1 121 | if i > imin 122 | if i < icrit 123 | cd = Pinv*r; 124 | BPhi = BPhi - (cd*err'); 125 | Pinv = Pinv -((cd)*(cd'))/( 1 + (r')*(cd)); 126 | end 127 | end 128 | end 129 | 130 | v = v + (30 - v).*(v>=vpeak); 131 | 132 | REC(i,:) = v(1:10); %Record a random voltage 133 | 134 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 135 | current(i,:) = z; 136 | RECB(i,:) = BPhi(1:10); 137 | REC2(i,:) = r(1:20); 138 | 139 | 140 | 141 | if mod(i,round(0.5/dt))==1 142 | dt*i 143 | drawnow 144 | figure(1) 145 | plot(tspike(1:1:ns,2),tspike(1:1:ns,1),'k.') 146 | xlim([dt*i-5,dt*i]) 147 | ylim([0,200]) 148 | figure(2) 149 | plot(dt*(1:1:i),zx(:,1:1:i),'k--','LineWidth',2), hold on 150 | plot(dt*(1:1:i),current(1:1:i,:),'LineWidth',2), hold off 151 | 152 | xlim([dt*i-5,dt*i]) 153 | %ylim([-0.5,0.5]) 154 | 155 | %xlim([dt*i,dt*i]) 156 | figure(5) 157 | plot(dt*(1:1:i),RECB(1:1:i,1:10),'.') 158 | end 159 | end 160 | time = 1:1:nt; 161 | %% 162 | TotNumSpikes = ns 163 | tspike = tspike(1:1:ns,:); 164 | M = tspike(tspike(:,2)>dt*icrit,:); 165 | AverageRate = length(M)/(N*(T-dt*icrit)) 166 | 167 | %% Plotting 168 | figure(30) 169 | for j = 1:1:5 170 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 171 | end 172 | xlim([T-2,T]) 173 | xlabel('Time (s)') 174 | ylabel('Neuron Index') 175 | title('Post Learning') 176 | figure(31) 177 | for j = 1:1:5 178 | plot((1:1:i)*dt,REC(1:1:i,j)/(30-vreset)+j), hold on 179 | end 180 | xlim([0,2]) 181 | xlabel('Time (s)') 182 | ylabel('Neuron Index') 183 | title('Pre-Learning') 184 | %% 185 | Z = eig(OMEGA+E*BPhi'); %eigenvalues after learning 186 | Z2 = eig(OMEGA); %eigenvalues before learning 187 | %% Plot eigenvalues before and after learning 188 | figure(40) 189 | plot(Z2,'r.'), hold on 190 | plot(Z,'k.') 191 | legend('Pre-Learning','Post-Learning') 192 | xlabel('Re \lambda') 193 | ylabel('Im \lambda') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/LIF MODEL 30/vanderpol.m: -------------------------------------------------------------------------------- 1 | function dy = vanderpol(mu,MD,TC,t,y) 2 | dy(1,1) = mu*(y(1,1)-(y(1,1).^3)*(MD*MD/3) - y(2,1)); 3 | dy(2,1) = y(1,1)/mu; 4 | dy = dy*TC; 5 | end -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 20/THETANOISYPRODSINES.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | %% Product of sinusoids 11 | T = 80; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = ((sin(2*tx*pi*4).*sin(2*tx*pi*6))+ 0.05*randn(1,nt))'; G = 15; Q = 1*10^4; %Scaling Weight for BPhi 12 | 13 | %% 14 | m = min(size(xz)); %dimensionality of teacher 15 | E = Q*(2*rand(N,m)-1); %encoders 16 | BPhi = zeros(N,m); %Decoders 17 | %% Compute Neuronal Intercepts and Tuning Curves 18 | initial = 0; 19 | p = 0.1; %Sparse Coupling 20 | OMEGA = G*randn(N,N).*(rand(N,N)0); 26 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 27 | end 28 | 29 | %% Storage Matrices and Initialization 30 | store = 10; %don't store every time step, saves time. 31 | current = zeros(nt,m); %storage variable for output current 32 | IPSC = zeros(N,1); %post synaptic current 33 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 34 | JD = 0*IPSC; 35 | 36 | vpeak = pi; %peak and reset 37 | vreset = -pi; 38 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 39 | v_ = v; %temporary storage variable for integration 40 | 41 | j = 1; 42 | time = zeros(round(nt/store),1); 43 | RECB = zeros(5,round(2*round(nt/store))); 44 | REC = zeros(10,round(nt/store)); 45 | tspike = zeros(8*nt,2); 46 | ns = 0; 47 | tic 48 | SD = 0; 49 | BPhi = zeros(N,m); 50 | z = zeros(m,1); 51 | step = 50; %Sets the frequency of RLMS 52 | imin = round(tmin/dt); %Start RLMS 53 | icrit = round((tcrit/dt)); %Stop RLMS 54 | 55 | Pinv = eye(N)*dt; 56 | i = 1; 57 | %% 58 | ilast = i; 59 | %icrit = ilast; 60 | for i = ilast :1:nt 61 | JX = IPSC + E*z; %current 62 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 63 | v = v_ + dt*(dv); %Euler integration plus refractory period. 64 | index = find(v>=vpeak); 65 | if length(index)>0 66 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 67 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 68 | ns = ns + length(index); 69 | end 70 | 71 | 72 | if tr == 0 73 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 74 | r = r *exp(-dt/td) + (v>=vpeak)/td; 75 | else 76 | IPSC = IPSC*exp(-dt/tr) + h*dt; 77 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 78 | 79 | r = r*exp(-dt/tr) + hr*dt; 80 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 81 | end 82 | 83 | 84 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 85 | v_ = v; 86 | %only store stuff every index variable. 87 | 88 | 89 | 90 | 91 | z = BPhi'*r; 92 | err = z - xz(i,:)'; 93 | 94 | 95 | if mod(i,step)==1 96 | if i > imin 97 | if i < icrit 98 | cd = Pinv*r; 99 | BPhi = BPhi - (cd*err'); 100 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 101 | end 102 | end 103 | end 104 | 105 | if mod(i,store) == 1; 106 | j = j + 1; 107 | time(j,:) = dt*i; 108 | current(j,:) = z; 109 | REC(:,j) = v(1:10); 110 | RECB(:,j) = BPhi(1:5,1); 111 | end 112 | 113 | 114 | if mod(i,round(0.1/dt))==1 115 | dt*i 116 | figure(1) 117 | drawnow 118 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 119 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 120 | xlabel('Time') 121 | ylabel('x(t)') 122 | 123 | figure(2) 124 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 125 | xlabel('Time') 126 | ylabel('\phi_j') 127 | 128 | figure(3) 129 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 130 | ylim([0,100]) 131 | xlabel('Time') 132 | ylabel('Neuron Index') 133 | end 134 | 135 | end 136 | %% 137 | %ns 138 | current = current(1:1:j,:); 139 | REC = REC(:,1:1:j); 140 | %REC2 = REC2(:,1:1:j); 141 | nt = length(current); 142 | time = (1:1:nt)*T/nt; 143 | xhat = current; 144 | 145 | %% 146 | Z = eig(OMEGA); %eigenvalues before learning 147 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 148 | figure(42) 149 | plot(Z,'k.'), hold on 150 | plot(Z2,'r.') 151 | xlabel('Re\lambda') 152 | ylabel('Im\lambda') 153 | legend('Pre-Learning','Post-Learning') 154 | 155 | %% 156 | figure(43) 157 | for z = 1:1:10 158 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 159 | end 160 | xlim([9,10]) 161 | xlabel('Time (s)') 162 | ylabel('Neuron Index') 163 | title('Post Learning') 164 | figure(66) 165 | for z = 1:1:10 166 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 167 | end 168 | xlim([0,1]) 169 | title('Pre-Learning') 170 | xlabel('Time (s)') 171 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 20/THETAPRODSINES.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.02; %decay time 9 | tr = 0.002; %Rise time 10 | 11 | %% Product of sinusoids 12 | T = 80; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = ((sin(2*tx*pi*4).*sin(2*tx*pi*6)))'; G = 25; Q = 1*10^4; %Scaling Weight for BPhi 13 | 14 | %% 15 | m = min(size(xz)); %dimensionality of teacher 16 | E = Q*(2*rand(N,m)-1); %encoders 17 | BPhi = zeros(N,m); %Decoders 18 | %% Compute Neuronal Intercepts and Tuning Curves 19 | initial = 0; 20 | p = 0.1; %Sparse Coupling 21 | OMEGA = G*randn(N,N).*(rand(N,N)0); 27 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 28 | end 29 | 30 | %% Storage Matrices and Initialization 31 | store = 10; %don't store every time step, saves time. 32 | current = zeros(nt,m); %storage variable for output current 33 | IPSC = zeros(N,1); %post synaptic current 34 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 35 | JD = 0*IPSC; 36 | 37 | vpeak = pi; %peak and reset 38 | vreset = -pi; 39 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 40 | v_ = v; %temporary storage variable for integration 41 | 42 | j = 1; 43 | time = zeros(round(nt/store),1); 44 | RECB = zeros(5,round(2*round(nt/store))); 45 | REC = zeros(10,round(nt/store)); 46 | tspike = zeros(8*nt,2); 47 | ns = 0; 48 | tic 49 | SD = 0; 50 | BPhi = zeros(N,m); 51 | z = zeros(m,1); 52 | step = 50; %Sets the frequency of RLS 53 | imin = round(tmin/dt); %Start RLS 54 | icrit = round((tcrit/dt)); %Stop RLS 55 | 56 | Pinv = eye(N)*dt; 57 | i = 1; 58 | %% 59 | ilast = i; 60 | %icrit = ilast; 61 | for i = ilast :1:nt 62 | JX = IPSC + E*z; %current 63 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 64 | v = v_ + dt*(dv); %Euler integration plus refractory period. 65 | index = find(v>=vpeak); 66 | if length(index)>0 67 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 68 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 69 | ns = ns + length(index); 70 | end 71 | 72 | 73 | if tr == 0 74 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 75 | r = r *exp(-dt/td) + (v>=vpeak)/td; 76 | else 77 | IPSC = IPSC*exp(-dt/tr) + h*dt; 78 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 79 | 80 | r = r*exp(-dt/tr) + hr*dt; 81 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 82 | end 83 | 84 | 85 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 86 | v_ = v; 87 | %only store stuff every index variable. 88 | 89 | 90 | 91 | 92 | z = BPhi'*r; 93 | err = z - xz(i,:)'; 94 | 95 | 96 | if mod(i,step)==1 97 | if i > imin 98 | if i < icrit 99 | cd = Pinv*r; 100 | BPhi = BPhi - (cd*err'); 101 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 102 | end 103 | end 104 | end 105 | 106 | if mod(i,store) == 1; 107 | j = j + 1; 108 | time(j,:) = dt*i; 109 | current(j,:) = z; 110 | REC(:,j) = v(1:10); 111 | RECB(:,j) = BPhi(1:5,1); 112 | end 113 | 114 | 115 | if mod(i,round(0.1/dt))==1 116 | dt*i 117 | figure(1) 118 | drawnow 119 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 120 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 121 | xlabel('Time') 122 | ylabel('x(t)') 123 | 124 | figure(2) 125 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 126 | xlabel('Time') 127 | ylabel('\phi_j') 128 | 129 | figure(3) 130 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 131 | ylim([0,100]) 132 | xlabel('Time') 133 | ylabel('Neuron Index') 134 | end 135 | 136 | end 137 | %% 138 | %ns 139 | current = current(1:1:j,:); 140 | REC = REC(:,1:1:j); 141 | %REC2 = REC2(:,1:1:j); 142 | nt = length(current); 143 | time = (1:1:nt)*T/nt; 144 | xhat = current; 145 | %% 146 | tspike = tspike(1:1:ns,:); 147 | M = tspike(tspike(:,2)>dt*icrit,:); 148 | AverageRate = length(M)/(N*(T-dt*icrit)) 149 | %% 150 | 151 | %% 152 | Z = eig(OMEGA); %eigenvalues before learning 153 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 154 | figure(42) 155 | plot(Z,'k.'), hold on 156 | plot(Z2,'r.') 157 | xlabel('Re\lambda') 158 | ylabel('Im\lambda') 159 | legend('Pre-Learning','Post-Learning') 160 | 161 | %% 162 | figure(43) 163 | for z = 1:1:10 164 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 165 | end 166 | xlim([9,10]) 167 | xlabel('Time (s)') 168 | ylabel('Neuron Index') 169 | title('Post Learning') 170 | figure(66) 171 | for z = 1:1:10 172 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 173 | end 174 | xlim([0,1]) 175 | title('Pre-Learning') 176 | xlabel('Time (s)') 177 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCEPRODSINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | 11 | %% 12 | T = 70; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = (sin(2*tx*pi*4).*sin(2*tx*pi*6) + randn(1,nt)*0)'; G = 50; Q = 2*10^4; %Scaling Weight for BPhi 13 | 14 | 15 | %% 16 | m = min(size(xz)); %dimensionality of teacher 17 | E = Q*(2*rand(N,m)-1); %encoders 18 | BPhi = zeros(N,m); %Decoders 19 | %% Compute Neuronal Intercepts and Tuning Curves 20 | initial = 0; 21 | p = 0.1; %Sparse Coupling 22 | OMEGA = G*randn(N,N).*(rand(N,N)0); 28 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 29 | end 30 | 31 | %% Storage Matrices and Initialization 32 | store = 10; %don't store every time step, saves time. 33 | current = zeros(nt,m); %storage variable for output current 34 | IPSC = zeros(N,1); %post synaptic current 35 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 36 | JD = 0*IPSC; 37 | 38 | vpeak = pi; %peak and reset 39 | vreset = -pi; 40 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 41 | v_ = v; %temporary storage variable for integration 42 | 43 | j = 1; 44 | time = zeros(round(nt/store),1); 45 | RECB = zeros(5,round(2*round(nt/store))); 46 | REC = zeros(10,round(nt/store)); 47 | tspike = zeros(8*nt,2); 48 | ns = 0; 49 | tic 50 | SD = 0; 51 | BPhi = zeros(N,m); 52 | z = zeros(m,1); 53 | step = 50; %Sets the frequency of RLS 54 | imin = round(tmin/dt); %Start RLS 55 | icrit = round((tcrit/dt)); %Stop RLS 56 | 57 | 58 | Pinv = eye(N)*dt*10; 59 | i = 1; 60 | %% 61 | ilast = i; 62 | %icrit = ilast; 63 | for i = ilast :1:nt 64 | JX = IPSC + E*z; %current 65 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 66 | v = v_ + dt*(dv); %Euler integration plus refractory period. 67 | index = find(v>=vpeak); 68 | if length(index)>0 69 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 70 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 71 | ns = ns + length(index); 72 | end 73 | 74 | 75 | 76 | if tr == 0 77 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 78 | r = r *exp(-dt/td) + (v>=vpeak)/td; 79 | else 80 | IPSC = IPSC*exp(-dt/tr) + h*dt; 81 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 82 | 83 | r = r*exp(-dt/tr) + hr*dt; 84 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 85 | end 86 | 87 | 88 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 89 | v_ = v; 90 | %only store stuff every index variable. 91 | 92 | 93 | 94 | 95 | z = BPhi'*r; 96 | err = z - xz(i,:)'; 97 | 98 | 99 | if mod(i,step)==1 100 | if i > imin 101 | if i < icrit 102 | cd = Pinv*r; 103 | BPhi = BPhi - (cd*err'); 104 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 105 | end 106 | end 107 | end 108 | 109 | if mod(i,store) == 1; 110 | j = j + 1; 111 | time(j,:) = dt*i; 112 | current(j,:) = z; 113 | REC(:,j) = v(1:10); 114 | RECB(:,j) = BPhi(1:5,1); 115 | end 116 | 117 | 118 | if mod(i,round(0.1/dt))==1 119 | dt*i 120 | figure(1) 121 | drawnow 122 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 123 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 124 | xlim([dt*i-1,dt*i]) 125 | xlabel('Time') 126 | ylabel('x(t)') 127 | 128 | figure(2) 129 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 130 | xlabel('Time') 131 | ylabel('\phi_j') 132 | 133 | figure(3) 134 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 135 | ylim([0,100]) 136 | xlabel('Time') 137 | ylabel('Neuron Index') 138 | end 139 | 140 | end 141 | %% 142 | %ns 143 | current = current(1:1:j,:); 144 | REC = REC(:,1:1:j); 145 | %REC2 = REC2(:,1:1:j); 146 | nt = length(current); 147 | time = (1:1:nt)*T/nt; 148 | xhat = current; 149 | tspike = tspike(1:1:ns,:); 150 | M = tspike(tspike(:,2)>dt*icrit,:); 151 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 152 | %% 153 | Z = eig(OMEGA); %eigenvalues before learning 154 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 155 | figure(42) 156 | plot(Z,'k.'), hold on 157 | plot(Z2,'r.') 158 | xlabel('Re\lambda') 159 | ylabel('Im\lambda') 160 | legend('Pre-Learning','Post-Learning') 161 | 162 | %% 163 | figure(43) 164 | for z = 1:1:10 165 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 166 | end 167 | xlim([9,10]) 168 | xlabel('Time (s)') 169 | ylabel('Neuron Index') 170 | title('Post Learning') 171 | figure(66) 172 | for z = 1:1:10 173 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 174 | end 175 | xlim([0,1]) 176 | title('Pre-Learning') 177 | xlabel('Time (s)') 178 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCEPRODSINENOISE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | 11 | %% 12 | T = 70; tmin = 5; tcrit = 55; nt = round(T/dt); tx = (1:1:nt)*dt; xz = (sin(2*tx*pi*4).*sin(2*tx*pi*6) + randn(1,nt)*0.05)'; G = 50; Q = 2*10^4; %Scaling Weight for BPhi 13 | 14 | 15 | %% 16 | m = min(size(xz)); %dimensionality of teacher 17 | E = Q*(2*rand(N,m)-1); %encoders 18 | BPhi = zeros(N,m); %Decoders 19 | %% Compute Neuronal Intercepts and Tuning Curves 20 | initial = 0; 21 | p = 0.1; %Sparse Coupling 22 | OMEGA = G*randn(N,N).*(rand(N,N)0); 28 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 29 | end 30 | 31 | %% Storage Matrices and Initialization 32 | store = 10; %don't store every time step, saves time. 33 | current = zeros(nt,m); %storage variable for output current 34 | IPSC = zeros(N,1); %post synaptic current 35 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 36 | JD = 0*IPSC; 37 | 38 | vpeak = pi; %peak and reset 39 | vreset = -pi; 40 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 41 | v_ = v; %temporary storage variable for integration 42 | 43 | j = 1; 44 | time = zeros(round(nt/store),1); 45 | RECB = zeros(5,round(2*round(nt/store))); 46 | REC = zeros(10,round(nt/store)); 47 | tspike = zeros(8*nt,2); 48 | ns = 0; 49 | tic 50 | SD = 0; 51 | BPhi = zeros(N,m); 52 | z = zeros(m,1); 53 | step = 50; %Sets the frequency of RLS 54 | imin = round(tmin/dt); %Start RLS 55 | icrit = round((tcrit/dt)); %Stop RLS 56 | 57 | 58 | Pinv = eye(N)*dt*10; 59 | i = 1; 60 | %% 61 | ilast = i; 62 | %icrit = ilast; 63 | for i = ilast :1:nt 64 | JX = IPSC + E*z; %current 65 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 66 | v = v_ + dt*(dv); %Euler integration plus refractory period. 67 | index = find(v>=vpeak); 68 | if length(index)>0 69 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 70 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 71 | ns = ns + length(index); 72 | end 73 | 74 | 75 | 76 | if tr == 0 77 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 78 | r = r *exp(-dt/td) + (v>=vpeak)/td; 79 | else 80 | IPSC = IPSC*exp(-dt/tr) + h*dt; 81 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 82 | 83 | r = r*exp(-dt/tr) + hr*dt; 84 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 85 | end 86 | 87 | 88 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 89 | v_ = v; 90 | %only store stuff every index variable. 91 | 92 | 93 | 94 | 95 | z = BPhi'*r; 96 | err = z - xz(i,:)'; 97 | 98 | 99 | if mod(i,step)==1 100 | if i > imin 101 | if i < icrit 102 | cd = Pinv*r; 103 | BPhi = BPhi - (cd*err'); 104 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 105 | end 106 | end 107 | end 108 | 109 | if mod(i,store) == 1; 110 | j = j + 1; 111 | time(j,:) = dt*i; 112 | current(j,:) = z; 113 | REC(:,j) = v(1:10); 114 | RECB(:,j) = BPhi(1:5,1); 115 | end 116 | 117 | 118 | if mod(i,round(0.1/dt))==1 119 | dt*i 120 | figure(1) 121 | drawnow 122 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 123 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 124 | xlim([dt*i-1,dt*i]) 125 | xlabel('Time') 126 | ylabel('x(t)') 127 | 128 | figure(2) 129 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 130 | xlabel('Time') 131 | ylabel('\phi_j') 132 | 133 | figure(3) 134 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 135 | ylim([0,100]) 136 | xlabel('Time') 137 | ylabel('Neuron Index') 138 | end 139 | 140 | end 141 | %% 142 | %ns 143 | current = current(1:1:j,:); 144 | REC = REC(:,1:1:j); 145 | %REC2 = REC2(:,1:1:j); 146 | nt = length(current); 147 | time = (1:1:nt)*T/nt; 148 | xhat = current; 149 | tspike = tspike(1:1:ns,:); 150 | M = tspike(tspike(:,2)>dt*icrit,:); 151 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 152 | %% 153 | Z = eig(OMEGA); %eigenvalues before learning 154 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalued after learning 155 | figure(42) 156 | plot(Z,'k.'), hold on 157 | plot(Z2,'r.') 158 | xlabel('Re\lambda') 159 | ylabel('Im\lambda') 160 | legend('Pre-Learning','Post-Learning') 161 | 162 | %% 163 | figure(43) 164 | for z = 1:1:10 165 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 166 | end 167 | xlim([9,10]) 168 | xlabel('Time (s)') 169 | ylabel('Neuron Index') 170 | title('Post Learning') 171 | figure(66) 172 | for z = 1:1:10 173 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 174 | end 175 | xlim([0,1]) 176 | title('Pre-Learning') 177 | xlabel('Time (s)') 178 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCESAWTOOTH.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | 11 | %% 12 | T = 15; tmin = 5; tcrit = 10; nt = round(T/dt); tx = (1:1:nt)*dt; xz = asin(sin(2*tx*pi*5))'; G = 50; Q = 2*10^4; 13 | 14 | %% 15 | m = min(size(xz)); %dimensionality of teacher 16 | E = Q*(2*rand(N,m)-1); %encoders 17 | BPhi = zeros(N,m); %Decoders 18 | %% Compute Neuronal Intercepts and Tuning Curves 19 | initial = 0; 20 | p = 0.1; %Sparse Coupling 21 | OMEGA = G*randn(N,N).*(rand(N,N)0); 27 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 28 | end 29 | 30 | %% Storage Matrices and Initialization 31 | store = 10; %don't store every time step, saves time. 32 | current = zeros(nt,m); %storage variable for output current 33 | IPSC = zeros(N,1); %post synaptic current 34 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 35 | JD = 0*IPSC; 36 | 37 | vpeak = pi; %peak and reset 38 | vreset = -pi; 39 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 40 | v_ = v; %temporary storage variable for integration 41 | 42 | j = 1; 43 | time = zeros(round(nt/store),1); 44 | RECB = zeros(5,round(2*round(nt/store))); 45 | REC = zeros(10,round(nt/store)); 46 | tspike = zeros(8*nt,2); 47 | ns = 0; 48 | tic 49 | SD = 0; 50 | BPhi = zeros(N,m); 51 | z = zeros(m,1); 52 | step = 50; %Sets the frequency of RLMS 53 | imin = round(tmin/dt); %Start RLMS 54 | icrit = round((tcrit/dt)); %Stop RLMS 55 | 56 | Pinv = eye(N)*dt*10; 57 | i = 1; 58 | %% 59 | ilast = i; 60 | %icrit = ilast; 61 | for i = ilast :1:nt 62 | JX = IPSC + E*z; %current 63 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 64 | v = v_ + dt*(dv); %Euler integration plus refractory period. 65 | index = find(v>=vpeak); 66 | if length(index)>0 67 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 68 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 69 | ns = ns + length(index); 70 | end 71 | 72 | 73 | 74 | if tr == 0 75 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 76 | r = r *exp(-dt/td) + (v>=vpeak)/td; 77 | else 78 | IPSC = IPSC*exp(-dt/tr) + h*dt; 79 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 80 | 81 | r = r*exp(-dt/tr) + hr*dt; 82 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 83 | end 84 | 85 | 86 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 87 | v_ = v; 88 | %only store stuff every index variable. 89 | 90 | 91 | 92 | 93 | z = BPhi'*r; 94 | err = z - xz(i,:)'; 95 | 96 | 97 | if mod(i,step)==1 98 | if i > imin 99 | if i < icrit 100 | cd = Pinv*r; 101 | BPhi = BPhi - (cd*err'); 102 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 103 | end 104 | end 105 | end 106 | 107 | if mod(i,store) == 1; 108 | j = j + 1; 109 | time(j,:) = dt*i; 110 | current(j,:) = z; 111 | REC(:,j) = v(1:10); 112 | RECB(:,j) = BPhi(1:5,1); 113 | end 114 | 115 | 116 | if mod(i,round(0.1/dt))==1 117 | dt*i 118 | figure(1) 119 | drawnow 120 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 121 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 122 | xlim([dt*i-1,dt*i]) 123 | xlabel('Time') 124 | ylabel('x(t)') 125 | 126 | figure(2) 127 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 128 | xlabel('Time') 129 | ylabel('\phi_j') 130 | 131 | figure(3) 132 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 133 | ylim([0,100]) 134 | xlabel('Time') 135 | ylabel('Neuron Index') 136 | end 137 | 138 | end 139 | %% 140 | %ns 141 | current = current(1:1:j,:); 142 | REC = REC(:,1:1:j); 143 | %REC2 = REC2(:,1:1:j); 144 | nt = length(current); 145 | time = (1:1:nt)*T/nt; 146 | xhat = current; 147 | tspike = tspike(1:1:ns,:); 148 | M = tspike(tspike(:,2)>dt*icrit,:); 149 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 150 | %% 151 | Z = eig(OMEGA); 152 | Z2 = eig(OMEGA+E*BPhi'); 153 | figure(42) 154 | plot(Z,'k.'), hold on 155 | plot(Z2,'r.') 156 | xlabel('Re\lambda') 157 | ylabel('Im\lambda') 158 | legend('Pre-Learning','Post-Learning') 159 | 160 | %% 161 | figure(43) 162 | for z = 1:1:10 163 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 164 | end 165 | xlim([9,10]) 166 | xlabel('Time (s)') 167 | ylabel('Neuron Index') 168 | title('Post Learning') 169 | figure(66) 170 | for z = 1:1:10 171 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 172 | end 173 | xlim([0,1]) 174 | title('Pre-Learning') 175 | xlabel('Time (s)') 176 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCESINE.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; tmin = 5; tcrit = 10; nt = round(T/dt); tx = (1:1:nt)*dt; xz = sin(2*tx*pi*5)'; G = 50; Q = 2*10^4; 12 | 13 | %% 14 | m = min(size(xz)); %dimensionality of teacher 15 | E = Q*(2*rand(N,m)-1); %encoders 16 | BPhi = zeros(N,m); %Decoders 17 | %% Compute Neuronal Intercepts and Tuning Curves 18 | initial = 0; 19 | p = 0.1; %Sparse Coupling 20 | OMEGA = G*randn(N,N).*(rand(N,N)0); 26 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 27 | end 28 | 29 | %% Storage Matrices and Initialization 30 | store = 10; %don't store every time step, saves time. 31 | current = zeros(nt,m); %storage variable for output current 32 | IPSC = zeros(N,1); %post synaptic current 33 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 34 | JD = 0*IPSC; 35 | 36 | vpeak = pi; %peak and reset 37 | vreset = -pi; 38 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 39 | v_ = v; %temporary storage variable for integration 40 | 41 | j = 1; 42 | time = zeros(round(nt/store),1); 43 | RECB = zeros(5,round(2*round(nt/store))); 44 | REC = zeros(10,round(nt/store)); 45 | tspike = zeros(8*nt,2); 46 | ns = 0; 47 | tic 48 | SD = 0; 49 | BPhi = zeros(N,m); 50 | z = zeros(m,1); 51 | step = 50; %Sets the frequency of RLS 52 | imin = round(tmin/dt); %Start RLS 53 | icrit = round((tcrit/dt)); %Stop RLS 54 | 55 | 56 | Pinv = eye(N)*dt*10; 57 | i = 1; 58 | %% 59 | ilast = i; 60 | %icrit = ilast; 61 | for i = ilast :1:nt 62 | JX = IPSC + E*z; %current 63 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 64 | v = v_ + dt*(dv); %Euler integration plus refractory period. 65 | index = find(v>=vpeak); 66 | if length(index)>0 67 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 68 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 69 | ns = ns + length(index); 70 | end 71 | 72 | 73 | 74 | if tr == 0 75 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 76 | r = r *exp(-dt/td) + (v>=vpeak)/td; 77 | else 78 | IPSC = IPSC*exp(-dt/tr) + h*dt; 79 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 80 | 81 | r = r*exp(-dt/tr) + hr*dt; 82 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 83 | end 84 | 85 | 86 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 87 | v_ = v; 88 | %only store stuff every index variable. 89 | 90 | 91 | 92 | 93 | z = BPhi'*r; 94 | err = z - xz(i,:)'; 95 | 96 | 97 | if mod(i,step)==1 98 | if i > imin 99 | if i < icrit 100 | cd = Pinv*r; 101 | BPhi = BPhi - (cd*err'); 102 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 103 | end 104 | end 105 | end 106 | 107 | if mod(i,store) == 1; 108 | j = j + 1; 109 | time(j,:) = dt*i; 110 | current(j,:) = z; 111 | REC(:,j) = v(1:10); 112 | RECB(:,j) = BPhi(1:5,1); 113 | end 114 | 115 | 116 | if mod(i,round(0.1/dt))==1 117 | dt*i 118 | figure(1) 119 | drawnow 120 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 121 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 122 | xlim([dt*i-1,dt*i]) 123 | xlabel('Time') 124 | ylabel('x(t)') 125 | 126 | figure(2) 127 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 128 | xlabel('Time') 129 | ylabel('\phi_j') 130 | 131 | figure(3) 132 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 133 | ylim([0,100]) 134 | xlabel('Time') 135 | ylabel('Neuron Index') 136 | end 137 | 138 | end 139 | %% 140 | %ns 141 | current = current(1:1:j,:); 142 | REC = REC(:,1:1:j); 143 | %REC2 = REC2(:,1:1:j); 144 | nt = length(current); 145 | time = (1:1:nt)*T/nt; 146 | xhat = current; 147 | tspike = tspike(1:1:ns,:); 148 | M = tspike(tspike(:,2)>dt*icrit,:); 149 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 150 | %% 151 | Z = eig(OMEGA); %eigenvalues beofre learning 152 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 153 | figure(42) 154 | plot(Z,'k.'), hold on 155 | plot(Z2,'r.') 156 | xlabel('Re\lambda') 157 | ylabel('Im\lambda') 158 | legend('Pre-Learning','Post-Learning') 159 | 160 | %% 161 | figure(43) 162 | for z = 1:1:10 163 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 164 | end 165 | xlim([9,10]) 166 | xlabel('Time (s)') 167 | ylabel('Neuron Index') 168 | title('Post Learning') 169 | figure(66) 170 | for z = 1:1:10 171 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 172 | end 173 | xlim([0,1]) 174 | title('Pre-Learning') 175 | xlabel('Time (s)') 176 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCEVDPHARMONIC.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; 12 | nt = round(T/dt); 13 | tx = (1:1:nt)*dt; 14 | 15 | %% Van der Pol 16 | T = 15; nt = round(T/dt); 17 | mu = 0.5; %Sets the behavior 18 | MD = 10; %Scale system in space 19 | TC = 20; %Scale system in time 20 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 21 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 22 | tx = (1:1:nt)*dt; 23 | xz(:,1) = interp1(t,y(:,1),tx); 24 | xz(:,2) = interp1(t,y(:,2),tx); 25 | G = 10; Q = 10^4; T = 15; tmin = 5; tcrit = 10; 26 | 27 | 28 | %% 29 | m = min(size(xz)); %dimensionality of teacher 30 | E = (2*rand(N,m)-1)*Q; %encoders 31 | BPhi = zeros(N,m); %Decoders 32 | %% Compute Neuronal Intercepts and Tuning Curves 33 | initial = 0; 34 | p = 0.1; %Sparse Coupling 35 | OMEGA = G*randn(N,N).*(rand(N,N)0); 41 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 42 | end 43 | 44 | %% Storage Matrices and Initialization 45 | store = 10; %don't store every time step, saves time. 46 | current = zeros(nt,m); %storage variable for output current 47 | IPSC = zeros(N,1); %post synaptic current 48 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 49 | JD = 0*IPSC; 50 | 51 | vpeak = pi; %peak and reset 52 | vreset = -pi; 53 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 54 | v_ = v; %temporary storage variable for integration 55 | 56 | j = 1; 57 | time = zeros(round(nt/store),1); 58 | RECB = zeros(5,round(2*round(nt/store))); 59 | REC = zeros(10,round(nt/store)); 60 | tspike = zeros(8*nt,2); 61 | ns = 0; 62 | tic 63 | SD = 0; 64 | BPhi = zeros(N,m); 65 | z = zeros(m,1); 66 | step = 50; %Sets the frequency of RLS 67 | imin = round(tmin/dt); %Start RLS 68 | icrit = round((tcrit/dt)); %Stop RLS 69 | 70 | E = Q*E; 71 | Pinv = eye(N)*dt*2; 72 | i = 1; 73 | %% 74 | ilast = i; 75 | %icrit = ilast; 76 | for i = ilast :1:nt 77 | JX = IPSC + E*z; %current 78 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 79 | v = v_ + dt*(dv); %Euler integration plus refractory period. 80 | index = find(v>=vpeak); 81 | if length(index)>0 82 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 83 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 84 | ns = ns + length(index); 85 | end 86 | 87 | 88 | 89 | if tr == 0 90 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 91 | r = r *exp(-dt/td) + (v>=vpeak)/td; 92 | else 93 | IPSC = IPSC*exp(-dt/tr) + h*dt; 94 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 95 | 96 | r = r*exp(-dt/tr) + hr*dt; 97 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 98 | end 99 | 100 | 101 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 102 | v_ = v; 103 | %only store stuff every index variable. 104 | 105 | 106 | 107 | 108 | z = BPhi'*r; 109 | err = z - xz(i,:)'; 110 | 111 | 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | if mod(i,store) == 1; 123 | j = j + 1; 124 | time(j,:) = dt*i; 125 | current(j,:) = z; 126 | REC(:,j) = v(1:10); 127 | RECB(:,j) = BPhi(1:5,1); 128 | end 129 | 130 | 131 | if mod(i,round(0.1/dt))==1 132 | dt*i 133 | figure(1) 134 | drawnow 135 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 136 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 137 | xlim([dt*i-1,dt*i]) 138 | xlabel('Time') 139 | ylabel('x(t)') 140 | 141 | figure(2) 142 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 143 | xlabel('Time') 144 | ylabel('\phi_j') 145 | 146 | figure(3) 147 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 148 | ylim([0,100]) 149 | xlabel('Time') 150 | ylabel('Neuron Index') 151 | end 152 | 153 | end 154 | %% 155 | %ns 156 | current = current(1:1:j,:); 157 | REC = REC(:,1:1:j); 158 | %REC2 = REC2(:,1:1:j); 159 | nt = length(current); 160 | time = (1:1:nt)*T/nt; 161 | xhat = current; 162 | tspike = tspike(1:1:ns,:); 163 | M = tspike(tspike(:,2)>dt*icrit,:); 164 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 165 | %% 166 | Z = eig(OMEGA); %eigenvalues before learning 167 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 168 | figure(42) 169 | plot(Z,'k.'), hold on 170 | plot(Z2,'r.') 171 | xlabel('Re\lambda') 172 | ylabel('Im\lambda') 173 | legend('Pre-Learning','Post-Learning') 174 | 175 | %% 176 | figure(43) 177 | for z = 1:1:10 178 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 179 | end 180 | xlim([9,10]) 181 | xlabel('Time (s)') 182 | ylabel('Neuron Index') 183 | title('Post Learning') 184 | figure(66) 185 | for z = 1:1:10 186 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 187 | end 188 | xlim([0,1]) 189 | title('Pre-Learning') 190 | xlabel('Time (s)') 191 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/THETAFORCEVDPRELAX.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | 5 | %% Fixed parameters across all simulations 6 | dt = 0.00001; %time step 7 | N = 2000; %Network Size 8 | td = 0.05; %decay time 9 | tr = 0.002; %Rise time 10 | %% 11 | T = 15; 12 | nt = round(T/dt); 13 | tx = (1:1:nt)*dt; 14 | 15 | %% Van der Pol 16 | T = 15; nt = round(T/dt); 17 | mu = 5; %Sets the behavior 18 | MD = 10; %Scale system in space 19 | TC = 20; %Scale system in time 20 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,[0.1;0.1]); %run once to get to steady state oscillation 21 | [t,y]= ode45(@(t,y)vanderpol(mu,MD,TC,t,y),0:0.001:T,y(end,:)); 22 | tx = (1:1:nt)*dt; 23 | xz(:,1) = interp1(t,y(:,1),tx); 24 | xz(:,2) = interp1(t,y(:,2),tx); 25 | G = 10; Q = 10^4; T = 15; tmin = 5; tcrit = 10; 26 | 27 | 28 | %% 29 | m = min(size(xz)); %dimensionality of teacher 30 | E = Q*(2*rand(N,m)-1); %encoders 31 | BPhi = zeros(N,m); %Decoders 32 | %% Compute Neuronal Intercepts and Tuning Curves 33 | initial = 0; 34 | p = 0.1; %Sparse Coupling 35 | OMEGA = G*randn(N,N).*(rand(N,N)0); 41 | OMEGA(i,QS) = OMEGA(i,QS) - sum(OMEGA(i,QS))/length(QS); 42 | end 43 | 44 | %% Storage Matrices and Initialization 45 | store = 10; %don't store every time step, saves time. 46 | current = zeros(nt,m); %storage variable for output current 47 | IPSC = zeros(N,1); %post synaptic current 48 | h = zeros(N,1); r = zeros(N,1); hr = zeros(N,1); 49 | JD = 0*IPSC; 50 | 51 | vpeak = pi; %peak and reset 52 | vreset = -pi; 53 | v = vreset + (vpeak-vreset)*rand(N,1); %initialze voltage 54 | v_ = v; %temporary storage variable for integration 55 | 56 | j = 1; 57 | time = zeros(round(nt/store),1); 58 | RECB = zeros(5,round(2*round(nt/store))); 59 | REC = zeros(10,round(nt/store)); 60 | tspike = zeros(8*nt,2); 61 | ns = 0; 62 | tic 63 | SD = 0; 64 | BPhi = zeros(N,m); 65 | z = zeros(m,1); 66 | step = 50; %Sets the frequency of RLS 67 | imin = round(tmin/dt); %Start RLS 68 | icrit = round((tcrit/dt)); %Stop RLS 69 | 70 | 71 | Pinv = eye(N)*dt*2; 72 | i = 1; 73 | %% 74 | ilast = i; 75 | %icrit = ilast; 76 | for i = ilast :1:nt 77 | JX = IPSC + E*z; %current 78 | dv = 1-cos(v) + (1+cos(v)).*JX*(pi)^2; %dv 79 | v = v_ + dt*(dv); %Euler integration plus refractory period. 80 | index = find(v>=vpeak); 81 | if length(index)>0 82 | JD = sum(OMEGA(:,index),2); %compute the increase in current due to spiking 83 | tspike(ns+1:ns+length(index),:) = [index,0*index+dt*i]; 84 | ns = ns + length(index); 85 | end 86 | 87 | 88 | 89 | if tr == 0 90 | IPSC = IPSC*exp(-dt/td)+ JD*(length(index)>0)/(td); 91 | r = r *exp(-dt/td) + (v>=vpeak)/td; 92 | else 93 | IPSC = IPSC*exp(-dt/tr) + h*dt; 94 | h = h*exp(-dt/td) + JD*(length(index)>0)/(tr*td); %Integrate the current 95 | 96 | r = r*exp(-dt/tr) + hr*dt; 97 | hr = hr*exp(-dt/td) + (v>=vpeak)/(tr*td); 98 | end 99 | 100 | 101 | v = v + (vreset - v).*(v>=vpeak); %reset with spike time interpolant implemented. 102 | v_ = v; 103 | %only store stuff every index variable. 104 | 105 | 106 | 107 | 108 | z = BPhi'*r; 109 | err = z - xz(i,:)'; 110 | 111 | 112 | if mod(i,step)==1 113 | if i > imin 114 | if i < icrit 115 | cd = Pinv*r; 116 | BPhi = BPhi - (cd*err'); 117 | Pinv = Pinv - ((cd)*(cd'))/( 1 + (r')*(cd)); 118 | end 119 | end 120 | end 121 | 122 | if mod(i,store) == 1; 123 | j = j + 1; 124 | time(j,:) = dt*i; 125 | current(j,:) = z; 126 | REC(:,j) = v(1:10); 127 | RECB(:,j) = BPhi(1:5,1); 128 | end 129 | 130 | 131 | if mod(i,round(0.1/dt))==1 132 | dt*i 133 | figure(1) 134 | drawnow 135 | plot(tx(1:1:i),xz(1:1:i,:),'k','LineWidth',2), hold on 136 | plot(time(1:1:j),current(1:1:j,:),'b--','LineWidth',2), hold off 137 | xlim([dt*i-1,dt*i]) 138 | xlabel('Time') 139 | ylabel('x(t)') 140 | 141 | figure(2) 142 | plot(time(1:1:j),RECB(1:5,1:1:j),'.') 143 | xlabel('Time') 144 | ylabel('\phi_j') 145 | 146 | figure(3) 147 | plot(tspike(1:1:ns,2), tspike(1:1:ns,1),'k.') 148 | ylim([0,100]) 149 | xlabel('Time') 150 | ylabel('Neuron Index') 151 | end 152 | 153 | end 154 | %% 155 | %ns 156 | current = current(1:1:j,:); 157 | REC = REC(:,1:1:j); 158 | %REC2 = REC2(:,1:1:j); 159 | nt = length(current); 160 | time = (1:1:nt)*T/nt; 161 | xhat = current; 162 | tspike = tspike(1:1:ns,:); 163 | M = tspike(tspike(:,2)>dt*icrit,:); 164 | AverageFiringRate = length(M)/(N*(T-dt*icrit)) 165 | %% 166 | Z = eig(OMEGA); %eigenvalues before learning 167 | Z2 = eig(OMEGA+E*BPhi'); %eigenvalues after learning 168 | figure(42) 169 | plot(Z,'k.'), hold on 170 | plot(Z2,'r.') 171 | xlabel('Re\lambda') 172 | ylabel('Im\lambda') 173 | legend('Pre-Learning','Post-Learning') 174 | 175 | %% 176 | figure(43) 177 | for z = 1:1:10 178 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 179 | end 180 | xlim([9,10]) 181 | xlabel('Time (s)') 182 | ylabel('Neuron Index') 183 | title('Post Learning') 184 | figure(66) 185 | for z = 1:1:10 186 | plot((1:1:j)*T/j,(REC(z,1:1:j))/(2*pi)+z), hold on 187 | end 188 | xlim([0,1]) 189 | title('Pre-Learning') 190 | xlabel('Time (s)') 191 | ylabel('Neuron Index') -------------------------------------------------------------------------------- /CODE FOR SUPPLEMENTARY OSCILLATOR PANEL/THETA MODEL 50/vanderpol.m: -------------------------------------------------------------------------------- 1 | function dy = vanderpol(mu,MD,TC,t,y) 2 | dy(1,1) = mu*(y(1,1)-(y(1,1).^3)*(MD*MD/3) - y(2,1)); 3 | dy(2,1) = y(1,1)/mu; 4 | dy = dy*TC; 5 | end -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Instructions for FORCE Training Code 2 | 3 | Wilten Nicola (wnicola@imperial.ac.uk) 4 | The code is separated into folders named for their corresponding figure from the manuscript. The code is usually labelled NeuronModelFORCETask.m or NeuronModelTask.m for example THETALORENZ is the code used to run a network of theta neurons learning a trajectory generated from the Lorenz system. Some of the folders also contain matlab files for numerically integrating the supervisors (lorenz.m, vanderpol.m etc). Running the code NeuronModelFORCEtask.m trains a network to reproduce the dynamics of the supervisor using FORCE training. The code for Figure 4 (songbird example) and Figure 5 (movie replay example) does not contain the supervisor due to file size constraints. Users can however provide their own supervisors in these examples. Some folders contain pre-trained weight matrices saved in .mat files. These folders contain a file labelled NETWORKSIM.mat which loads the weight matrix, and simulates the pre-trained network with random initial conditions. Also note, that there is a slight discrepancy in the reported parameter set for the Izhikevich neuron model for one of the supplementary oscillatory examples, which has b = -2 ns/mv, vthresh = -19.2 mv instead if b = 0 ns/mv and vthresh = -20 mv, as reported. This does not affect convergence results for the supplementary oscillator figure but leads to slight differences in reported post-training firing rates for the supplementary oscillatory figure. --------------------------------------------------------------------------------