SEXP graph_bitarray_getEdgeAttrOrder(SEXP _bits, SEXP _from, SEXP _to) { unsigned char *bits = (unsigned char*) RAW(_bits); int ns = asInteger(getAttrib(_bits, install("nbitset"))); int len = length(_from); int *from = INTEGER(_from); int *to = INTEGER(_to); int dim = NROW(_bits); int byteIndex, bitIndex, shft, indx, intIndx, i, j; int oindx=0, nindx=0, attrIndx=0, setCount=0; SEXP origRightPos, origLeftPos, newRightPos, newLeftPos, res, namesres; PROTECT(origRightPos = allocVector(INTSXP, ns)); //index into orig attr PROTECT(origLeftPos = allocVector(INTSXP, ns)); PROTECT(newRightPos = allocVector(INTSXP, len)); PROTECT(newLeftPos = allocVector(INTSXP, len)); setCount =1; for(j =0; j < dim ; j ++) { for(i =0; i < dim; i++){ indx = COORD_TO_INDEX(i, j , dim); byteIndex = indx / 8; bitIndex = indx % 8; shft = 1 << bitIndex; intIndx = COORD_TO_INDEX(from[attrIndx]-1, to[attrIndx]-1, dim); if(bits[byteIndex] & (shft) ) { INTEGER(origRightPos)[oindx] = oindx + 1 ; INTEGER(origLeftPos)[oindx] = setCount ; oindx++; if(intIndx != indx){ setCount++; } } if(intIndx == indx) { INTEGER(newRightPos)[nindx] = nindx + 1; INTEGER(newLeftPos)[nindx] = setCount ; nindx++; if(attrIndx < len-1){ attrIndx++; } setCount++; } } } SET_LENGTH(newRightPos, nindx); SET_LENGTH(newLeftPos, nindx); PROTECT(res = allocVector(VECSXP, 4)); SET_VECTOR_ELT(res, 0, newLeftPos); SET_VECTOR_ELT(res, 1, newRightPos); SET_VECTOR_ELT(res, 2, origLeftPos); SET_VECTOR_ELT(res, 3, origRightPos); PROTECT(namesres = allocVector(STRSXP, 4)); SET_STRING_ELT(namesres, 0, mkChar("newLeftPos")); SET_STRING_ELT(namesres, 1, mkChar("newRightPos")); SET_STRING_ELT(namesres, 2, mkChar("origLeftPos")); SET_STRING_ELT(namesres, 3, mkChar("origRightPos")); setAttrib(res, R_NamesSymbol, namesres); UNPROTECT(6); return(res); }
/* Given a bit vector representing directed edges, return a new bit vector with the underlying undirected edges. */ SEXP graph_bitarray_undirect(SEXP bits) { int i, j, c = 0, len = length(bits), nrow = NROW(bits); SEXP tbits = PROTECT(graph_bitarray_transpose(bits)), ans = PROTECT(duplicate(bits)); unsigned char *bytes = RAW(bits), *tbytes = RAW(tbits), *abytes = RAW(ans); for (i = 0; i < len; i++) { unsigned char v; if (0 != (abytes[i] = bytes[i] | tbytes[i])) { /* keep track of edge count */ for (v = abytes[i]; v; c++) { v &= v - 1; /* clear the least significant bit set */ } } } /* zero out lower tri */ for (i = 0; i < nrow; i++) { for (j = 0; j < nrow; j++) { if (i > j) { unsigned char v; int idx = COORD_TO_INDEX(i, j, nrow); v = abytes[idx / 8]; if (0 != v) { if (IS_SET(abytes, idx / 8, idx % 8)) c--; abytes[idx / 8] &= ~(1 << (idx % 8)); } } } } INTEGER(getAttrib(ans, install("nbitset")))[0] = c; UNPROTECT(2); return ans; }
void fbSetPixelXY(struct fbconfig* fb, unsigned x, unsigned y, unsigned color) { unsigned width = fb->width; if(fb->landscape) { unsigned tmp = x; width = fb->height; x = fb->height-1 - y; y = tmp; } fbSetPixel(fb, COORD_TO_INDEX(x,y, width), color); }
static inline void astar_schedule_neighbor(struct astar_node *node, struct astar_search_info *info) { struct astar_node *ptr; int location; /* 'cost' is an attribute of the path leading to this node. When we * find two paths leading to the same node, cost helps us decide which * path to take. */ int cost = 0; /* 'goodness' is an attribute both of a node and of the path leading to * that node. It is important because it allows us to prioritize nodes, * so we can search the more promising nodes first. */ int goodness = 0; info->heuristic(info, &goodness, &cost, node->x, node->y); /* Cost is cumulative along a path, so add the parent node's cost. */ cost += node->cost; /* Nodes with cheaper paths leading to them are better than nodes with * costlier paths. */ goodness -= cost; location = COORD_TO_INDEX(info->x0, info->y0, info->width); /* Check if we already have a route to this location. */ if ((ptr = astar_old_route(location))) { /* If the old route is better than skip this neighbor. */ if (goodness <= ptr->goodness) return; /* If the new route is better than replace the old with the new * and reschedule. */ astar_replace_route(ptr, info->x0, info->y0, cost, goodness, node, location); return; } /* This is a new route. */ ptr = astar_node_create(info->x0, info->y0, cost, goodness, node, location); if (!ptr) { err("Allocation failed"); return; } if (astar_schedule(ptr)) { err("Schedule failed!"); exit(-1); } }
SEXP graph_bitarray_transpose(SEXP bits) { SEXP ans; int nrow, i, j, len = length(bits); unsigned char *bytes = RAW(bits), *ans_bytes; ans = PROTECT(duplicate(bits)); /* dup to capture attributes */ ans_bytes = RAW(ans); memset(ans_bytes, 0, len); nrow = NROW(bits); /* FIXME: use a single loop, look at R's array.c */ for (i = 0; i < nrow; i++) { for (j = 0; j < nrow; j++) { int idx = COORD_TO_INDEX(i, j, nrow), tidx = COORD_TO_INDEX(j, i, nrow); int byteIndex = idx / 8, bitIndex = idx % 8, tBitIndex = tidx % 8; if (IS_SET(bytes, byteIndex, bitIndex)) ans_bytes[tidx / 8] |= (1 << tBitIndex); } } UNPROTECT(1); return ans; }
SEXP graph_bitarray_getBitCell(SEXP bits, SEXP _from, SEXP _to) { int len = length(_to); SEXP ans; PROTECT(ans = allocVector(LGLSXP, len)); unsigned char *bytes = (unsigned char *) RAW(bits); int *from = INTEGER(_from); int *to = INTEGER(_to); int dim = NROW(bits); int i = 0, val, byteIndex, bitIndex, indx; for(i =0; i < len; i++) { indx = COORD_TO_INDEX(from[i]-1, to[i]-1, dim) ; byteIndex = indx / 8 ; bitIndex = indx % 8 ; val = bytes[byteIndex] & (1 << bitIndex); LOGICAL(ans)[i] = 0; if (val) { LOGICAL(ans)[i] = 1; } } UNPROTECT(1); return(ans); }
struct astar_node *astar_search(struct astar_search_info *info) { struct astar_node *node; int row; int col; int cost = 0; int goodness = 0; astar_search_init(); info->heuristic(info, &goodness, &cost, info->x0, info->y0); node = astar_node_create(info->x0, info->y0, cost, goodness, NULL, COORD_TO_INDEX(info->x0, info->y0, info->width)); astar_schedule(node); while (!heap_empty(schedule)) { //astar_dump_schedule(); node = astar_schedule_extract(); /* Check if this node is the target location */ if ((info->flags & ASTAR_HORZ || node->x == info->x1) && (info->flags & ASTAR_VERT || node->y == info->y1)) { /* Reverse the path to get a pointer to the start */ node = astar_path_reverse(node); /* Remove the nodes in the path from the tree so that * we don't free them with the rest */ astar_explored_remove(node); goto done; } /* Check if this node is at max depth */ if (node->depth == MAX_DEPTH || (info->limit_depth && node->depth == info->max_depth)) { continue; } /* Check the four non-diagonal neighbors of this node */ for (row = 0, info->y0 = node->y - 1; row < 3; row++, info->y0++) { /* Wrap y-coord if applicable */ if (info->wraps) info->y0 = ((info->y0 + info->height) % info->height); for (col = 0, info->x0 = node->x - 1; col < 3; col++, info->x0++) { #if (CONFIG_NEIGHBORS==4) /* skip diagonals and center */ if (((row * 3 + col) % 2) == 0) { continue; } #elif (CONFIG_NEIGHBORS==8) /* skip center */ if ((row == col) && (row == 1)) { continue; } #else # error CONFIG_NEIGHBORS undefined or has bad value #endif /* Wrap x-coord if applicable */ if (info->wraps) info->x0 = ((info->x0 + info->width) % info->width); /* Skip this neighbor if it's not a valid * location (impassable, off-map, etc) */ if (!info->is_valid_location(info->context, node->x, node->y, info->x0, info->y0)) continue; astar_schedule_neighbor(node, info); } } } node = 0; done: astar_cleanup(); return node; }