std::list<MatrixCoord> dumbPath(Matrix<Cell> &matrix, const MatrixCoord &start, const MatrixCoord &end) { std::list<MatrixCoord> path; MatrixCoord matrixSize = matrix.size(); Matrix<Directions> directionsMatrix(matrixSize); Directions alldir(1,1,1,1); MatrixCoord currentDir = alldir.dir[rand()%4]; for (int i=0; i<matrixSize.x; ++i) { for (int j=0; j<matrixSize.y; ++j) { MatrixCoord ij(i, j); directionsMatrix[ij] = Directions(matrix[ij].up, matrix[ij].down, matrix[ij].right, matrix[ij].left); } } // directionsMatrix has, in each coord, the possible directionsMatrix from that coord path.clear(); MatrixCoord currentCoord = start; while (!(currentCoord == end)) { // at each arrived coord path.push_back(currentCoord); // add it as arrived(stuff here only gets added(never removed), it makes the full back-and-forth trace) std::random_shuffle(directionsMatrix[currentCoord].dir.begin(), directionsMatrix[currentCoord].dir.end()); // get a coord from this one currentCoord += directionsMatrix[currentCoord].dir.back(); } path.push_back(currentCoord); return path; }
// const TableOperation* ResultSet::getConstrainedTableOperation (const TableOperation* tableop) { // } const Operation* ResultSet::getConstrainedOperation (const Operation* op) const { /* The VarLister is a serializer which also records all variables. */ if (size() == 1 && (*results.begin())->size() == 0) return NULL; FilterInjector ij((POSFactory*)posFactory, *this); // this is const, but the factory isn't. op->express(&ij); return ij.last.operation; }
void outMatrix(double*A, int dim) { int i,j; for(i=0;i<dim;i++) { for(j=0;j<dim;j++) printf("%10g\t", *ij(A,i,j,dim)); printf("\n"); } }
int main(int argc, char *argv[]) { int rows = SIZE; int cols = SIZE; bool fullyrand = true; BenchTimer timer; Coordinates coords; Values values; if(fullyrand) { Coordinates pool; pool.reserve(cols*NBPERROW); std::cerr << "fill pool" << "\n"; for (int i=0; i<cols*NBPERROW; ) { // DynamicSparseMatrix<int> stencil(SIZE,SIZE); Vector2i ij(ei_random<int>(0,rows-1),ei_random<int>(0,cols-1)); // if(stencil.coeffRef(ij.x(), ij.y())==0) { // stencil.coeffRef(ij.x(), ij.y()) = 1; pool.push_back(ij); } ++i; } std::cerr << "pool ok" << "\n"; int n = cols*NBPERROW*KK; coords.reserve(n); values.reserve(n); for (int i=0; i<n; ++i) { int i = ei_random<int>(0,pool.size()); coords.push_back(pool[i]); values.push_back(ei_random<Scalar>()); } } else { for (int j=0; j<cols; ++j) for (int i=0; i<NBPERROW; ++i) { coords.push_back(Vector2i(ei_random<int>(0,rows-1),j)); values.push_back(ei_random<Scalar>()); } } std::cout << "nnz = " << coords.size() << "\n"; CHECK_MEM // dense matrices #ifdef DENSEMATRIX { BENCH(setrand_eigen_dense(coords,values);) std::cout << "Eigen Dense\t" << timer.value() << "\n"; }
double SparseMatrix::getElement(size_t i, size_t j) const { std::vector<size_t> ij(2); ij[0] = i; ij[1] = j; std::map< std::vector<size_t>, double >::const_iterator it = this->_elements.find(ij); if (it != this->_elements.end()) { // we found our value return it->second; } else { return 0.0; } }
Stmt lowerTranspose(Var target, const IndexExpr* iexpr, Environment* env, Storage* storage) { simit_iassert(isa<IndexedTensor>(iexpr->value)); simit_iassert(isa<VarExpr>(to<IndexedTensor>(iexpr->value)->tensor)); Var source = to<VarExpr>(to<IndexedTensor>(iexpr->value)->tensor)->var; auto sourceIndex = storage->getStorage(source).getTensorIndex(); auto targetIndex = storage->getStorage(target).getTensorIndex(); auto sourceType = source.getType().toTensor(); auto iRange = sourceType->getOuterDimensions()[0]; Var i("i", Int); Var ij("ij", Int); Var j("j", Int); Var locVar(INTERNAL_PREFIX("locVar"), Int); Stmt locStmt = CallStmt::make({locVar}, intrinsics::loc(), {Load::make(sourceIndex.getColidxArray(),ij), i, targetIndex.getRowptrArray(), targetIndex.getColidxArray()}); Stmt body; auto blockType = *sourceType->getBlockType().toTensor(); if (blockType.order() == 0) { // Not blocked body = Store::make(target, locVar, Load::make(source, ij)); } else { // Blocked simit_iassert(blockType.order() == 2); Var ii("ii", Int); Var jj("jj", Int); auto d1 = blockType.getOuterDimensions()[0]; auto d2 = blockType.getOuterDimensions()[1]; Expr l1 = Length::make(d1); Expr l2 = Length::make(d2); body = Store::make(target, locVar*l1*l2 + ii*l2 + jj, Load::make(source, ij*l1*l2 + ii*l2 + jj)); body = For::make(jj, ForDomain(d2), body); body = For::make(ii, ForDomain(d1), body); } simit_iassert(body.defined()); Expr start = Load::make(sourceIndex.getRowptrArray(), i); Expr stop = Load::make(sourceIndex.getRowptrArray(), i+1); Stmt innerLoop = ForRange::make(ij, start, stop, Block::make(locStmt, body)); return For::make(i, iRange, innerLoop); }
void orth_MGS(double *A, double *U, int n) { int i,j,k; double *tmp = (double*) malloc(n * sizeof(double)); double normui; int changeR; //outMatrix(A,n); for(i=0; i<n; i++) { //u(i,:) = A(i,:); for(j=0; j<n; j++) *ij(U,i,j,n) = *ij(A,i,j,n); // for j = 1:i-1 for (j=0; j<i; j++) { // u(i,:) = u(i,:) - proj(u(j,:), u(i,:)); proj(ij(U,j,0,n), ij(U,i,0,n), tmp, n); //outVector(tmp,n); for (k=0; k<n; k++) { *ij(U,i,k,n) -= tmp[k]; } } // u(i,:) = u(i,:) / mynorm(u(i,:)); normui = norm2(ij(U,i,0,n), n); for (k=0; k<n; k++) *ij(U,i,k,n) /= normui; } free(tmp); if (cec15_rand() > 0.5) { changeR = _myuniform(n); tmp = ij(U, changeR-1, 0, n); for (k=0; k<n; k++) tmp[k] *= 2.0; } }
nlist_t* gdgeoip2_make_list(const char* pathname, const char* map_name, dclists_t* dclists, const dcmap_t* dcmap, const bool city_auto_mode, const bool city_no_region) { dmn_assert(pathname); dmn_assert(map_name); dmn_assert(dclists); nlist_t* nl = NULL; geoip2_t* db = geoip2_new(pathname, map_name, dclists, dcmap, city_auto_mode, city_no_region); if(db) { if(!city_auto_mode && !dcmap) { log_warn("plugin_geoip: map %s: not processing GeoIP2 database '%s': no auto_dc_coords and no actual 'map', therefore nothing to do", map_name, pathname); } else { ij_func_t ij = &isolate_jmp; ij(db, &nl); } geoip2_destroy(db); } return nl; }
void Surf::LimitTargetMap() { int nmapu = m_SrcMap.size(); int nmapw = m_SrcMap[0].size(); int nmap = nmapu * nmapw; // Create size sortable index of array i,j coordinates vector< pair < double, pair < int, int > > > index; index.resize( nmap ); int k = 0; for( int i = 0; i < nmapu ; i++ ) { for( int j = 0; j < nmapw ; j++ ) { pair< int, int > ij( i, j ); pair < double, pair < int, int > > id( m_SrcMap[i][j].m_str, ij ); index[k] = id; k++; m_SrcMap[i][j].m_maxvisited = -1; // Reset traversal limiter. } } // Sort index std::sort( index.begin(), index.end(), indxcompare ); // Start from smallest for( int k = 0; k < nmap; k++ ) { pair< int, int > ij = index[k].second; int i = ij.first; int j = ij.second; MapSource src = m_SrcMap[i][j]; // Recursively limit from small to large (skip if dominated) if( !src.m_dominated ) { WalkMap( i, j, k, i, j ); } } }
std::list<MatrixCoord> randomDFSPath(Matrix<Cell> &matrix, const MatrixCoord &start, const MatrixCoord &end) { std::list<MatrixCoord> path; MatrixCoord matrixSize = matrix.size(); Matrix<Directions> directionsMatrix(matrixSize); for (int i=0; i<matrixSize.x; ++i) { for (int j=0; j<matrixSize.y; ++j) { MatrixCoord ij(i, j); directionsMatrix[ij] = Directions(matrix[ij].up, matrix[ij].down, matrix[ij].right, matrix[ij].left); } } // directionsMatrix has, in each coord, the possible directionsMatrix from that coord path.clear(); std::list<MatrixCoord> coordStack; MatrixCoord currentCoord = start; while (!(currentCoord == end)) { // at each arrived coord path.push_back(currentCoord); // add it as arrived(stuff here only gets added(never removed), it makes the full back-and-forth trace) // every coord I arrive must be added here if (directionsMatrix[currentCoord].dir.size() > 0) { std::random_shuffle(directionsMatrix[currentCoord].dir.begin(), directionsMatrix[currentCoord].dir.end()); // get a coord from this one MatrixCoord modifier = directionsMatrix[currentCoord].dir.back(); directionsMatrix[currentCoord].dir.pop_back(); // erase the pointer from currentCoord to currentCoord+modifier const MatrixCoord modified = currentCoord + modifier; // just an alias to the next coordinate I will visit directionsMatrix[modified].dir.erase(std::find(directionsMatrix[modified].dir.begin(), directionsMatrix[modified].dir.end(), -modifier)); // erase the pointer to the current currentCoord from(currentCoord+modifier) coordStack.push_back(currentCoord); // add it to the stack, so that if I get to a dead end, I can get back currentCoord = modified; } else { currentCoord = coordStack.back(); // dead end, just get back to last one coordStack.pop_back(); } // std::cout << path << std::endl; } path.push_back(currentCoord); return path; }
/*! \ingroup group_imgproc_contours Extract contours from a binary image. \param I_original : Input binary image (0 means background, 1 means foreground, other values are not allowed). \param contours : Detected contours. \param contourPts : List of contours, each contour contains a list of contour points. \param retrievalMode : Contour retrieval mode. */ void vp::findContours(const vpImage<unsigned char> &I_original, vpContour &contours, std::vector<std::vector<vpImagePoint> > &contourPts, const vpContourRetrievalType& retrievalMode) { if (I_original.getSize() == 0) { return; } //Clear output results contourPts.clear(); vpImage<int> I(I_original.getHeight(), I_original.getWidth()); for (unsigned int cpt = 0; cpt < I_original.getSize(); cpt++) { I.bitmap[cpt] = I_original.bitmap[cpt]; } int nbd = 1; //Newest border int lnbd = 1; //Last newest border //Background contour //By default the root contour is a hole contour vpContour *root = new vpContour(vp::CONTOUR_HOLE); std::map<int, vpContour*> borderMap; borderMap[lnbd] = root; for (unsigned int i = 0; i < I.getHeight(); i++) { lnbd = 1; //Reset LNBD at the beginning of each scan row for (unsigned int j = 0; j < I.getWidth(); j++) { int fji = I[i][j]; bool isOuter = isOuterBorderStart(I, i, j); bool isHole = isHoleBorderStart(I, i, j); if (isOuter || isHole) { //else (1) (c) vpContour *border = new vpContour; vpContour *borderPrime = NULL; vpImagePoint from(i, j); if (isOuter) { //(1) (a) nbd++; from.set_j(from.get_j() - 1); border->m_contourType = vp::CONTOUR_OUTER; borderPrime = borderMap[lnbd]; //Table 1 switch (borderPrime->m_contourType) { case vp::CONTOUR_OUTER: border->setParent(borderPrime->m_parent); break; case vp::CONTOUR_HOLE: border->setParent(borderPrime); break; default: break; } } else { //(1) (b) nbd++; if (fji > 1) { lnbd = fji; } borderPrime = borderMap[lnbd]; from.set_j(from.get_j() + 1); border->m_contourType = vp::CONTOUR_HOLE; //Table 1 switch (borderPrime->m_contourType) { case vp::CONTOUR_OUTER: border->setParent(borderPrime); break; case vp::CONTOUR_HOLE: border->setParent(borderPrime->m_parent); break; default: break; } } vpImagePoint ij(i, j); followBorder(I, ij, from, border, nbd); //(3) (1) ; single pixel contour if (border->m_points.empty()) { border->m_points.push_back(ij); I[i][j] = -nbd; } //Compute contour polygon border->m_contourPolygon.buildFrom(border->m_points); if (retrievalMode == CONTOUR_RETR_LIST || retrievalMode == CONTOUR_RETR_TREE) { //Add contour points contourPts.push_back(border->m_points); } borderMap[nbd] = border; } //(4) if (fji != 0 && fji != 1) { lnbd = std::abs(fji); } } } if (retrievalMode == CONTOUR_RETR_EXTERNAL || retrievalMode == CONTOUR_RETR_LIST) { //Delete contours content contours.m_parent = NULL; for (std::vector<vpContour *>::iterator it = contours.m_children.begin(); it != contours.m_children.end(); ++it) { (*it)->m_parent = NULL; if (*it != NULL) { delete *it; *it = NULL; } } contours.m_children.clear(); } if (retrievalMode == CONTOUR_RETR_EXTERNAL) { //Add only external contours for (std::vector<vpContour*>::const_iterator it = root->m_children.begin(); it != root->m_children.end(); ++it) { contours.m_children.push_back(new vpContour(**it)); contourPts.push_back((*it)->m_points); } } else if (retrievalMode == CONTOUR_RETR_LIST) { getContoursList(*root, 0, contours); //Set parent to root for (std::vector<vpContour*>::iterator it = contours.m_children.begin(); it != contours.m_children.end(); ++it) { (*it)->m_parent = &contours; } } else { //CONTOUR_RETR_TREE contours = *root; } delete root; root = NULL; }
// The gateway mex routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Check for proper number of input and output arguments */ if ((nlhs != 1) || (nrhs != 2)) mexErrMsgTxt("Usage: B = BIADJANCENCY_MATRIX(A,M) OR " "B = BIADJANCENCY_MATRIX(A,M,K).\n"); /* Read input */ double *A = mxGetPr(prhs[0]); // assignment image int X = mxGetM(prhs[0]); // image size X int Y = mxGetN(prhs[0]); // image size Y int M = (int)mxGetPr(prhs[1])[0]; // patch size int K; // number dict patches if (nrhs==3) K = (int)mxGetPr(prhs[2])[0]; else{ // assumes number of dict patches is max(A) K = 0; for (int a=0; a<X*Y; a++) if (A[a]>K) K = A[a]; } /* Compute some useful sizes */ int c = (M-1)/2; // width of boundary having no assignment int n = X*Y; // number of image pixels int m = M*M*K; // number of dict pixels int s = (X-M+1)*(Y-M+1)*M*M; // number image-dict links (elements in B) /* Finding elements of B as row-column indices */ std::vector<ij> bij; bij.reserve(s); int ic,i,j; for (int y=0+c; y<Y-c; y++){ // visiting patches centered around pixels for (int x=0+c; x<X-c; x++){ ic = x+y*X; // central patch pixel for (int dy=-c; dy<=c; dy++){ // visiting pixels around central for (int dx=-c; dx<=c; dx++){ i = (x+dx)+(y+dy)*X; j = (c+dx)+(c+dy)*M+(A[ic]-1)*M*M; bij.push_back(ij(i,j)); } } } } /* Sorting elements in bij columnwise */ std::sort (bij.begin(), bij.end()); /* Placeholder for output */ plhs[0] = mxCreateSparseLogicalMatrix(n,m,s); // output mxArray, sparse logical matrix B if (plhs[0]==NULL) mexErrMsgTxt("Could not allocate enough memory!\n"); /* Access fields of output mxArray via pointers */ mwIndex *ir = mxGetIr(plhs[0]); // row index (0 indexed) mwIndex *jc = mxGetJc(plhs[0]); // cumulative number of elements per column mxLogical *pr = mxGetLogicals(plhs[0]); // element values (will be all true) /* Converting row-column indices into row-cumulative column */ int k = 0; // for visiting elements of bij jc[0] = 0; // first element of cumulative sum is 0 for (int bc=0; bc<m; bc++){ // all columns of B jc[bc+1] = jc[bc]; while (k<bij.size() && bij[k].j==bc){ jc[bc+1]++; ir[k] = bij[k].i; pr[k] = true; k++; } } }
SEXP map_assemble_polygons(SEXP lon, SEXP lat, SEXP z) { PROTECT(lon = AS_NUMERIC(lon)); double *lonp = REAL(lon); PROTECT(lat = AS_NUMERIC(lat)); double *latp = REAL(lat); PROTECT(z = AS_NUMERIC(z)); double *zp = REAL(z); int nlat = length(lat); int nlon = length(lon); if (nlon < 1) error("must have at least 2 longitudes"); if (nlat < 1) error("must have at least 2 latitudes"); // Note that first dimension of z is for y (here, lat) and second for x (here, lon) int nrow = INTEGER(GET_DIM(z))[0]; int ncol = INTEGER(GET_DIM(z))[1]; if (nlat != ncol) error("mismatch; length(lat)=%d must equal nrow(z)=%d", nlat, ncol); if (nlon != nrow) error("mismatch; length(lon)=%d must equal ncol(z)=%d", nlon, nrow); int n = nlon * nlat; SEXP polylon, polylat, polyz; PROTECT(polylon = allocVector(REALSXP, 5*n)); PROTECT(polylat = allocVector(REALSXP, 5*n)); PROTECT(polyz = allocMatrix(REALSXP, nlon, nlat)); double *polylonp = REAL(polylon), *polylatp = REAL(polylat), *polyzp = REAL(polyz); double latstep = 0.5 * fabs(latp[1] - latp[0]); double lonstep = 0.5 * fabs(lonp[1] - lonp[0]); #ifdef DEBUG Rprintf("nlon: %d, nlat: %d, latstep: %f, lonstep: %f\n", nlon, nlat, latstep, lonstep); #endif int k = 0, l=0; // indices for points and polygons for (int j = 0; j < ncol; j++) { for (int i = 0; i < nrow; i++) { #ifdef DEBUG if (j == 0 && i < 3) Rprintf("i: %d, j: %d, lon: %.4f, lat:%.4f, k: %d\n", i, j, lonp[i], latp[j], k); #endif // Lower left polylonp[k] = lonp[i] - lonstep; polylatp[k++] = latp[j] - latstep; // Upper left polylonp[k] = lonp[i] - lonstep; polylatp[k++] = latp[j] + latstep; // Upper right polylonp[k] = lonp[i] + lonstep; polylatp[k++] = latp[j] + latstep; // Lower right polylonp[k] = lonp[i] + lonstep; polylatp[k++] = latp[j] - latstep; // end polylonp[k] = NA_REAL; polylatp[k++] = NA_REAL; polyzp[l++] = zp[ij(i, j)]; #ifdef DEBUG if (j == 0 && i < 3) for (int kk=k-5; kk<k-1; kk++) Rprintf("k: %d, lon: %.4f, lat:%.4f\n", kk, polylonp[kk], polylatp[kk]); #endif } if (k > 5 * n) error("coding error (assigned insufficient memory); k: %d, 5*n: %d", k, 5*n); } if (k != 5 * n) error("coding error (assigned surplus memory); k: %d, 5*n: %d", k, 5*n); SEXP res; SEXP res_names; PROTECT(res = allocVector(VECSXP, 3)); PROTECT(res_names = allocVector(STRSXP, 3)); SET_VECTOR_ELT(res, 0, polylon); SET_STRING_ELT(res_names, 0, mkChar("longitude")); SET_VECTOR_ELT(res, 1, polylat); SET_STRING_ELT(res_names, 1, mkChar("latitude")); SET_VECTOR_ELT(res, 2, polyz); SET_STRING_ELT(res_names, 2, mkChar("z")); setAttrib(res, R_NamesSymbol, res_names); UNPROTECT(8); return(res); }
void SparseMatrix::setElement(size_t i, size_t j, double value){ std::vector<size_t> ij(2); ij[0] = i; ij[1] = j; this->_elements[ij] = value; }
void PIV::xxcorr(const std::vector<double>& mat0, const std::vector<double>& mat1, const int wNx, const int wNy, int nRows, int nCols, std::vector<double>& xdisps, std::vector<double>& ydisps, std::vector<double>& xcorrvals) { int n = static_cast<int>(mat0.size()); xdisps.resize(n); ydisps.resize(n); xcorrvals.resize(n); // UGLY PARAMETER TODO double lim = 5.0; double xdisp = 0.0; double ydisp = 0.0; double xcorrval = 0.0; for (int i=0; i<nRows; ++i) { int imin = ((i-wNy < 0)? 0:i-wNy); int imax = ((i+wNy >= nRows)? nRows-1:i+wNy); for (int j=0; j<nCols; ++j) { int jmin = ((j-wNx < 0)? 0:j-wNx); int jmax = ((j+wNx >= nCols)? nCols-1:j+wNx); int nnCols = jmax-jmin+1; int nnRows = imax-imin+1; //std::vector<double> txdisps(nnCols*nnRows, 0.0); //std::vector<double> tydisps(nnCols*nnRows, 0.0); //std::vector<double> txcorrvals(nnCols*nnRows, 0.0); xdisp = 0.0; ydisp = 0.0; xcorrval = 0.0; double maxxcorrval = 1.0e10; for (int ii=imin; ii<=imax; ++ii) { for (int jj=jmin; jj<=jmax; ++jj) { //if (abs(mat1[ij(ii,jj,nRows, nCols)]) < lim) continue; //xcorrval = intpow<1>(mat0[ij(i,j,nRows,nCols)])* //intpow<1>(mat1[ij(ii, jj, nRows, nCols)]); xcorrval = std::abs(intpow<1>(mat0[ij(i,j,nRows,nCols)]) - intpow<1>(mat1[ij(ii,jj,nRows,nCols)])); if (xcorrval < maxxcorrval) { maxxcorrval = xcorrval; xdisp = jj; ydisp = ii; } } } xdisps[ij(i,j,nRows,nCols)] = j-xdisp; ydisps[ij(i,j,nRows,nCols)] = i-ydisp; xcorrvals[ij(i,j,nRows,nCols)] = maxxcorrval; } } }
SEXP matrix_smooth(SEXP mat) { #define ij(i, j) ((i) + (ni) * (j)) /* Note: the 2d data are stored in column order */ SEXP res; int ni = INTEGER(GET_DIM(mat))[0]; int nj = INTEGER(GET_DIM(mat))[1]; int i, j; double *matp, *resp; if (!isMatrix(mat)) error("'mat' must be a matrix"); if (!isReal(mat)) error("'mat' must be numeric, not integer"); matp = REAL(mat); if (length(mat) != ni * nj) error("'ni'*'nj' must equal number of elements in 'mat'"); PROTECT(res = allocMatrix(REALSXP, ni, nj)); resp = REAL(res); for (i = 0; i < ni*nj; i++) resp[i] = 99.99; // copy edges (FIXME: coiuld use 1D smoother here) for (j = 0; j < nj; j++) { resp[ij(0, j)] = matp[ij(0, j)]; resp[ij(ni-1, j)] = matp[ij(ni-1, j)]; } for (i = 0; i < ni; i++) { resp[ij(i, 0)] = matp[ij(i, 0)]; resp[ij(i, nj-1)] = matp[ij(i, nj-1)]; } // smooth middle for (i = 1; i < ni - 1; i++) for (j = 1; j < nj - 1; j++) resp[ij(i, j)] = (2.0*matp[ij(i, j)] + matp[ij(i-1, j)] + matp[ij(i+1, j)] + matp[ij(i, j-1)] + matp[ij(i, j+1)]) / 6.0; UNPROTECT(1); return(res); #undef ix }
SEXP boxcar_average_2d(SEXP x1, SEXP x2, SEXP y, SEXP x1out, SEXP x2out) { // array lookup #define ij(i, j) ((i) + (nx1out) * (j)) PROTECT(x1 = AS_NUMERIC(x1)); PROTECT(x2 = AS_NUMERIC(x2)); PROTECT(y = AS_NUMERIC(y)); PROTECT(x1out = AS_NUMERIC(x1out)); PROTECT(x2out = AS_NUMERIC(x2out)); double *x1p = REAL(x1); double *x2p = REAL(x2); double *yp = REAL(y); double *x1outp = REAL(x1out); double *x2outp = REAL(x2out); int nx1out = LENGTH(x1out); int nx2out = LENGTH(x2out); #ifdef DEBUG Rprintf("output array will have dimension %d x %d\n", nx1out, nx2out); #endif SEXP avg; // first holds sum, then (divided by count), the average PROTECT(avg = allocMatrix(REALSXP, nx1out, nx2out)); double *avgp = REAL(avg); SEXP count; PROTECT(count = allocMatrix(REALSXP, nx1out, nx2out)); double *countp = REAL(count); for (int ij = 0; ij < nx1out * nx2out; ij++) { avgp[ij] = 0.0; countp[ij] = 0.0; } // FIXME: what if dg < 0 or dg == 0? (check in R code) double x1outMin = x1outp[0]; double x2outMin = x2outp[0]; double x1outInc = x1outp[1] - x1outp[0]; double x2outInc = x2outp[1] - x2outp[0]; int nx = LENGTH(x1); #ifdef DEBUG Rprintf("nx=%d (should be 31)\n", nx); #endif for (int i=0; i < nx; i++) { // FIXME: assuming regular grid int which1 = (int)floor(0.5 + (x1p[i] - x1outMin) / x1outInc); int which2 = (int)floor(0.5 + (x2p[i] - x2outMin) / x2outInc); #ifdef DEBUG Rprintf("x[%d]=%f y[%d]=%f -> [%d, %d]\n", i, x1p[i], i, x2p[i], which1, which2); #endif if (0 <= which1 && which1 < nx1out && 0 <= which2 && which2 < nx2out) { avgp[ij(which1, which2)] += yp[i]; countp[ij(which1, which2)] += 1.0; } } for (int i=0; i < nx1out; i++) { for (int j=0; j < nx2out; j++) { if (countp[ij(i, j)] > 0.0) { avgp[ij(i, j)] /= countp[ij(i, j)]; } else { avgp[ij(i, j)] = NA_REAL; } } } // create return value, a list SEXP res; SEXP res_names; PROTECT(res = allocVector(VECSXP, 3)); PROTECT(res_names = allocVector(STRSXP, 3)); SET_VECTOR_ELT(res, 0, avg); SET_STRING_ELT(res_names, 0, mkChar("average")); SET_VECTOR_ELT(res, 1, x1out); SET_STRING_ELT(res_names, 1, mkChar("x1out")); SET_VECTOR_ELT(res, 2, x2out); SET_STRING_ELT(res_names, 2, mkChar("x2out")); setAttrib(res, R_NamesSymbol, res_names); UNPROTECT(9); #undef ij return(res); }