File: descendants.c

package info (click to toggle)
r-cran-phylobase 0.8.6-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,308 kB
  • sloc: cpp: 306; ansic: 247; xml: 135; lisp: 38; sh: 9; makefile: 5
file content (53 lines) | stat: -rw-r--r-- 1,615 bytes parent folder | download | duplicates (3)
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
/*
  descendants.c:
    Identify all descendants of each node in the input vector. Function
  inputs are derived from a phylo4 edge matrix, which *must* be in
  preorder order. The isDescendant output is an indicator matrix of
  which nodes (rows, corresponding to the decendant vector) are
  descendants of each input node (columns, corresponding to the nodes
  vector). It will contain 1 for each descendant of the node, *including
  itself*, and 0 for all other nodes.

  Jim Regetz (NCEAS)
*/

#include <R.h>
#include <Rinternals.h>

SEXP descendants_c(SEXP nod, SEXP anc, SEXP des) {

    int numEdges = length(anc);
    int numNodes = length(nod);

    int* nodes = INTEGER(nod);
    int* ancestor = INTEGER(anc);
    int* descendant = INTEGER(des);

    int child = 0;
    SEXP isDescendant;

    PROTECT(isDescendant = allocMatrix(INTSXP, numEdges, numNodes));
    for (int n=0; n<numNodes; n++) {
        for (int i=0; i<numEdges; i++) {
            if (nodes[n]==descendant[i]) {
                INTEGER(isDescendant)[i + n*numEdges] = 1;
            } else {
                INTEGER(isDescendant)[i + n*numEdges] = 0;
            }
        }
    }
    for (int n=0; n<numNodes; n++) {
        for (int i=0; i<numEdges; i++) {
            if (INTEGER(isDescendant)[i + n*numEdges]==1) {
                child = descendant[i];
                for (int j=i+1; j<numEdges; j++) {
                    if (ancestor[j]==child) {
                        INTEGER(isDescendant)[j + n*numEdges] = 1;
                    }
                }
            }
        }
    }
    UNPROTECT(1);
    return isDescendant;
}