/* Load a program into the vm and initialize its state. */ void load(struct _context* ctx, avm* vm, assembly* p ) { int i; symbol* s; if (!p) return; vm->ctx = ctx; vm->instructions = p->instructions; vm->numins = p->nextslot; vm->pc = p->entry; for (i=0; i<NUM_REGS; i++) seti(&vm->regs[i], 0); if ((vm->hs=(stack*)calloc(1, sizeof(stack))) == 0) { setvmerror(vm, ZEN_VM_OUT_OF_MEMORY); return; } vm->hs->size = p->stacksize; vm->hs->sbody = (word*)calloc(vm->hs->size, sizeof(word)); vm->hs->fp = vm->hs->sp = 0; vm->cs = vm->hs; vm->lasterror = ZEN_NO_ERROR; initheap(vm, &vm->hp); s = lookupall(0, ctx, GLOBAL_NAME); vm->globalsize = s->localsize+s->tempsize; vm->regs[rs].entity.ival += vm->globalsize; vm->tot.size = ZEN_INITIALTOTSIZE; if (!(vm->tot.table = calloc(vm->tot.size, sizeof(pair)))) { setvmerror(vm, ZEN_VM_OUT_OF_MEMORY); return; } vm->loaded = 1; }
void tablelength(avm* vm) { word *w = getarg(vm, 0), w1; ctable* table = (ctable*)getdata(vm->hp.heap, ind2off(w->entity.ival)); seti(&w1, table->nextslot); returnv(vm, &w1); }
/* Open a dynamic linking library. */ void wdlopen(avm* vm) { word w; char* lib = getstring(vm, 0); HMODULE mod = LoadLibrary((LPCTSTR)lib); if (!mod) setvmerror(vm, ZEN_VM_CANNOT_LOAD_LIB); seti(&w, (int)mod); returnv(vm, &w); }
/* Open a dynamic library. */ void ldlopen(avm* vm) { word w; char* lib = getstring(vm, 0); void* handle = dlopen(lib, RTLD_LAZY); if (!handle) setvmerror(vm, ZEN_VM_CANNOT_LOAD_LIB); seti(&w, (int)handle); returnv(vm, &w); }
int main() { //allocate memory for registers and program data byte reg[16]; byte mem[4096]; //unsigned int offset = (unsigned int)mem - 0x200; word I = 0x200; int i; printf("Initialize registers\n"); seti(reg+0x0,0); seti(reg+0x1,2); seti(reg+0x2,3); seti(reg+0x3,255); printregs(stdout,reg); shl(reg+0x3,reg+0xF); printf("Shift V3 left,V3 = 254,VF = 1\n"); printregs(stdout,reg); shl(reg+0x1,reg+0xF); printf("Shift V1 left,V1 = 4,VF = 0\n"); printregs(stdout,reg); shr(reg+0x1,reg+0xF); printf("Shift V1 right,V1 = 2,VF = 0\n"); printregs(stdout,reg); seti(reg+0x4,255); seti(reg+0x5,7); and(reg+0x4,reg+0x5); printf("V4 = 255,V5 = 7, V4 = V4 & V5 -> 7\n"); printregs(stdout,reg); seti(reg+0x6,15); seti(reg+0x7,240); or(reg+0x6,reg+0x7); printf("V6 = 15, V7 = 240,V6 = V6 | V7 -> 255\n"); printregs(stdout,reg); seti(reg+0x8,0xF0); seti(reg+0x9,0x0F); xor(reg+0x8,reg+0x9); printf("V8 = 0xF0,V9 = 0x0F, V8 = V8 ^ V9 -> FF\n"); printregs(stdout,reg); return 0; }
void string_getrect(avm *vm) { word w; long off = newtable(vm, ZEN_INITIALTABLESIZE); long tindex = TOTinsert(vm, off); ctable* tbl = (ctable*)getdata(vm->hp.heap, off); word index, source; sfFloatRect col = sfString_GetRect(getstring(vm, 0)); sets(&index, newstring(vm, "Left")); seti(&source, col.Left); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "Top")); seti(&source, col.Top); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "Right")); seti(&source, col.Right); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "Bottom")); seti(&source, col.Bottom); IA(vm, tbl, tindex, &index, &source); sett(&w, tindex); returnv(vm, &w); }
void Shape_GetPointOutlineColor(avm *vm) { word w; long off = newtable(vm, ZEN_INITIALTABLESIZE); long tindex = TOTinsert(vm, off); ctable* tbl = (ctable*)getdata(vm->hp.heap, off); word index, source; sfColor col = sfShape_GetPointOutlineColor(getint(vm, 0), getint(vm, 1)); sets(&index, newstring(vm, "R")); seti(&source, col.r); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "G")); seti(&source, col.g); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "B")); seti(&source, col.b); IA(vm, tbl, tindex, &index, &source); sets(&index, newstring(vm, "A")); seti(&source, col.a); IA(vm, tbl, tindex, &index, &source); sett(&w, tindex); returnv(vm, &w); }
void Shape_CreateCircle(avm *vm) { word wr; sfColor Col; Col.r = getint(vm, 3); Col.g = getint(vm, 4); Col.b = getint(vm, 5); Col.a = getint(vm, 6); sfColor OutlineCol; OutlineCol.r = getint(vm, 8); OutlineCol.g = getint(vm, 9); OutlineCol.b = getint(vm, 10); OutlineCol.a = getint(vm, 11); seti(&wr, sfShape_CreateCircle(getfloat(vm, 0), getfloat(vm, 1), getfloat(vm, 2), Col, getfloat(vm, 7), OutlineCol)); returnv(vm, &wr); }
void Shape_GetBlendMode(avm *vm) { sfBlendMode mode = sfShape_GetBlendMode(getint(vm, 0)); int x; if(mode == sfBlendAlpha) x = 0; else if(mode == sfBlendAdd) x = 1; else if(mode == sfBlendMultiply) x = 2; else x = 3; word w; seti(&w, x); returnv(vm, &w); }
int main() { //allocate memory for registers and program data byte reg[16]; byte mem[4096]; //unsigned int offset = (unsigned int)mem - 0x200; word I = 0x200; int i; //printf("Hello World!\n"); //printf("Char size: %u\n",CHAR_BIT); //printf("Char min: %u\n",CHAR_MIN); //printf("Char max: %u\n",UCHAR_MAX); //printf("mem start: %p\n",mem); //printf("mem + 1: %p\n",mem+1); //fill registers to make the string "Hello World", //print it with printf, save it to memory, then //load it again seti(reg+0x0,0x48); seti(reg+0x1,0x65); seti(reg+0x2,0x6C); seti(reg+0x3,0x6C); seti(reg+0x4,0x6F); seti(reg+0x5,0x20); seti(reg+0x6,0x57); seti(reg+0x7,0x6F); seti(reg+0x8,0x72); seti(reg+0x9,0x6C); seti(reg+0xA,0x64); seti(reg+0xB,0x0); //print string printf("%s\n",reg); printf("Register contents after setting\n"); printregs(stdout,reg); printf("Memory contents before doing anythong\n"); printmem(stdout,mem,0x200,0x20F); //printf("Store register contents in memory"); stor(reg,0xB,mem,&I); //printmem(stdout,mem,0x200,0x20F); //zero all the registers memset(reg,0,REG_COUNT); printf("Memory after saving\n"); printmem(stdout,mem,0x200,0x20F); printf("Read memory as a string, line below should read \"Hello World\"\n"); printf("%s\n",mem+0x200); printf("Registers should all be 0\n"); printregs(stdout,reg); printf("Registers should now hold just the 2nd word\n"); I = 0x206; load(reg,0x5,mem,&I); //should load "World" printregs(stdout,reg); printf("%s\n",reg); //test the other opcodes printf("Clear registers\n"); memset(reg,0,REG_COUNT); printregs(stdout,reg); seti(reg+0x0,0x1); printf("set V0 to 1\n"); printregs(stdout,reg); set(reg+0x1,reg+0x0); printf("Set V1 to V0 (1)\n"); printregs(stdout,reg); addi(reg+0x0,0x2); printf("Added 2 to V0,should now be 3\n"); printregs(stdout,reg); add(reg+0x0,reg+0x1,reg+0xF); printf("Add V0 and V1, store answer in V0\n"); printregs(stdout,reg); addi(reg+0x2,0xFF); add(reg+0x0,reg+0x2,reg+0xF); printf("Testing carry flag, add 255 to V2 and add V2 to V0 (sets CF)\n"); printregs(stdout,reg); subyx(reg+0x0,reg+0x2,reg+0xF); printf("V0 - V2, V0 should be 0xFC, VF = 0\n"); printregs(stdout,reg); subxy(reg+0x1,reg+0x2,reg+0xF); printf("V2 (0xFF) - V1 (0x1) -> V1 (0xFE),VF = 1\n"); printregs(stdout,reg); }
void Shape_GetNbPoints(avm *vm) { word w; seti(&w, sfShape_GetNbPoints(getint(vm, 0))); returnv(vm, &w); }
void Shape_Create(avm *vm) { word wr; seti(&wr, sfShape_Create()); returnv(vm, &wr); }
int step(context* ctx, avm* vm) { int m, iop1, iop2, iopdest, i, res = ZEN_NO_ERROR; int framesize; /* used for high order functions */ char *str, *str1, *str2, ibuf[32]; symbol* s; thread* th; ctable* table; instruction* ins = &vm->instructions[vm->pc]; iop1 = ins->op1.ival; iop2 = ins->op2.ival; iopdest = ins->opdest.ival; #ifdef ZEN_ENABLE_TRAP if (vm->traphook) (vm->traphook)(vm); #endif if (ins->op == opHalt) return ZEN_VM_HALT; switch (ins->op) { case opLogand: seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival==0||vm->regs[iop2].entity.ival==0)?0:1); break; case opLogor: seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival==1||vm->regs[iop2].entity.ival==1)?1:0); break; case opBitcom: if (gettypew(&vm->regs[iopdest])==TINTEGER) seti(&vm->regs[iopdest], ~vm->regs[iopdest].entity.ival) else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opBitand: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival & vm->regs[iop2].entity.ival)) else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opBitor: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival | vm->regs[iop2].entity.ival)) else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opBitxor: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], vm->regs[iop1].entity.ival ^ vm->regs[iop2].entity.ival) else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opLshift: seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival<<vm->regs[iop2].entity.ival)); break; case opRshift: seti(&vm->regs[iopdest], (vm->regs[iop1].entity.ival>>vm->regs[iop2].entity.ival)); break; case opNeg: if (gettypew(&vm->regs[iopdest])==TINTEGER) seti(&vm->regs[iopdest], -vm->regs[iopdest].entity.ival) else setf(&vm->regs[iopdest], -vm->regs[iopdest].entity.fval) break; case opNot: vm->regs[iopdest].entity.ival = !vm->regs[iopdest].entity.ival; break; case opFact: vm->regs[iopdest].entity.ival = factorial(vm->regs[iopdest].entity.ival); break; case opAdd: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], vm->regs[iop1].entity.ival + vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], (float)vm->regs[iop1].entity.ival + vm->regs[iop2].entity.fval) else if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TSTRING) { str = (char*)calloc(strlen(getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival))+64, sizeof(char)); sprintf(str, "%d%s", vm->regs[iop1].entity.ival, getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival)); sets(&vm->regs[ins->opdest.ival], newstring(vm,str)); free(str); } else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TINTEGER) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval + (float)vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval + vm->regs[iop2].entity.fval) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TSTRING) { str = (char*)calloc(strlen(getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival))+64, sizeof(char)); sprintf(str, "%f%s", vm->regs[iop1].entity.fval, getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival)); sets(&vm->regs[ins->opdest.ival], newstring(vm,str)); free(str); } else if (gettypew(&vm->regs[iop1])==TSTRING && gettypew(&vm->regs[iop2])==TINTEGER) { str = (char*)calloc(strlen(getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival))+64, sizeof(char)); sprintf(str, "%s%d", getdata(vm->hp.heap, vm->regs[iop1].entity.ival), vm->regs[ins->op2.ival].entity.ival); sets(&vm->regs[ins->opdest.ival], newstring(vm,str)); free(str); } else if (gettypew(&vm->regs[iop1])==TSTRING && gettypew(&vm->regs[iop2])==TFLOAT) { str = (char*)calloc(strlen(getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival))+64, sizeof(char)); sprintf(str, "%s%f", getdata(vm->hp.heap, vm->regs[iop1].entity.ival), vm->regs[ins->op2.ival].entity.fval); sets(&vm->regs[ins->opdest.ival], newstring(vm,str)); free(str); } else if (gettypew(&vm->regs[iop1])==TSTRING && gettypew(&vm->regs[iop2])==TSTRING) { char* s1 = getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival); str = (char*)calloc(strlen(getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival)) +strlen(getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival))+1, sizeof(char)); strcpy(str, (char*)getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival)); strcat(str, (char*)getdata(vm->hp.heap, vm->regs[ins->op2.ival].entity.ival)); sets(&vm->regs[ins->opdest.ival], newstring(vm,str)); free(str); } //- added for testing else if (gettypew(&vm->regs[iop1])== TTABLE && gettypew(&vm->regs[iop2])==TINTEGER) {/* long tindex = TOTinsert(vm, off); ctable* tbl = (ctable*)getdata(vm->hp.heap, ind2off(vm->regs[iop1].entity.ival)); word index, source; seti(&index, tbl->nextslot); seti(&source, vm->regs[iop2].entity.ival); IA(vm, tbl, tindex, &index, &source); sett(&vm->regs[iopdest], tindex);*/ } else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opMinus: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], vm->regs[iop1].entity.ival - vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], (float)vm->regs[iop1].entity.ival - vm->regs[iop2].entity.fval) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TINTEGER) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval - (float)vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval - vm->regs[iop2].entity.fval) else setvmerror(vm, ZEN_VM_INVALID_OPERATION); break; case opMultiply: if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TINTEGER) seti(&vm->regs[iopdest], vm->regs[iop1].entity.ival * vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], (float)vm->regs[iop1].entity.ival * vm->regs[iop2].entity.fval) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TINTEGER) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval * (float)vm->regs[iop2].entity.ival) else if (gettypew(&vm->regs[iop1])==TFLOAT && gettypew(&vm->regs[iop2])==TFLOAT) setf(&vm->regs[iopdest], vm->regs[iop1].entity.fval * vm->regs[iop2].entity.fval) //- String repeat else if (gettypew(&vm->regs[iop1])==TSTRING && gettypew(&vm->regs[iop2])==TINTEGER) { char* s1 = string_repeat(getdata(vm->hp.heap, vm->regs[ins->op1.ival].entity.ival), vm->regs[iop2].entity.ival); sets(&vm->regs[iopdest], newstring(vm, s1)) } else if (gettypew(&vm->regs[iop1])==TINTEGER && gettypew(&vm->regs[iop2])==TSTRING)
void setup() { seti(); }
/* Set an integer global's value by the name. */ void setglobali(avm* vm, const char* idname, int ival) { word w; seti(&w, ival); setglobal(vm, idname, &w); }
void font_createfromfile(avm *vm) { word w; seti(&w, sfFont_CreateFromFile(getstring(vm, 0), getint(vm, 1), NULL)); returnv(vm, &w); }
static int cluster (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); // table containing data unsigned int *j, k, m, N = luaL_len(L, 1); // number of similarities & preferences unsigned int *ij = (unsigned int *)lua_newuserdata(L, 2*N * sizeof(unsigned int)); double *sij = (double *)lua_newuserdata(L, N * sizeof(double)); j = ij+N; for (k=1; k<=N; k++) { lua_rawgeti(L, 1, k); luaL_checktype(L, 2, LUA_TTABLE); *ij++ = (unsigned int)geti(L, 1); *j++ = (unsigned int)geti(L, 2); *sij++ = geti(L, 3); lua_pop(L, 1); } printf("Passed second flag.\n"); // find number of points m = ij[0]; for (k=1; k<N; k++) { if (ij[k] > m) break; else m = ij[k]; } m++; //ij is 0-based printf("Passed third flag.\n"); APOPTIONS apoptions={0}; int *idx = (int *)lua_newuserdata(L, m * sizeof(int)); // memory for returning clusters of the data points double netsim = 0.0; // variable for returning the final net similarity apoptions.cbSize = sizeof(APOPTIONS); apoptions.lambda = 0.9; apoptions.minimum_iterations = 1; apoptions.converge_iterations = 200; apoptions.maximum_iterations = 2000; apoptions.nonoise = 0; apoptions.progress=NULL; apoptions.progressf=NULL; // check whether there are extra args if (lua_gettop(L) > 1 ) { // is table with apOptions? luaL_checktype(L, 2, LUA_TTABLE); double ret; if ( (ret = getfield(L, 2, "lambda")) > 0.0 ) apoptions.lambda = ret; if ( (ret = getfield(L, 2, "convits")) > 0.0 ) apoptions.converge_iterations = (int)ret; if ( (ret = getfield(L, 2, "maxits")) > 0.0 ) apoptions.maximum_iterations = (int)ret; } printf("Passed fourth flag.\n"); printf("Number of similarities & preferences: %d\n", N); printf("Number of data points: %d\n", m); printf("\tReady to call affinity propagation.\n"); int iter = apcluster32(&sij[0], &ij[0], &ij[N], N, idx, &netsim, &apoptions); /* actual function call */ printf("\tAPCluster has finished.\n"); lua_newtable(L); if( iter>0 ) for(k=0; k<m; k++) seti(L, k+1, idx[k]); lua_pushnumber(L, netsim); lua_pushinteger(L, iter); // error code: 0, else: success return 3; /* lua_pushinteger(L, 0); lua_pushinteger(L, 0); lua_pushinteger(L, 0); return 3; */ }
void string_getstyle(avm *vm) { word w; seti(&w, sfString_GetStyle(getint(vm, 0))); returnv(vm, &w); }
void string_getfont(avm *vm) { word w; seti(&w, sfString_GetFont(getint(vm, 0))); returnv(vm, &w); }
void string_create(avm *vm) { word w; seti(&w, sfString_Create()); returnv(vm, &w); }
void QOP_bicgstabSet(QOP_Bicgstab *bcg, char *s, double v) { seti(verbose); seti(indent); }
void font_create(avm *vm) { word w; seti(&w, sfFont_Create()); returnv(vm, &w); }
void collapseLocations(geoPoint2** locations, int n_locations, double max_move, geoPoint2p** locationsOut, int* n_locationsOut, int** indecesOut, int* n_indecesOut) { if ( max_move < 0 ) max_move= 50; tprintf("Performing Location Collapse\n"); int i, j, k; tprintf("Build Distance Table with %d locations and max move %f km\n", n_locations, max_move); bool* mask= bnalloc(n_locations*n_locations); int n_mask= n_locations; int len_D= n_locations; setb(mask, n_locations, false); real* x= rnalloc(n_locations); real* y= rnalloc(n_locations); real* z= rnalloc(n_locations); int n_x, n_y, n_z; n_x= n_y= n_z= n_locations; for ( i= 0; i < n_locations; ++i ) { x[i]= locations[i]->x; y[i]= locations[i]->y; z[i]= locations[i]->z; } real tmpx, tmpy, tmpz; for ( k= 0; k < n_x; ++k ) { for ( j= k+1; j < n_x; ++j ) { tmpx= x[k] - x[j]; tmpx*= tmpx; tmpy= y[k] - y[j]; tmpy*= tmpy; tmpz= z[k] - z[j]; tmpz*= tmpz; mask[k*n_locations + j]= ((tmpx + tmpy + tmpz) < max_move*max_move ? true : false); //printf("%f,%f ", sqrt(tmpx + tmpy + tmpz), max_move*2); } } for ( k= 0; k < n_locations; ++k ) for ( j= 0; j <= k; ++j ) mask[k*n_locations + j]= mask[j*n_locations + k]; for ( k= 0; k < n_locations; ++k ) mask[k*n_locations + k]= true; tprintf("End of Build Distance Table\n"); tprintf("Begin Build Target List\n"); int* multiple= inalloc(n_locations); for ( i= 0; i < n_locations; ++i ) { multiple[i]= 0; for ( j= 0; j < n_locations; ++j ) multiple[i]+= mask[i*n_locations + j]; } bool* bad= bnalloc(len_D); setb(bad, len_D, false); bool* kill= bad; int* indices= inalloc(n_locations); for ( i= 0; i < n_locations; ++i ) indices[i]= i; int** index_list= (int**)malloc(sizeof(int*)*len_D); int* n_index_list= (int*)malloc(sizeof(int)*len_D); /*for ( i= 0; i < len_D; ++i ) { index_list[i]= (int*)malloc(sizeof(int)*1000); index_list[i][0]= i; n_index_list[i]= 1; }*/ // Repeatedly loop of location list removing closely associated groups // until all locations are separated by at least the min separation distance. int next; int* fk= inalloc(len_D); int n_fk; maxIA2(multiple, len_D, &next, fk, &n_fk); int* f= inalloc(len_D); int n_f; int sum= 0; geoPoint2** targets= (geoPoint2**)malloc(sizeof(geoPoint2*)*n_locations); for ( i= 0; i < n_locations; ++i ) targets[i]= createGeoPoint2C(locations[i]); int n_targets= n_locations; geoPoint2* target; real* dd= rnalloc(len_D); bool* sel= bnalloc(len_D); bool* I= bnalloc(len_D); int* demult= inalloc(len_D); while ( next > 1 ) { // tprintf("loop: next - %d\n", next); n_f= 0; for ( j= 0; j < len_D; ++j ) if ( mask[fk[0]*len_D + j] && !bad[j] ) { f[n_f++]= j; I[j]= true; } else I[j]= false; target= centerGP2NV(targets, n_targets, f, n_f); for ( i= 0; i < n_f; ++i ) dd[i]= distanceGP2(target, targets[f[i]]); for ( i= 0; i < n_f; ++i ) sel[i]= dd[i] < max_move; for ( i= 0; i < n_f; ++i ) if ( !sel[i] ) I[f[i]]= false; sum= 0; for ( i= 0; i < n_f; ++i ) sum+= sel[i]; if ( sum <= 1 ) { if ( sum == 0 ) for ( i= 0; i < n_f; ++i ) I[f[i]]= true; seti(demult, len_D, 0); for ( i= 0; i < n_f; ++i ) for ( j= 0; j < len_D; ++j ) demult[j]+= mask[j*len_D + f[i]]; for ( i= 0; i < n_f; ++i ) for ( j= 0; j < len_D; ++j ) mask[j*len_D + f[i]]= false; for ( i= 0; i < len_D; ++i ) multiple[i]-= demult[i]; for ( i= 0; i < len_D; ++i ) if ( I[i] ) multiple[i]= 0; maxIA2(multiple, len_D, &next, fk, &n_fk); continue; } else if ( sum == 2 && n_f > 1 ) { target= centerGP2NV(targets, n_targets, f, n_f); } for ( i= 0; i < len_D; ++i ) if ( I[i] ) bad[i]= true; n_f= 0; for ( i= 0; i < len_D; ++i ) if ( I[i] ) f[n_f++]= i; for ( i= 1; i < n_f; ++i ) kill[f[i]]= true; targets[f[0]]= target; seti(demult, len_D, 0); for ( i= 0; i < n_f; ++i ) for ( j= 0; j < len_D; ++j ) demult[j]+= mask[j*len_D + f[i]]; for ( i= 0; i < n_f; ++i ) for ( j= 0; j < len_D; ++j ) mask[j*len_D + f[i]]= false; for ( i= 0; i < len_D; ++i ) multiple[i]-= demult[i]; for ( i= 0; i < len_D; ++i ) if ( I[i] ) multiple[i]= 0; maxIA2(multiple, len_D, &next, fk, &n_fk); } for ( i= 0; i < len_D; ++i ) if ( kill[i] ) targets[i]= NULL; j= 0; for ( i= 0; i < len_D; ++i ) { if ( targets[i] != NULL ) targets[j++]= targets[i]; } n_targets= j; tprintf("End of Build Target List\n"); tprintf("number of targets: %d\n", n_targets); tprintf("Begin Generate Reference Table\n"); targets= (geoPoint2**)realloc(targets, (sizeof(geoPoint2*))*(n_targets+1)); targets[n_targets]= createGeoPoint2N(); ++n_targets; real* tx= rnalloc(n_targets); real* ty= rnalloc(n_targets); real* tz= rnalloc(n_targets); for ( i= 0; i < n_targets; ++i ) { tx[i]= targets[i]->x; ty[i]= targets[i]->y; tz[i]= targets[i]->z; } // Now that we have a list of effective station locations to use, assign // each actual location to its nearest effective location. real* templ= rnalloc(n_targets); real mn; int* fkr= inalloc(n_targets); int n_fkr; for ( k= 0; k < len_D; ++k ) { for ( i= 0; i < n_targets; ++i ) { tmpx= x[k] - tx[i]; tmpx*= tmpx; tmpy= y[k] - ty[i]; tmpy*= tmpy; tmpz= z[k] - tz[i]; tmpz*= tmpz; templ[i]= sqrt(tmpx + tmpy + tmpz); } minRA2(templ, n_targets, &mn, fkr, &n_fkr); indices[k]= fkr[0]; } int* un; int n_un; uniqueIAN(indices, len_D, &un, &n_un); int* tmpA= inalloc(n_targets); for ( i= 0; i < n_targets; ++i ) tmpA[i]= i; int* bad2= inalloc(n_targets); int n_bad2; setdiffIA(tmpA, n_targets, un, n_un, bad2, &n_bad2); for ( k= n_bad2-1; k >= 0; --k ) { for ( i= 0; i < len_D; ++i ) if ( indices[i] >= bad2[k] ) indices[i]--; } j= 0; for ( i= 0; i < n_targets; ++i ) { for ( k= 0; k < n_bad2; ++k ) if ( bad2[k] == i ) break; if ( k == n_bad2 ) targets[j++]= targets[i]; } n_targets= j; *indecesOut= indices; *n_indecesOut= len_D; *locationsOut= targets; *n_locationsOut= n_targets; tprintf("freeing allocated memory\n"); tprintf("%d total locations used\n", n_targets); free(x); free(y); free(z); free(mask); free(multiple); free(bad); free(index_list); free(n_index_list); free(fk); free(f); free(dd); free(sel); free(I); free(demult); free(tx); free(ty); free(tz); free(templ); free(fkr); free(un); free(tmpA); free(bad2); tprintf("End of Generate Reference Table\n"); tprintf("End of Performing Location Collapse\n"); }