123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- function [cid, alpha, mu] = circ_clust(alpha, numclust, disp)
- %
- % [cid, alpha, mu] = circClust(alpha, numclust, disp)
- % Performs a simple agglomerative clustering of angular data.
- %
- % Input:
- % alpha sample of angles
- % numclust number of clusters desired, default: 2
- % disp show plot at each step, default: false
- %
- % Output:
- % cid cluster id for each entry of alpha
- % alpha sorted angles, matched with cid
- % mu mean direction of angles in each cluster
- %
- % Run without any input arguments for demo mode.
- %
- % Circular Statistics Toolbox for Matlab
- % By Marc J. Velasco and Philipp Berens, 2009
- % velasco@ccs.fau.edu
- % Distributed under Open Source BSD License
- if nargin < 2, numclust = 5; end;
- if nargin < 3, disp = 0; end
- if nargin < 1
- % demo mode
- n = 20;
- alpha = 2*pi*rand(n,1)-pi;
- numclust = 4;
- disp = 1;
- end;
- n = length(alpha);
- if n < numclust, error('Not enough data for clusters.'), end
- % prepare data
- cid = (1:n)';
- % main clustering loop
- num_unique = length(unique(cid));
- num_clusters_wanted = numclust;
- while(num_unique > num_clusters_wanted)
- % find centroid means...
-
- % calculate the means for each putative cluster
- mu = NaN(n,1);
- for j=1:n
- if sum(cid==j)>0
- mu(j) = circ_mean(alpha(cid==j)');
- end
- end
-
- % find distance between centroids...
- mudist = abs(circ_dist2(mu));
- % find closest pair of clusters/datapoints
- mindist = min(mudist(tril(ones(size(mudist)),-1)==1));
- [row, col] = find(mudist==mindist);
-
- % update cluster id's
- cid(cid==max(row)) = min(col);
- % update stop criteria
- num_unique = length(unique(cid));
- end
- % renumber cluster ids (so cids [1 3 7 10] => [1 2 3 4]
- cid2 = cid;
- uniquecids = unique(cid);
- for j=1:length(uniquecids)
- cid(cid2==uniquecids(j)) = j;
- end
- % compute final cluster means
- mu = NaN(num_unique,1);
- r = NaN(num_unique,1);
- for j=1:num_unique
- if sum(cid==j)>0
- mu(j) = circ_mean(alpha(cid==j)');
- r(j) = circ_r(alpha(cid==j)');
- end
- end
- if disp
- % plot output
- z2 = exp(i*alpha);
- plotColor(real(z2), imag(z2), cid, 2)
- zmu = r.*exp(i*mu);
- plotColor(real(zmu), imag(zmu), 1:num_unique, 2, '*', 10, 1)
- axis square
- set(gca, 'XLim', [-1, 1]);
- set(gca, 'YLim', [-1, 1]);
- end
- function plotColor(x, y, c, varargin)
- % FUNCTION plotColor(x, y, c, [figurenum], [pstring], [markersize], [overlay_tf]);
- % plots a scatter plot for x, y, using color values in c (c should be
- % categorical info), with c same size as x and y;
- % fourth argument can be figure#, otherwise, uses figure(1);
- %
- % colors should be positive integes
- % copyright (c) 2009 Marc J. Velasco
- if nargin < 4
- figurenum = 1;
- else
- figurenum = varargin{1};
- end
- if nargin < 5
- pstring = '.';
- else
- pstring = varargin{2};
- end
- if nargin < 6
- ms = 10;
- else
- ms = varargin{3};
- end
- if nargin < 7
- overlay = 0;
- else
- overlay = varargin{4};
- end
- csmall = unique(c);
- figure(figurenum);
- if ~overlay, close(figurenum); end
- figure(figurenum);
- colors={'y', 'b', 'r', 'g', 'c', 'k', 'm'};
- hold on;
- for j=1:length(csmall);
-
- ci = (c == csmall(j));
- plot(x(ci), y(ci), strcat(pstring, colors{mod(j, length(colors))+1}), 'MarkerSize', ms);
-
- end
- if ~overlay, hold off; end
- figure(figurenum)
|