//' 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; }
/* 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)); } }