shiba
 All Data Structures Files Functions Variables Macros Pages
shiba.c
Go to the documentation of this file.
1 
5 #include "shiba.h"
6 
7 void shiba(phylo phy)
8 {
9  // pthreads preparation:
10  pthread_t *thread = (pthread_t *) malloc(RUN_BATCH * sizeof(pthread_t));
11  pthread_attr_t attr;
12  void *status; // for pthread_join
13  pthread_attr_init(&attr);
14  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
15 
16  // these are global variables passed between functions.
17  // Shrink the scope if poss, and rename
18  record = mem2d_i(Lineages, Spaces);
19  success = 0;
20  topresent = 0;
21  maxarea = findMaxArea();
22  maxdist = findMaxDist();
23 
24  // set disp, surv functions
27  for (int t = 0; t < Times; t++)
28  for (int s = 0; s < Spaces; s++) {
29  PSurv[t][s] = pSurvival(Area[t][s] / maxarea);
30  for (int s2 = 0; s2 < Spaces; s2++)
31  PDisp[t][s][s2] = pDispersal(Dist[t][s][s2] / maxdist);
32  }
33 
34  // initialize srandom with time
35  srandom(time(NULL));
36 
37  printf("\n# SHIBA (Simulated Historical Island Biogeography Analysis)\n\n");
38 
39  long int batch;
40  // run in batches of RUN_BATCH
41  for (batch = 0; batch < (long int)(Cfg.maxRuns/RUN_BATCH);batch++) {
42  // start threads
43  for (long int i = 0; i < RUN_BATCH ; i++)
44  pthread_create(&thread[i], &attr, biogeo, NULL);
45 
46  // collect:
47  for (long int i = 0; i < RUN_BATCH ; i++)
48  pthread_join(thread[i], &status);
49 
50  // Reporting (and adjustment)
51  fprintf(stderr,"\r> runs: %9ld; to present: %8ld; successes: %5ld",
52  batch * RUN_BATCH , topresent , success);
53  fflush(NULL); // Flush the buffer
54 
55  // check for successes
56  if (success >= Cfg.stopAfterSuccess) break;
57  }
58 
59  // Final reporting:
60  fprintf(stderr, "\n\n"); fflush(NULL);
61  printf("## Successes : %ld (in %ld runs)\n\n", success, batch * RUN_BATCH );
62  printSuccessAll(phy);
63 
64  // free3d_i(locn , Lineages, Times);
65  free2d_i(record, Lineages);
66 
67  free(thread); free(status);
68  pthread_attr_destroy(&attr);
69  pthread_mutex_destroy(&mymutex);
70 
77 }
78 
79 double findMaxArea()
80 {
81  // finds total area on the landscape
82  // was - max island size. Now unlikely that any area get 100% survival
83  double tot, max = 0.0;
84  for (int t = 0; t < Times; t++) {
85  tot = 0;
86  for (int a = 0; a < Spaces; a++) tot += Area[t][a];
87  if (tot > max) max = tot;
88  }
89  return max;
90 }
91 
92 double findMaxDist()
93 {
94  double max = 0.0;
95  for (int t = 0; t < Times; t++)
96  for (int a = 0; a < Spaces; a++)
97  for (int b = 0; b < Spaces; b++)
98  if (Dist[t][a][b] > max) max = Dist[t][a][b];
99  return max;
100 }
101 
102 void *biogeo()
103 {
104 
105  int ***locn = mem3d_i(Lineages, Times, Spaces);
106 
110 
115 
116  int ss = 0;
117  while (ss < Cfg.nStartSpaces) {
118  int rnd = (int)((double) Spaces * (double) random() /
119  (double)(RAND_MAX+1.0));
120 
127 
128  if ((!locn[0][0][rnd]) &&
129  (Area[0][rnd] > 0.0) &&
130  (Cfg.startSpace[rnd])) {
131  locn[0][0][rnd] = 1;
132  ss++;
133  }
134  }
135 
140  for (int t = 0; t < Times-1; t++) {
141  // print array at start
142  if (Cfg.verbose==1)
143  for (int i = 0; i < Lineages; i++)
144  if (LineagePeriod[i][t]) {
145  printf("t%d l%d : ", t, i);
146  for (int x = 0; x < Spaces; x++) printf("%d", locn[i][t][x]);
147  printf("\n");
148  }
149 
152  for (int l = 0; l < Lineages; l++) {
153 
156  if (LineagePeriod[l][t]) {
157 
158  int linck = 0; // the number of surv lineages from one period to next
159 
162  for (int s = 0; s < Spaces; s++) {
163 
168 
172  if (locn[l][t][s]) {
173 
180  for (int i = 0; i < Spaces ; i++) {
181  if ( ( ((double) random() / (double)(RAND_MAX+1.0))
182  < PDisp[t][s][i] ) && (i != s) && (Area[t][i] > 0.0)) {
183  locn[l][t+1][i] = 1;
184 
185  if (Cfg.verbose==1) printf(" l%d disperses from s%d to s%d\n",l,s,i);
186  linck++;
187  }
188  }
189 
196  if (((double) random() / (double)(RAND_MAX+1.0)) < PSurv[t][s]) {
197  locn[l][t+1][s] = 1;
198  linck++;
199  }
200  else if (Cfg.verbose==1) printf(
201  " l%d goes locally extinct in s%d\n", l , s);
202 
203  }
204  }
205 
210  if (!linck) {
211  if (Cfg.verbose==1) printf(" l%d has died out\n",l);
212  if (Cfg.verbose==1) printf("----------\n");
213  free3d_i(locn, Lineages, Times);
214  pthread_exit(NULL);
215  //return;
216  }
217 
218 
222  if (!LineagePeriod[l][t+1]) {
223 
231 
232  int places = 0; //number of spaces occupied by daughters of `l`
233  int placemapping[Spaces]; // mapping from 0..places to 'real' spaces
234  for (int s = 0; s < Spaces; s++)
235  if (locn[l][t+1][s]) {
236  placemapping[places] = s;
237  places++;
238  }
239  int placeck[places]; // has the place got a lineage in it?
240  for (int h = 0; h < places; h++) placeck[h] = 0;
241  int fullplaces = 0; // number of places filled
242 
245 
246  for (int q = 0; q < LineageDaughtersN[l]; q++) {
247  int placed = 0; // has this daughter been placed?
248  while (!placed) {
249 
258  int rnd = (int) ( (double) places * (double) random() /
259  (double) (RAND_MAX+1.0));
260  if (placeck[rnd]) {
261  if (fullplaces >= places) {
262  locn[LineageDaughters[l][q]][t+1][placemapping[rnd]] = 1;
263  placed = 1;
264  if (Cfg.verbose==1) printf(
265  " l%d ends; l%d begins in s%d\n", l,
266  LineageDaughters[l][q], placemapping[rnd]);
267  }
268  } else {
269  locn[LineageDaughters[l][q]][t+1][placemapping[rnd]] = 1;
270  placeck[rnd] = 1;
271  placed = 1;
272  fullplaces++;
273  if (Cfg.verbose==1) printf(
274  " l%d ends; l%d begins in s%d\n",
275  l, LineageDaughters[l][q], placemapping[rnd]);
276 
277  }
278  }
279  }
280  }
281  }
282  }
285  }
291 
292  // final layout
293  if (Cfg.verbose==1)
294  {
295  for (int i = 0; i < Lineages; i++)
296  if (LineagePeriod[i][Times-1]) {
297  printf("t%d l%d : ", Times-1, i);
298  for (int x = 0; x < Spaces; x++) printf("%d", locn[i][Times-1][x]);
299  printf("\n");
300  }
301 
302  //printExtant(Lineages);
303  }
304 
309 
310  int diffs = 0; // the count of differences between sim and obs
311  for (int l = 0; l < Lineages; l++) {
312  if (LineagePeriod[l][Times-1]) {
313  for (int s = 0; s < Spaces; s++) {
314  if (locn[l][Times-1][s] != LineageExtant[l][Times-1][s]) diffs++;
315  }
316  }
317  }
318 
322 
323  // lock mutex
324  pthread_mutex_lock(&mymutex);
325  topresent++;
326 
327  if (!diffs) {
328  success++;
329  for (int l = 0; l < Lineages; l++) {
330  for (int t = 0; t < Times; t++) {
331  if (LineagePeriod[l][t]) {
332  for (int s = 0; s < Spaces; s++)
333  record[l][s] += locn[l][t][s];
334  break;
335  }
336  }
337  }
338  }
339  pthread_mutex_unlock(&mymutex);
340 
341  if (Cfg.verbose==1) printf("-----------\n");
342 
343  free3d_i(locn, Lineages, Times);
344  pthread_exit(NULL);
345 }
346 
347 
348 void printSuccessAll(phylo p)
349 {
350  printf("## Number of runs in which the base of each lineage was in each space:\n (*= extant distrib)\n\n");
351  // printf("lin bor wsu ngu phi luz\n");
352  printf(" Space | ");
353  for (int k = 0; k < Spaces; k++) printf(" %3d ", k);
354  printf("\n");
355  printf(" ------------+--");
356  for (int k = 0; k < Spaces; k++) printf("-----");
357  printf("\n");
358 
359  for (int i = 0; i < Lineages; i++) {
360  printf(" Lineage %3d | ", i);
361  for (int k = 0; k < Spaces; k++) {
362  if (LineageExtant[i][Times-1][k])
363  printf(" %3d*", record[i][k]);
364  else printf(" %3d ", record[i][k]);
365  }
366  printf(" --> ");
367  if(p.taxon[i]) printf("%s", p.taxon[i]);
368  for(int l = 0; l < LineageDaughtersN[i]; l++)
369  printf("l%d ", LineageDaughters[i][l]);
370  printf("\n");
371  }
372  printf("\n");
373 }
374 
375 double pDispersal(double x) {
376  return Cfg.probDispA * powf( 10.0, -1.0 * Cfg.probDispB * x ) ;
377 }
378 
379 double pSurvival(double x) {
380  return Cfg.probSurvA * (log10f(( x * ( powf(10, Cfg.probSurvB) -1.0 )) +1.0 )
381  / Cfg.probSurvB );
382 }
383 
384