function [swarming_ind] = fuzzySwarm2d(M,S); % COMPSWARM(M,S) ---- This is a computational version of the Swarming Index % presented in Watt et al. (1997), calculated for the array 'M', if M is in the % standard format. This is essentially the mean of the ratios for each group of % the number in the group to the perimeter of the group. % % The actual index used a grid of 4 squares by 6; perimeter was estimated by the % number of sides necessary to enclose the group. This function uses convhull to % find peripheral points, then the distances between each set to generate an actual % measure of the perimeter of the polygon enclosing the group. Number per group % is found by the findgroups2d function, from which the input 'S' to this function % is the output. % First, a matrix to hold to groups' swarming values is initialized. SWARM = []; % Now, one loop will consider the groups, one at a time. First the rows from the % original array, M, for the group of interest are removed and recombined with each % other. The count and perimeter can then be found. for i = 1:size(S,2) % Loop over each group. GI = S(i).members; % Find the indices into M for the group members' % rows. G = M(GI',:); % The group matrix, G, is built from these rows. g_size = size(G,1); % The number in the group, g_size, is simply the % number of rows in G. % The original index only considers groups larger than 3; so, a check is now % performed to see that the group meets this criterion, and completes the % calculations only if it does. Otherwise, matrix SWARM is left empty. if g_size > 3 % Checks for group of more than 3. K = convhull(G(:,2),G(:,3)); % The convhull function is used to find the % perimeter individuals. circ = 0; % Initialize CIRCumference measure. for j = 1:(size(K,1)-1) % This will loop over all perimeter segments. P = G(K(j,1),:); % P is the first endpoint of the segment P2 = G(K(j+1,1),:); % P2 is the other endpoint. d = dist2d(P(1,2),P(1,3),P2(1,2),P2(1,3)); % And the distance between, d. circ = circ + d; % Then these d's are added up one by one % to the circumference of the group. end % Now, the swarming index for this group is calculated, gswarm. It is put % in a matrix SWARM. gswarm = g_size / circ; SWARM = [SWARM; gswarm]; end % Ends the size check loop. end % Ends the group loop. % Since groups of 3 or less will have been ignored, a final check must be performed. % If there were any 'legal' groups at all, SWARM will have been filled with their % values. So, if SWARM is not empty at this point, the mean of it is taken (i.e. the % average index for the array is found). If there were no legal groups, i.e. only % stragglers/pairs/triplets, then -999 is entered for the index (which can easily be % weeded out later). if size(SWARM) ~= [0 0]; swarming_ind = mean(SWARM); else swarming_ind = -999; end