diff --git a/linearalgebra/simulations/covareigen.m b/linearalgebra/simulations/covareigen.m new file mode 100644 index 0000000..1acf330 --- /dev/null +++ b/linearalgebra/simulations/covareigen.m @@ -0,0 +1,82 @@ +function covareigen( x, y, pm, w, h ) +% computes covariance matrix from the pairs x, y +% diagonalizes covariance matrix +% x and y are column vectors +% pm: 0 - scatter of data, 1 histogram, 2 multivariate gauus from +% covariance matrix, 1 and 2 require w and h +% w and h are the width and the height (in data units) for plotting +% histograms instead of scatter + + % covariance matrix: + cv = cov( [ x y ] ); + + % eigen values: + [ v , d] = eig( cv ) + s = sign( v ); + s(1,:) = s(2,:); + v = v .* s; + + % plots: + subplot( 2, 2, 1 ); + hold on; + + if (pm > 0) & (nargin == 5) + if pm == 1 + % histogram of data: + xp = -w:0.5:w; + yp = -h:0.5:h; + [n,c] = hist3([x y], { xp, yp } ); + contourf( c{1}, c{2}, n' ); + else + xp = -w:0.1:w; + yp = -h:0.1:h; + [xg,yg] = meshgrid( xp, yp ); + xy = [ xg(:) yg(:) ]; + gauss = reshape( exp(-0.5*diag(xy*inv(cv)*xy'))/sqrt((2.0*pi)^2.0*det(cv)), size( xg ) ); + contourf( xp, yp, gauss ) + end + colormap( 'gray' ); + else + % scatter plot: + scatter( x, y, 'b', 'filled', 'MarkerEdgeColor', 'white' ); + end + + % plot eigenvectors: + quiver( ones( 1, 2 ).*mean( x ), ones( 1, 2 )*mean(y), v(1,:).*sqrt(diag(d))', v(2,:).*sqrt(diag(d))', 'r', 'LineWidth', 3, 'AutoScale', 'off', 'AutoScaleFactor', 1.0, 'MaxHeadSize', 0.7 ) + + axis( 'equal' ); + hold off; + + subplot( 2, 2, 3 ); + hist( x, 50, 'b' ); + + % sort the eigenvalues: + [d,inx] = sort( diag(d), 'descend' ); + + subplot( 2, 2, 2 ); + hold on; + % subtract means: + x = x - mean( x ); + y = y - mean( y ); + % project onto eigenvectors: + nx = [ x y ] * v(:,inx(1)); + ny = [ x y ] * v(:,inx(2)); + cv = cov( [nx, ny] ) + [ v , d] = eig( cv ) + if (pm > 0) & (nargin == 5) + if pm == 1 + [n,c] = hist3([nx ny], { xp, yp } ); + contourf( c{1}, c{2}, n' ); + else + gauss = reshape( exp(-0.5*diag(xy*inv(cv)*xy'))/sqrt((2.0*pi)^2.0*det(cv)), size( xg ) ); + contourf( xp, yp, gauss ) + end + else + scatter( nx, ny, 'b', 'filled', 'MarkerEdgeColor', 'white' ); + end + axis( 'equal' ); + hold off; + + subplot( 2, 2, 4 ); + hist( nx, 50, 'b' ); +end diff --git a/linearalgebra/simulations/covareigen3.m b/linearalgebra/simulations/covareigen3.m new file mode 100644 index 0000000..c11f2de --- /dev/null +++ b/linearalgebra/simulations/covareigen3.m @@ -0,0 +1,45 @@ +function covareigen3( x, y, z ) +% computes covariance matrix from the triples x, y, z +% diagonalizes covariance matrix +% x, y and z are column vectors + + % covariance matrix: + cv = cov( [ x y z ] ); + + % eigen values: + [ v , d] = eig( cv ) + + % plots: + subplot( 1, 2, 1 ); + hold on; + + % scatter plot: + view( 3 ); + scatter3( x, y, z, 0.1, 'b', 'filled', 'MarkerEdgeColor', 'blue' ); + xlabel( 'x' ); + ylabel( 'y' ); + zlabel( 'z' ); + grid on; + + % plot eigenvectors: + quiver3( ones( 1, 3 ).*mean( x ), ones( 1, 3 )*mean(y), ones( 1, 3 )*mean(z), v(1,:).*sqrt(diag(d))', v(2,:).*sqrt(diag(d))', v(3,:).*sqrt(diag(d))', 'r', 'LineWidth', 3, 'AutoScale', 'off', 'AutoScaleFactor', 1.0, 'MaxHeadSize', 0.7 ) + + %axis( 'equal' ); + hold off; + + % sort the eigenvalues: + [d,inx] = sort( diag(d), 'descend' ); + + subplot( 2, 2, 2 ); + hold on; + % subtract means: + x = x - mean( x ); + y = y - mean( y ); + % project onto eigenvectors: + nx = [ x y z ] * v(:,inx(1)); + ny = [ x y z ] * v(:,inx(2)); + scatter( nx, ny, 'b', 'filled', 'MarkerEdgeColor', 'white' ); + axis( 'equal' ); + hold off; + +end diff --git a/linearalgebra/simulations/covareigen3examples.m b/linearalgebra/simulations/covareigen3examples.m new file mode 100644 index 0000000..3d16628 --- /dev/null +++ b/linearalgebra/simulations/covareigen3examples.m @@ -0,0 +1,14 @@ +n = 10000; + +% three distributions: +x = randn( n, 1 ); +y = randn( n, 1 ); +z = randn( n, 1 ); +f = figure( 'Position', [ scrsz(3)/2 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2 ]); +d = [ 0 4 -4 8 ]; +for k = 1:4 + x((k-1)*n/4+1:k*n/4) = x((k-1)*n/4+1:k*n/4) + d(k); + y((k-1)*n/4+1:k*n/4) = y((k-1)*n/4+1:k*n/4) - d(k); + z((k-1)*n/4+1:k*n/4) = z((k-1)*n/4+1:k*n/4) + d(k); +end +covareigen3( x, y, z ); diff --git a/linearalgebra/simulations/covareigenexamples.m b/linearalgebra/simulations/covareigenexamples.m new file mode 100644 index 0000000..f360e8c --- /dev/null +++ b/linearalgebra/simulations/covareigenexamples.m @@ -0,0 +1,35 @@ +scrsz = get( 0, 'ScreenSize' ); +set( 0, 'DefaultFigurePosition', [ scrsz(3)/2 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2 ] ); + +% correlation coefficients: +n = 10000; +x = randn( n, 1 ); +f = figure( 1 ); +for r = 0.01:0.199:1 + fprintf( 'Correlation = %g\n', r ); + clf( f ); + y = r*x + sqrt(1-r^2)*randn( n, 1 ); + covareigen( x, y, 2, 5.0, 3.0 ); + key = waitforbuttonpress; +end +return + +% two distributions: +n = 10000; +x1 = randn( n/2, 1 ); +y1 = randn( n/2, 1 ); +x2 = randn( n/2, 1 ); +y2 = randn( n/2, 1 ); +f = figure( 1 ); +pause( 'on' ); +for d = 0:1:5 + fprintf( 'Distance = %g\n', d ); + clf( f ); + d2 = d / sqrt( 2.0 ); + x = [ x1; x2 ]; + y = [ y1+d2; y2-d2 ]; + scrsz = get(0,'ScreenSize'); + covareigen( x, y, 1, 10.0, 7.0 ); + %key = waitforbuttonpress; + pause( 1.0 ); +end diff --git a/linearalgebra/simulations/matrix2dtrafos.m b/linearalgebra/simulations/matrix2dtrafos.m new file mode 100644 index 0000000..da6840e --- /dev/null +++ b/linearalgebra/simulations/matrix2dtrafos.m @@ -0,0 +1,74 @@ +m = [ 1 0; 0 1]; +matrixbox( m ); +title( 'Identity' ); +waitforbuttonpress; + +m = [ 2 0; 0 1]; +matrixbox( m ); +title( 'Scale x' ); +waitforbuttonpress; + +m = [ 1 0; 0 2]; +matrixbox( m ); +title( 'Scale y' ); +waitforbuttonpress; + +m = [ 2 0; 0 2]; +matrixbox( m ); +title( 'Scale both' ); +waitforbuttonpress; + +m = [ -1 0; 0 1]; +matrixbox( m ); +title( 'Flip x' ); +waitforbuttonpress; + +m = [ 1 0; 0 -1]; +matrixbox( m ); +title( 'Flip y' ); +waitforbuttonpress; + +m = [ -1 0; 0 -1]; +matrixbox( m ); +title( 'Flip both' ); +waitforbuttonpress; + +m = [ 1 0; 1 1]; +matrixbox( m ); +title( 'Shear x' ); +waitforbuttonpress; + +m = [ 1 1; 0 1]; +matrixbox( m ); +title( 'Shear y' ); +waitforbuttonpress; + +phi = 0.1667*pi; +m = [ cos(phi) -sin(phi); sin(phi) cos(phi)]; +matrixbox( m ); +title( 'Rotate 30' ); +waitforbuttonpress; + +phi = 0.333*pi; +m = [ cos(phi) -sin(phi); sin(phi) cos(phi)]; +matrixbox( m ); +title( 'Rotate 60' ); +waitforbuttonpress; + +phi = 0.5*pi; +m = [ cos(phi) -sin(phi); sin(phi) cos(phi)]; +matrixbox( m ); +title( 'Rotate 90' ); +waitforbuttonpress; + +phi = 0.75*pi; +m = [ cos(phi) -sin(phi); sin(phi) cos(phi)]; +matrixbox( m ); +title( 'Rotate 135' ); +waitforbuttonpress; + +phi = 1.0*pi; +m = [ cos(phi) -sin(phi); sin(phi) cos(phi)]; +matrixbox( m ); +title( 'Rotate 180' ); +waitforbuttonpress; diff --git a/linearalgebra/simulations/matrixbox.m b/linearalgebra/simulations/matrixbox.m new file mode 100644 index 0000000..5abbfa0 --- /dev/null +++ b/linearalgebra/simulations/matrixbox.m @@ -0,0 +1,24 @@ +function matrixbox( m ) +% visualizes the effect of a matrix m on a set of vectors forming a box +% m: a 2x2 matrix + + v = [ 0 1 1 0 0; 0 0 1 1 0]; + w = m*v; + clf; + hold on; + %set(gca, 'Xtick', [], 'Ytick', [], 'box', 'off') + % axis: + plot( [-2 2], [0 0], 'k', 'LineWidth', 1 ); + plot( [0 0], [-2 2], 'k', 'LineWidth', 1 ); + % old box: + plot( v(1,:), v(2,:), 'k', 'LineWidth', 1.0 ) + quiver( [v(1,1)], [v(2,1)], [v(1,3)], [v(2,3)], 1.0, 'k', 'LineWidth', 2.0 ); + scatter( [v(1,2)], [v(2,2)], 60.0, 'filled', 'k' ); + % transfomred box: + plot( w(1,:), w(2,:), 'b', 'LineWidth', 2.0 ) + quiver( [w(1,1)], [w(2,1)], [w(1,3)], [w(2,3)], 1.0, 'b', 'LineWidth', 3.0 ); + scatter( [w(1,2)], [w(2,2)], 100.0, 'filled', 'b' ); + hold off; + xlim( [ -2 2 ] ); + ylim( [ -2 2 ] ); +end diff --git a/linearalgebra/simulations/plotvector.m b/linearalgebra/simulations/plotvector.m new file mode 100644 index 0000000..668818f --- /dev/null +++ b/linearalgebra/simulations/plotvector.m @@ -0,0 +1,22 @@ +function plotvector( v, s, sp ) +% plot an arrow for the 2D-vector v +% v: the 2D vector +% s: a string passed to quiver for the color +% sp: if this string is set it defines the color of some helper lines + + if nargin < 2 + s = 'b'; + end + quiver( [0.0], [0.0], [v(1)], [v(2)], 1.0, s ); + grid on; + if nargin == 3 + hh = ishold; + if ~hh + hold on; + end + plot( [0.0 v(1) v(1)], [0.0 0.0 v(2)], sp ); + if ~hh + hold off; + end + end +end diff --git a/linearalgebra/simulations/plotvector3.m b/linearalgebra/simulations/plotvector3.m new file mode 100644 index 0000000..d93e873 --- /dev/null +++ b/linearalgebra/simulations/plotvector3.m @@ -0,0 +1,24 @@ +function plotvector3( v, s, sp ) +% plot an arrow for the 3D-vector v +% v: the 3D vector +% s: a string passed to quiver for the color +% sp: if this string is set it defines the color of some helper lines + + if nargin < 2 + s = 'b'; + end + quiver3( [0.0], [0.0], [0.0], [v(1)], [v(2)], [v(3)], 1.0, s ); + view( 42, 12 ); + grid on + if nargin == 3 + hh = ishold; + if ~hh + hold on; + end + plot3( [v(1) v(1)], [v(2) v(2)], [0.0 v(3)], sp ); + plot3( [0.0 v(1) v(1)], [v(2) v(2) 0.0], [0.0 0.0 0.0], sp ); + if ~hh + hold off; + end + end +end diff --git a/linearalgebra/simulations/spikesortingwave.m b/linearalgebra/simulations/spikesortingwave.m new file mode 100644 index 0000000..369915e --- /dev/null +++ b/linearalgebra/simulations/spikesortingwave.m @@ -0,0 +1,127 @@ +% generate spikes: +n = 1000; +misi = 0.01; +isis = exprnd( misi, n, 1 ); +isis = isis + 0.01; +spikes = cumsum( isis ); +p = rand( size( spikes ) ); + +% spike waveforms: +dt = 0.0001; +x = -0.01:dt:0.01; +y1 = 2.0*exp( -(x-0.0003).^2/2.0/0.0005^2 ) - 1.4*exp( -(x-0.0005).^2/2.0/0.0005^2 ); +y2 = exp( -x.^2/2.0/0.002^2 ).*cos(2.0*pi*x/0.005); +p12 = 0.5; + +% voltage trace: +noise = 0.2; +t = 0:dt:spikes(end)+3.0*x(end); +v = noise*randn( 1, length( t ) ); +for k = 1:length( spikes ) + inx = ceil( spikes(k)/dt ); + if p(k) < p12 + v(inx:inx+length(x)-1) = v(inx:inx+length(x)-1) + y1; + else + v(inx:inx+length(x)-1) = v(inx:inx+length(x)-1) + y2; + end +end + +figure( 1 ); +clf; +plot( t(t<1.0), v(t<1.0) ); +hold on; + +% find peaks: +thresh = 0.7; +inx = find( v(2:end-1) > thresh & v(1:end-2)<v(2:end-1) & v(2:end-1) > v(3:end) ) + 1; +spiket = t(inx); +spikev = v(inx); +tinx = inx; +for k=1:2 + inx = find( ( spiket(2:end-1)-spiket(1:end-2)>0.005 | spikev(2:end-1) > spikev(1:end-2) ) & ( spiket(3:end)-spiket(2:end-1)>0.005 | spikev(2:end-1) > spikev(3:end) ) )+1; + spiket = spiket(inx); + spikev = spikev(inx); + tinx = tinx(inx); +end +scatter( spiket(spiket<1.0), spikev(spiket<1.0), 100.0, 'r', 'filled' ); +%scatter( t(tinx), v(tinx), 100.0, 'r', 'filled' ); +hold off; + +% spike waveform snippets: +w = ceil( 0.005/dt ); +vs = []; +for k=1:length(tinx) + vs = [ vs; v(tinx(k)-w:tinx(k)+w-1) ]; +end +ts = t(1:size(vs,2)); +ts = ts - ts(floor(length(ts)/2)); +figure( 2 ); +clf; +hold on +for k=1:size(vs,1) + plot( ts, vs(k,:), '-b' ); +end +hold off + +% pca: +cv = cov( vs ); +[ ev , ed ] = eig( cv ); +[d,dinx] = sort( diag(ed), 'descend' ); +% spectrum of eigenvalues: +figure( 3 ); +clf; +subplot( 4, 1, 1 ); +scatter( 1:length(d), d, 'b', 'filled' ); +% project onto eigenvectors: +nx = vs * ev(:,dinx(1)); +ny = vs * ev(:,dinx(2)); +%scatter( nx, ny, 'b', 'filled', 'MarkerEdgeColor', 'white' ); +%hold on; + +% features: +subplot( 4, 2, 5 ); +plot( 1000.0*ts, ev(:,dinx(1)), 'g', 'LineWidth', 2 ); +subplot( 4, 2, 6 ); +plot( 1000.0*ts, ev(:,dinx(2)), 'r', 'LineWidth', 2 ); + +% clustering: +%kx = kmeans( [ nx, ny ], 2 ); +% nx smaller or greater a threshold: +kthresh = 1.6; +kx = ones( size( vs, 1 ), 1 ); +kx(nx>kthresh) = 2; + +subplot( 4, 1, 2 ); +scatter( nx(kx==1), ny(kx==1), 'g', 'filled', 'MarkerEdgeColor', 'white' ); +hold on; +scatter( nx(kx==2), ny(kx==2), 'r', 'filled', 'MarkerEdgeColor', 'white' ); +hold off; + +% show sorted spike waveforms: +subplot( 4, 2, 7 ); +hold on +kinx1 = find(kx==1); +for k=1:length(kinx1) + plot( 1000.0*ts, vs(kinx1(k),:), '-g' ); +end +plot( 1000.0*x, y1, '-k', 'LineWidth', 2 ); +xlim( [ 1000.0*ts(1) 1000.0*ts(end) ] ) +hold off +subplot( 4, 2, 8 ); +hold on +kinx2 = find(kx==2); +for k=1:length(kinx2) + plot( 1000.0*ts, vs(kinx2(k),:), '-r' ); +end +plot( 1000.0*x, y2, '-k', 'LineWidth', 2 ); +xlim( [ 1000.0*ts(1) 1000.0*ts(end) ] ) +hold off + +% spike trains: +figure( 1 ); +hold on; +six1 = find( spiket(kinx1)<1.0 ); +scatter( spiket(kinx1(six1)), spikev(kinx1(six1)), 100.0, 'g', 'filled' ); +six2 = find( spiket(kinx2)<1.0 ); +scatter( spiket(kinx2(six2)), spikev(kinx2(six2)), 100.0, 'r', 'filled' ); +hold off; diff --git a/linearalgebra/simulations/spiketime.m b/linearalgebra/simulations/spiketime.m new file mode 100644 index 0000000..fb22807 --- /dev/null +++ b/linearalgebra/simulations/spiketime.m @@ -0,0 +1,11 @@ +p = 0.0; +n=0; +for k = 1:length( spikes ) + %a= 0.5*(spikes(k+1)+spikes(k)); + %fprintf( 'set label %d "$T_{%d}$" at %g, -0.5 center\n', k+2, k, a ); + %fprintf( 'set arrow %d from %g, 0.3 to %g, 0.3 heads\n', k+2, spikes(k), spikes(k+1) ); + %fprintf( '%g %d\n%g %d\n\n', p, n, spikes(k), n ); + fprintf( '%g %d\n', spikes(k), n+1 ); + n = n+1; + p = spikes(k); +end