示例#1
0
//' rcpp_neutral_hotspots_ntests
//'
//' Performs repeated neutral tests to yield average distributions of both
//' hotspot values and spatial autocorrelation statistics.
//'
//' @param nbs An \code{spdep} \code{nb} object listing all neighbours of each
//' point. 
//' @param wts Weighting factors for each neighbour; must have same length as
//' nbs. 
//' @param nbsi List of matrices as returned from \code{get_nbsi}. each element
//' of which contains the i-th nearest neighbour to each point.
//' @param alpha Strength of spatial autocorrelation
//' @param sd0 Standard deviation of truncated normal distribution used to model
//' environmental variation (with mean of 1)
//' @param nt Number of successive layers of temporal and spatial autocorrelation
//' used to generate final modelled values
//' @param ntests Number of tests used to obtain average values
//' @param ac_type Character string specifying type of aucorrelation
//' (\code{moran}, \code{geary}, or code{getis-ord}).
//'
//' @return A matrix of dimension (size, 2), with first column containing
//' sorted and re-scaled hotspot values, and second column containing sorted and
//' re-scaled spatial autocorrelation statistics.
//'
// [[Rcpp::export]]
Rcpp::NumericMatrix rcpp_neutral_hotspots_ntests (Rcpp::List nbs, 
        Rcpp::List wts, Rcpp::List nbsi, double alpha, double sd0, int niters,
        std::string ac_type, bool log_scale, int ntests)
{
    const int size = nbs.size ();

    Rcpp::NumericMatrix hs1;
    Rcpp::NumericVector z (size), z1 (size), ac (size), ac1 (size);
    std::fill (ac.begin (), ac.end (), 0.0);
    std::fill (z.begin (), z.end (), 0.0);

    for (int n=0; n<ntests; n++)
    {
        hs1 = rcpp_neutral_hotspots (nbs, wts, nbsi, alpha, sd0, log_scale,
                niters, ac_type);

        z += hs1 (Rcpp::_, 0);
        ac += hs1 (Rcpp::_, 1);
    }

    Rcpp::NumericMatrix result (size, 2);
    result (Rcpp::_, 0) = z / (double) ntests;
    result (Rcpp::_, 1) = ac / (double) ntests;
    Rcpp::colnames (result) = Rcpp::CharacterVector::create ("z", "ac");

    return result;
}
示例#2
0
/*
Adds a single cycle region to regs if cycle is valid.

*/
void addRegion2(vector<pair<Region*, bool> >& regs, vector<Point>& cycle){

  if(cycle.size()<4){ // at least 3 points
    cerr << "Cycle with less than 3 different points detected" << endl;
    return;
  }
  bool isFace = getDir(cycle);

  // create a DBArray of halfsegments representing this cycle
  DbArray<HalfSegment> segments1(0);
  
  for(unsigned int i=0;i<cycle.size()-1;i++){
    Point p1 = cycle[i];
    Point p2 = cycle[i+1];
    Point lp(0.0,0.0);
    Point rp(0.0,0.0);
    if(p1<p2){
       lp = p1;
       rp = p2;
    } else {
       lp = p2;
       rp = p1;
    }

    HalfSegment hs1(true,lp,rp);

    hs1.attr.edgeno = i;
    hs1.attr.faceno = 0;
    hs1.attr.cycleno =0;
    hs1.attr.coverageno = 0;
    hs1.attr.insideAbove = false;
    hs1.attr.partnerno = -1;

    HalfSegment hs2 = hs1;
    hs2.SetLeftDomPoint(false);

    segments1.Append(hs1);
    segments1.Append(hs2);
  }

  segments1.Sort(HalfSegmentCompare);

  // split the segments at crossings and overlappings
  DbArray<HalfSegment>* segments = Split(segments1);


  SetPartnerNo(*segments);


  bool used[segments->Size()];
  for(int i=0;i<segments->Size();i++){
    used[i] = false;
  }

  // try to find cycles

  vector< vector<Point> > cycles; // corrected (simple) cycles

  vector<Point> path;     // current path
  set<Point>  points;     // index for points in path
  bool subcycle;          // a multiple point within the path?
  for(int i=0; i< segments->Size(); i++){
    if(!used[i]){ // start of a new path found
      int pos = i;
      path.clear();
      points.clear();
      bool done = false;
      subcycle = false;
      while(!done){
        HalfSegment hs1;
        segments->Get(pos,hs1);
        Point dp = hs1.GetDomPoint();
        Point ndp = hs1.GetSecPoint();
        int partner = hs1.attr.partnerno;
        path.push_back(dp);
        points.insert(dp);
        used[pos] = true;
        used[partner] = true;
        if(points.find(ndp)!=points.end()){ // (sub) cycle found
          if(AlmostEqual(path[0],ndp)){ // cycle closed
             path.push_back(ndp);
             done = true;
          } else { // subcycle found
             subcycle = true;
          }
        }
        if(!done){
          // no cycle, try to extend
          int nb = getUnusedExtension(*segments,partner,used);
          if(nb>=0){ // extension found, continue
            pos = nb;
          } else { // dead end found, track back
            cout << " ----> DEAD END FOUND <--- " << endl;
            done = true; // should never occur
          }
        }
      }
      if(subcycle){
        separateCycles(path,cycles);
      } else if( (path.size()>3 ) && AlmostEqual(path[0],path[path.size()-1])){
        vector<Point> cycle = path;
        cycles.push_back(cycle);
      } else {
        cout << "remove invalid path of lengthh " << path.size() << endl;
      }
    }// new path found
  } // for
  delete segments;

  // build the region from the corrected cycles
  Region* result = 0;
  for(unsigned int i = 0; i< cycles.size();i++){
    vector<Point> cycle = cycles[i];
    bool cw = getDir(cycle);
    Region* reg = new Region(0);
    reg->StartBulkLoad();
    for(unsigned int j=0;j<cycle.size()-1;j++){
       Point lp,rp;
       bool smallb;
       smallb = (cycle[j] < cycle[j+1]);
       if(smallb){
         lp = cycle[j];
         rp = cycle[j+1];
       } else {
         lp = cycle[j+1];
         rp = cycle[j];
       }
       HalfSegment hs(true,lp,rp);
       hs.attr.edgeno = j;
       hs.attr.insideAbove = (cw && !smallb) || (!cw && smallb);
       hs.attr.faceno=0;
       hs.attr.cycleno = 0;
       hs.attr.coverageno = 0;
       HalfSegment hs2(hs);
       hs2.SetLeftDomPoint(false);
       *reg += hs;
       *reg += hs2;
    }
    reg->EndBulkLoad();

    if(!result){
      result = reg;
    } else {
      Region* tmp = SetOp(*result,*reg,avlseg::union_op);
      delete result;
      result = tmp;
      delete reg;
    }
  }
  if(result){
    regs.push_back(make_pair(result,isFace));
  }
}