-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_aggregated_coordinates.m
79 lines (56 loc) · 2.35 KB
/
get_aggregated_coordinates.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
%% Generate aggregated spatial distribution of individuals
%
% Returns the coordinates of individuals used for the initial spatial
% distribution of individuals across the landscape in the "aggregated"
% model variant.
%
% How this works:
% 1. for each species with Ni > 1, draw a number of parents between 1 and
% Ni/10
% 2. for each individual of the species, randomly assign a parent
% 3. randomly distribute parents across the plane (homogeneous poisson
% point process)
% 4. distribute individuals around their parents in a circle with radius r
function [coords_x, coords_y] = get_aggregated_coordinates(SAD, c)
Stot = length(SAD); % Number of species
Itot = sum(SAD); % Number of Individuals
% Radius of aggregates (strongly clumped if small, more random if large)
r = c/20 ;
coords_x = [];
coords_y = [];
%% Loop over species
for s = 1:Stot
Ni = SAD(s);
if Ni>1 % distribute individuals in clumps
% randomly draw the number of parents between 1 and Ni/10
np = randi(max(1, floor(Ni/10)));
% for each individual, assign a random parent
ip = randi(np, 1, Ni);
% randomly assign center coordinates to the parents (1:1:100)
px = randi(c, 1, np);
py = randi(c, 1, np);
% randomly assign relative polar coordinates to the individuals
theta = 2*pi*(rand(Ni,1))';
rho = r*sqrt(rand(Ni,1))';
% convert these relative coordinates from polar to Cartesian
[ix_rel,iy_rel] = pol2cart(theta,rho);
% for each individual, move its relative cartesian coordinates by
% the center of their respective parent and round the result
ix = round(ix_rel+px(ip));
iy = round(iy_rel+py(ip));
else % if only one individual exists, randomly place it in the plane
ix = randi(c);
iy = randi(c);
end
coords_x = [coords_x ix];
coords_y = [coords_y iy];
end
% correct for boundary condition
coords_x = mod(coords_x-1,c)+1;
coords_y = mod(coords_y-1,c)+1;
%% Security checks of result
assert(isequal(size(coords_x), [1 Itot]) && isequal(size(coords_y), [1 Itot]),...
'Wrong size of coordinate vector')
assert(all([coords_x coords_y]>=1) && all([coords_x coords_y]<=c), ...
'Boundary condition of coordinates violated! Ouside of cxc range!')
end