static void adjust_anchors(Agraph_t* g, int* anchors, int k, mat z) { int i, j; double* centroid = (double*) malloc(sizeof(double)*z->c); for(i = 0; i < k; i++) { Agnode_t* n = get_node(anchors[i]); Agedge_t* e; int degree = 0; for(j = 0; j < z->c; j++) { centroid[j] = 0; } for(e = agfstedge(g,n); e; e = agnxtedge(g,e,n)) { int v = (n == aghead(e)) ? getid(agtail(e)) : getid(aghead(e)); for(j = 0; j < z->c; j++) { centroid[j] += z->m[mindex(v,j,z)]; } degree++; } for(j = 0; j < z->c; j++) { if(degree != 0) centroid[j] /= degree; z->m[mindex(anchors[i],j,z)] = centroid[j]; } } free(centroid); }
static double* mat_mult_for_d(mat u, double* s, mat u_t, double* ones) { double* tmp = (double*) malloc(sizeof(double)*u->c); double* d = (double*) malloc(sizeof(double)*u->r); int i,j; for(i = 0; i < u_t->r; i++) { //tmp = u_t*ones double sum = 0; for(j = 0; j < u_t->c; j++) { sum += u_t->m[mindex(i,j,u_t)]*ones[j]; } tmp[i] = sum; } for(i = 0; i < u->c; i++) { //tmp = diagmat(s)*tmp tmp[i] *= s[i]; } for(i = 0; i < u->r; i++) { //d = u*tmp double sum = 0; for(j = 0; j < u->c; j++) { sum += u->m[mindex(i,j,u)]*tmp[j]; } d[i] = sum; } free(tmp); return d; }
void mat_sub(mat a, mat b) { int i,j; for(i = 0; i < a->r; i++) { for(j = 0; j < a->c; j++) { a->m[mindex(i,j,a)] = a->m[mindex(i,j,a)]-b->m[mindex(i,j,b)]; } } }
mat mat_trans(mat m) { int i,j; mat m_trans = mat_new(m->c,m->r); for(i = 0; i < m->r; i++) { for(j = 0; j < m->c; j++) { m_trans->m[mindex(j,i,m_trans)] = m->m[mindex(i,j,m)]; } } return m_trans; }
static mat get_positions(Agraph_t* g, int dim) { int i; mat z = mat_new(agnnodes(g),dim); for(i = 0; i < z->r; i++) { Agnode_t* n = get_node(i); char* pos = agget(n,"pos"); if(dim == 2) { sscanf(pos,"%lf,%lf",&z->m[mindex(i,0,z)],&z->m[mindex(i,1,z)]); } else { sscanf(pos,"%lf,%lf,%lf",&z->m[mindex(i,0,z)],&z->m[mindex(i,1,z)],&z->m[mindex(i,2,z)]); } } return z; }
void pManagement::projectContents() { /* *Todo: Hazır şablonlar sınıfı oluşturulacak. *Bu method hazır şablon sınıfına devredilecek. */ //Ana dosya oluşuturuluyor. QString path = getProjectPath()+QDir::separator()+getProjectName()+ QDir::separator()+getMainClass(); QFile mclass(path+".d"); if (!mclass.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&mclass); out << "import std.stdio;" << endl << "void main(){" << endl << " writefln(\"Merhaba\");" << endl << "}" << endl; mclass.close(); QFile mindex(getProjectPath()+QDir::separator()+getProjectName()+QDir::separator()+"index.did"); if (!mindex.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out2(&mindex); out2 << "RUNCLASS=" << getMainClass() <<".d\n"; mindex.close(); projectsHistory(getProjectPath()+QDir::separator()+getProjectName()); }
int main(int argc, char* argv[]) { struct marsopts opts = init(argc, argv); Agraph_t* g = agread(opts.fin, (Agdisc_t*)NULL); Agnode_t* n; mat z; init_graph(g); z = mars(g, opts); mat_scalar_mult(z, opts.scale); if(opts.viewer) { viewer(argc, argv); } else { for(n = agfstnode(g); n; n = agnxtnode(g,n)) { int id = getid(n); char* s = pos_to_str(&z->m[mindex(id, 0, z)], z->c); agset(n,"pos",s); free(s); } agwrite(g, opts.fout); } mat_free(z); clean_up(g); agclose(g); return 0; }
static void qr_factorize(mat m, mat q, mat r) { int i,j; double* a = (double*) malloc(sizeof(double)*m->r*m->c); double* tau = (double*) malloc(sizeof(double)*m->c); double* work; double workopt; int lda = m->r; int lwork = -1; int info; int loc; loc = 0; for(j = 0; j < m->c; j++) { for(i = 0; i < m->r; i++) { a[loc++] = m->m[mindex(i,j,m)]; } } /*QR decomposition into a compact format*/ dgeqrf_(&m->r, &m->c, a, &lda, tau, &workopt, &lwork, &info); lwork = (int) workopt; work = (double*) malloc(sizeof(double)*lwork); dgeqrf_(&m->r, &m->c, a, &lda, tau, work, &lwork, &info); for(i = 0; i < m->c; i++) { for(j = i; j < m->c; j++) { r->m[mindex(i,j,r)] = a[i+j*lda]; a[i+j*lda] = (i == j) ? 1 : 0; } } lwork = -1; dorgqr_(&m->r, &m->c, &m->c, a, &lda, tau, &workopt, &lwork, &info); lwork = (int) workopt; work = (double*) realloc(work, sizeof(double)*lwork); dorgqr_(&m->r, &m->c, &m->c, a, &lda, tau, work, &lwork, &info); for(i = 0; i < q->r; i++) { for(j = 0; j < q->c; j++) { q->m[mindex(i,j,q)] = a[i+j*lda]; } } free(work); free(a); free(tau); }
static mat some_pairs_dist(mat z, int* anchors, int k) { int i, j, x, dim = z->c; mat d = mat_new(k,z->r); for(i = 0; i < k; i++) { int anchor = anchors[i]; for(j = 0; j < z->r; j++) { double dist = 0; for(x = 0; x < dim; x++) { dist += ((z->m[mindex(anchor,x,z)]-z->m[mindex(j,x,z)]) * (z->m[mindex(anchor,x,z)]-z->m[mindex(j,x,z)])); } d->m[mindex(i,j,d)] = sqrt(dist); } } return d; }
static mat sample_cols(Agraph_t* g, mat x, int power) { mat m = mat_new(x->c, x->r); int i, j, k = x->r; double* p = prob(x,power); for(i = 0; i < x->r; i++) { for(j = 0; j < x->c; j++) { if(x->m[mindex(i,j,x)] == 0) { m->m[mindex(j,i,m)] = 0; } else { m->m[mindex(j,i,m)] = (-1.0/pow(x->m[mindex(i,j,x)],power))/sqrt(k*p[i]); } } } free(p); return m; }
static int* graph_cluster(Agraph_t* g, mat dij, int* anchors) { int k = dij->r; int* clusters = (int*) malloc(sizeof(int)*dij->c); int i, j; for(i = 0; i < dij->c; i++) { int min_index = 0, min_dist = dij->m[mindex(0,i,dij)]; for(j = 1; j < k; j++) { if(min_dist > dij->m[mindex(j,i,dij)]) { min_dist = dij->m[mindex(j,i,dij)]; min_index = j; } } clusters[i] = min_index; } return clusters; }
static double stress(mat z, mat dij, int* anchors, int power) { int i,j; double sum; mat d = some_pairs_dist(z,anchors,dij->r); mat_sub(d,dij); for(i = 0; i < d->r; i++) { for(j = 0; j < d->c; j++) { d->m[mindex(i,j,d)] = pow(d->m[mindex(i,j,d)],2); if(dij->m[mindex(i,j,d)] != 0) { d->m[mindex(i,j,d)] *= 1.0 / pow(dij->m[mindex(i,j,d)], power); } } } sum = mat_accu(d); mat_free(d); return sum; }
double* mat_col(mat a, int j) { double* col = (double*) malloc(sizeof(double)*a->r); int i; for(i = 0; i < a->r; i++) { col[i] = a->m[mindex(i,j,a)]; } return col; }
void mat_print(mat m, FILE* out) { int i,j; for(i = 0; i < m->r; i++) { for(j = 0; j < m->c; j++) { fprintf(out,"%f ",m->m[mindex(i,j,m)]); } fprintf(out,"\n"); } }
mat mat_mult(mat a, mat b) { int i,j,k; mat res = mat_new(a->r, b->c); if(a->c != b->r) { fprintf(stderr, "Invalid matrix multiplication. Cols of param 1 do not equal rows of param 2."); exit(1); } for(i = 0; i < res->r; i++) { for(j = 0; j < res->c; j++) { double sum = 0; for(k = 0; k < a->c; k++) { sum += a->m[mindex(i,k,a)]*b->m[mindex(k,j,b)]; } res->m[mindex(i,j,res)] = sum; } } return res; }
static double* prob(mat x, int power) { int i,j; double* p = (double*) malloc(sizeof(double)*x->r); double frob_norm = 0, sum; for(i = 0; i < x->r; i++) { sum = 0; for(j = 0; j < x->c; j++) { if(x->m[mindex(i,j,x)] != 0) { sum += (1.0 / pow(x->m[mindex(i,j,x)], 2*power)); } } p[i] = sum; frob_norm += sum; } frob_norm *= (((double)x->c)/x->r); for(i = 0; i < x->r; i++) { p[i] /= frob_norm; } return p; }
static void translate_by_centroid(mat z) { int i, j; double* centroid = (double*) malloc(sizeof(double)*z->c); darrset(centroid, z->c, 0); for(i = 0; i < z->r; i++) { for(j = 0; j < z->c; j++) { centroid[j] += z->m[mindex(i,j,z)]; } } for(i = 0; i < z->c; i++) { centroid[i] /= z->r; } for(i = 0; i < z->r; i++) { for(j = 0; j < z->c; j++) { z->m[mindex(i,j,z)] -= centroid[j]; } } free(centroid); }
static void singular_vectors(Agraph_t* g, mat x, int power, mat u, double* s) { int i, j, loc, n = x->c, k = x->r; int lda = n, ldu = n, ldvt = k, info, lwork = -1; mat c = sample_cols(g,x,power); double* c_lapack = (double*) malloc(sizeof(double)*n*k); double* s_lapack = (double*) malloc(sizeof(double)*k); double* u_lapack = (double*) malloc(sizeof(double)*n*k); double* vt_lapack = (double*) malloc(sizeof(double)*k*k); double* work; double wkopt; loc = 0; for(j = 0; j < c->c; j++) {//Write c into array in column major order for(i = 0; i < c->r; i++) { c_lapack[loc++] = c->m[mindex(i,j,c)]; } } //Query for optimal size of work array dgesvd_("S","S", &n, &k, c_lapack, &lda, s_lapack, u_lapack, &ldu, vt_lapack, &ldvt, &wkopt, &lwork, &info); lwork = (int)wkopt; work = (double*) malloc(sizeof(double)*lwork); //Compute svd dgesvd_("S","S", &n, &k, c_lapack, &lda, s_lapack, u_lapack, &ldu, vt_lapack, &ldvt, work, &lwork, &info); for(i = 0; i < n; i++) { for(j = 0; j < k; j++) { u->m[mindex(i,j,u)] = u_lapack[i+j*ldu]; } } for(i = 0; i < k; i++) { s[i] = s_lapack[i]; } mat_free(c); free(c_lapack); free(s_lapack); free(u_lapack); free(vt_lapack); free(work); }
static void update_anchors(mat z, mat dij, int* anchors, int power) { int i, j, k; double* xi = (double*) malloc(sizeof(double)*z->c); double* xi_next = (double*) malloc(sizeof(double)*z->c); double* xj = (double*) malloc(sizeof(double)*z->c); for(i = 0; i < dij->r; i++) { int n = anchors[i]; double wgt_sum = 0; darrset(xi_next, z->c, 0); for(j = 0; j < z->c; j++) { xi[j] = z->m[mindex(n,j,z)]; } for(j = 0; j < z->r; j++) { if(n != j) { double wgt = 1.0/pow(dij->m[mindex(i,j,dij)],power); double dist = 0; for(k = 0; k < z->c; k++) { xj[k] = z->m[mindex(j,k,z)]; } for(k = 0; k < z->c; k++) { dist += (xi[k]-xj[k])*(xi[k]-xj[k]); } dist = sqrt(dist); if(dist > EPSILON) { for(k = 0; k < z->c; k++) { xi_next[k] += wgt*(xj[k]+dij->m[mindex(i,j,dij)]*(xi[k]-xj[k])/dist); } wgt_sum += wgt; } } } for(j = 0; j < z->c; j++) { z->m[mindex(n,j,z)] = xi_next[j]/wgt_sum; } } free(xi); free(xi_next); free(xj); }
double* mat_vec_mult(mat a, double* b) { double* res = (double*) malloc(sizeof(double)*a->r); int i,j; for(i = 0; i < a->r; i++) { double sum = 0; for(j = 0; j < a->c; j++) { sum += a->m[mindex(i,j,a)]*b[j]; } res[i] = sum; } return res; }
static mat barnes_hut(mat z) { mat lz = mat_new(z->r, z->c); real* x = (real*) malloc(sizeof(real)*z->r*z->c); real *center = NULL, *supernode_wgts = NULL, *distances = NULL; real bh = 0.65, counts = 0; /* Barnes-Hut constant, if width(snode)/dist[i,snode] < bh, treat snode as a supernode.*/ int flag, nsuper, nsupermax, dim = z->c, max_qtree_level = 10; //max_qtree_level, like bh, should also be a command line argument QuadTree qt = NULL; int i, j, node; for(i = 0; i < z->r; i++) { for(j = 0; j < z->c; j++) { x[i*z->c + j] = z->m[mindex(i,j,z)]; } } qt = QuadTree_new_from_point_list(dim, z->r, max_qtree_level, x, NULL); for(i = 0; i < z->r; i++) { QuadTree_get_supernodes(qt, bh, &(x[dim*i]), i, &nsuper, &nsupermax, ¢er, &supernode_wgts, &distances, &counts, &flag); for(j = 0; j < dim; j++) { for(node = 0; node < nsuper; node++) { if(distances[node] > EPSILON) { lz->m[mindex(i,j,lz)] += supernode_wgts[node] * (z->m[mindex(i,j,z)]-center[node*dim+j]) / distances[node]; } else { lz->m[mindex(i,j,lz)] = 0; } } } } free(x); free(center); free(supernode_wgts); free(distances); QuadTree_delete(qt); return lz; }
static void upper_tri_solve(mat u, double* b) { double* a = (double*) malloc(sizeof(double)*u->r*u->c); char uplo = 'U'; char trans = 'N'; char diag = 'N'; int nrhs = 1, lda = u->r, ldb = u->c; int info; int loc, i, j; loc = 0; for(j = 0; j < u->c; j++) { for(i = 0; i < u->r; i++) { a[loc++] = u->m[mindex(i,j,u)]; } } dtrtrs_(&uplo, &trans, &diag, &u->c, &nrhs, a, &lda, b, &ldb, &info); free(a); }
static void select_anchors(Agraph_t* g, mat x, int* anchors, int k) { int i, j, max_dist, max_index; Agnode_t* n; double *d, *dmin; n = agfstnode(g); d = dijkstra(g,n); dmin = (double*) malloc(sizeof(double)*agnnodes(g)); darrset(dmin, agnnodes(g), DBL_MAX); max_dist = d[0]; max_index = 0; for(i = 0; i < agnnodes(g); i++) { if(max_dist < d[i]) { max_dist = d[i]; max_index = i; } } for(i = 0; i < k; i++) { n = get_node(max_index); anchors[i] = max_index; free(d); d = dijkstra(g,n); for(j = 0; j < agnnodes(g); j++) { x->m[mindex(i,j,x)] = d[j]; dmin[j] = MIN(dmin[j],d[j]); } max_dist = dmin[0]; max_index = 0; for(j = 0; j < agnnodes(g); j++) { if(max_dist < dmin[j]) { max_dist = dmin[j]; max_index = j; } } } free(d); free(dmin); }
void putref(int n, char **tvec) { char *s, *tx; char buf1[BUFSIZ], buf2[50]; int nauth = 0, i, lastype = 0, cch, macro = 0, la; int lauth = 0, ltitle = 0, lother = 0; fprintf(fo, ".]-%c", sep); for (i = 0; i < n; i++) { s = tvec[i]; if (*s == 0) continue; if (control(s[0])) { if (lastype && macro) fprintf(fo, "..%c", sep); if (control(s[1])) { cch = s[2]; tx = s+3; macro = 1; } else { cch = s[1]; tx = s+2; macro = 0; } } else { cch = lastype; tx = s; } #if EBUG fprintf(stderr, "smallcaps %s cch %c\n",smallcaps, cch); #endif if (mindex(smallcaps, cch)) tx = caps(tx, buf1); #if EBUG fprintf(stderr, " s %o tx %o %s\n",s,tx,tx); #endif if (!control(s[0])) { /* append to previous item */ if (lastype != 0) { if (macro) fprintf(fo, "%s%c", tx, sep); else fprintf(fo, ".as [%c \" %s%c",lastype,tx,sep); if (lastype == 'T') ltitle = (mindex(".;,?", last(tx))!=0); if (lastype == 'A') lauth = last(tx) == '.'; } continue; } if (mindex("XYZ[]", cch)) { /* skip these */ lastype = 0; continue; } else { if (cch == 'A') { if (nauth < authrev) tx = revauth(tx, buf2); if (nauth++ == 0) if (macro) fprintf(fo, ".de [%c%c%s%c",cch,sep,tx,sep); else fprintf(fo, ".ds [%c%s%c", cch,tx,sep); else { la = (tvec[i+1][1]!='A'); fprintf(fo, ".as [A \""); if (la == 0 || nauth != 2) fprintf(fo, ","); if (la) fprintf(fo,"%s", mindex(smallcaps, 'A') ? " \\s-2AND\\s+2" : " and"); fprintf(fo, "%s%c", tx, sep); } lauth = last(tx) == '.'; } else { if (macro) fprintf(fo, ".de [%c%c%s%c",cch,sep,tx,sep); else fprintf(fo, ".ds [%c%s%c",cch,tx, sep); } } if (cch == 'P') fprintf(fo, ".nr [P %d%c", mindex(s, '-')!=0, sep); lastype = cch; if (cch == 'T') ltitle = (mindex(".;,?", last(tx)) != 0); if (cch == 'O') lother = (mindex(".;,?", last(tx)) != 0); } if (lastype && macro) fprintf(fo, "..%c", sep); fprintf(fo, ".nr [T %d%c", ltitle, sep); fprintf(fo, ".nr [A %d%c", lauth, sep); fprintf(fo, ".nr [O %d%c", lother, sep); fprintf(fo, ".][ %s%c", class(n, tvec), '\n'); }
int findline(char *_in, char **out, int outlen, long _indexdate) { static char name[100] = ""; char *p, **ftp; static FILE *fa = NULL; long lp, llen; # ifdef D1 int len; # endif int k, nofil; # if D1 fprintf(stderr, "findline: %s\n", _in); # endif if (mindex(_in, '!')) /* return(remote(in, *out)); /\* Does NOTHING */ return(0); nofil = _in[0]==0; for(p=_in; *p && *p != ':' && *p != ';'; p++) ; if (*p) *p++=0; else p=_in; k = sscanf(p, "%ld,%ld", &lp, &llen); # ifdef D1 fprintf(stderr, "p %s k %d lp %ld llen %ld\n",p,k,lp,llen); # endif if (k<2) { lp = 0; llen=outlen; } # ifdef D1 fprintf(stderr, "lp %ld llen %ld\n",lp, llen); # endif # ifdef D1 fprintf(stderr, "fa now %o, p %o in %o %s\n",fa, p,in,_in); # endif if (nofil) { # if D1 fprintf(stderr, "set fa to stdin\n"); # endif fa = stdin; } else if (strcmp (name, _in) != 0 || 1) { # if D1 fprintf(stderr, "old: %s new %s not equal\n",name,_in); # endif if (fa != NULL) fa = freopen(_in, "r", fa); else fa = fopen(_in, "r"); # if D1 if (fa==NULL) fprintf(stderr, "failed to (re)open *%s*\n",_in); # endif if (fa == NULL) return(0); /* err("Can't open %s", in); */ strcpy(name, _in); if (gdate(fa) > _indexdate && _indexdate != 0) { if (keepold) { for(ftp=fgnames; ftp<fgnamp; ftp++) if (strcmp(*ftp, name)==SAME) return(0); strcpy (*fgnamp++ = fgp, name); assert(fgnamp<fgnames+FGCT); while (*fgp && *fgp!=':') fgp++; *fgp++ = 0; assert (fgp<fgspace+FGSIZE); return(0); } fprintf(stderr, "Warning: index predates file '%s'\n", name); } } # if D1 else fprintf(stderr, "old %s new %s same fa %o\n", name,_in,fa); # endif if (fa != NULL) { fseek(fa, lp, SEEK_SET); *out = malloc(llen + 1); if (*out == NULL) { return(0); } # ifdef D1 len = # endif fread(*out, 1, llen, fa); *(*out + llen) = 0; # ifdef D1 fprintf(stderr, "length as read is %d\n",len); # endif } return(llen); }
mat mars(Agraph_t* g, struct marsopts opts) { int i, j, n = agnnodes(g), k = MIN(n, MAX(opts.k, 2)), iter = 0; mat dij, u, u_trans, q, r, q_t, tmp, tmp2, z; double* s = (double*) malloc(sizeof(double)*k); double* ones = (double*) malloc(sizeof(double)*n); double* d; int* anchors = (int*) malloc(sizeof(int)*k); int* clusters = NULL; double change = 1, old_stress = -1; dij = mat_new(k, n); u = mat_new(n,k); tmp = mat_new(n,k); darrset(ones,n,-1); select_anchors(g, dij, anchors, k); if(opts.color) { for(i = 0; i < k; i++) { Agnode_t* anchor = get_node(anchors[i]); agset(anchor, "color", "red"); } } if(opts.power != 1) { clusters = graph_cluster(g,dij,anchors); } singular_vectors(g, dij, opts.power, u, s); vec_scalar_mult(s, k, -1); u_trans = mat_trans(u); d = mat_mult_for_d(u, s, u_trans, ones); for(i = 0; i < u->c; i++) { double* col = mat_col(u,i); double* b = inv_mul_ax(d,col,u->r); for(j = 0; j < u->r; j++) { tmp->m[mindex(j,i,tmp)] = b[j]; } free(b); free(col); } tmp2 = mat_mult(u_trans,tmp); for(i = 0; i < k; i++) { tmp2->m[mindex(i,i,tmp2)] += (1.0/s[i]); } q = mat_new(tmp2->r, tmp2->c); r = mat_new(tmp2->c, tmp2->c); qr_factorize(tmp2,q,r); q_t = mat_trans(q); if(opts.given) { z = get_positions(g, opts.dim); } else { z = mat_rand(n, opts.dim); } translate_by_centroid(z); if(opts.viewer) { init_viewer(g, opts.max_iter); append_layout(z); } old_stress = stress(z, dij, anchors, opts.power); while(change > EPSILON && iter < opts.max_iter) { mat right_side; double new_stress; if(opts.power == 1) { right_side = barnes_hut(z); } else { right_side = barnes_hut_cluster(z, dij, clusters, opts.power); } for(i = 0; i < opts.dim; i++) { double sum = 0; double* x; double* b = mat_col(right_side,i); for(j = 0; j < right_side->r; j++) { sum += b[j]; } x = inv_mul_full(d, b, right_side->r, u, u_trans, q_t, r); for(j = 0; j < z->r; j++) { z->m[mindex(j,i,z)] = x[j] - sum/right_side->r; } free(x); free(b); } adjust_anchors(g, anchors, k, z); update_anchors(z, dij, anchors, opts.power); translate_by_centroid(z); if(opts.viewer) { append_layout(z); } new_stress = stress(z, dij, anchors, opts.power); change = fabs(new_stress-old_stress)/old_stress; old_stress = new_stress; mat_free(right_side); iter++; } mat_free(dij); mat_free(u); mat_free(u_trans); mat_free(q); mat_free(r); mat_free(q_t); mat_free(tmp); mat_free(tmp2); free(s); free(ones); free(d); free(anchors); free(clusters); return z; }
static mat barnes_hut_cluster(mat z, mat dij, int* clusters, int power) { mat lz = mat_new(z->r, z->c); int k = dij->r; int n = z->r; int i, j, qt_i, node; real** x = (real**) malloc(sizeof(real*)*k); real** wgts = (real**) malloc(sizeof(real*)*k); real* x_all = (real*) malloc(sizeof(real)*z->r*z->c); real *center = NULL, *supernode_wgts = NULL, *distances = NULL; real bh = 0.65, counts = 0; int flag, nsuper, nsupermax, dim = z->c, max_qtree_level = 10; QuadTree* qt = (QuadTree*) malloc(sizeof(QuadTree)*2*k); int* sizes = (int*) malloc(sizeof(int)*k); int* curr_loc = (int*) malloc(sizeof(int)*k); iarrset(sizes,k,0); iarrset(curr_loc,k,0); for(i = 0; i < n; i++) { sizes[clusters[i]]++; } for(i = 0; i < k; i++) { x[i] = (real*) malloc(sizeof(real)*sizes[i]*z->c); wgts[i] = (real*) malloc(sizeof(real)*sizes[i]); } for(i = 0; i < z->r; i++) { for(j = 0; j < z->c; j++) { x_all[i*z->c+j] = z->m[mindex(i,j,z)]; } } for(i = 0; i < n; i++) { int cluster = clusters[i]; for(j = 0; j < z->c; j++) { x[cluster][curr_loc[cluster]*z->c+j] = z->m[mindex(i,j,z)]; } curr_loc[cluster]++; } iarrset(curr_loc,k,0); for(i = 0; i < n; i++) { int cluster = clusters[i]; wgts[cluster][curr_loc[cluster]] = dij->m[mindex(cluster,i,dij)] < EPSILON ? 0 : 1.0/pow(dij->m[mindex(cluster,i,dij)],power-1); curr_loc[cluster]++; } for(i = 0; i < k; i++) { qt[i] = QuadTree_new_from_point_list(dim, sizes[i], max_qtree_level, x[i], NULL); } for(i = 0; i < k; i++) { qt[i+k] = QuadTree_new_from_point_list(dim, sizes[i], max_qtree_level, x[i], wgts[i]); } for(i = 0; i < z->r; i++) { for(qt_i = 0; qt_i < k; qt_i++) { double d = dij->m[mindex(qt_i,i,dij)]; if(d < EPSILON) { //Node i is the center of some cluster QuadTree_get_supernodes(qt[qt_i+k], bh, &(x_all[dim*i]), -1, &nsuper, &nsupermax, ¢er, &supernode_wgts, &distances, &counts, &flag); d = 1; } else { QuadTree_get_supernodes(qt[qt_i], bh, &(x_all[dim*i]), -1, &nsuper, &nsupermax, ¢er, &supernode_wgts, &distances, &counts, &flag); d = 1.0 / pow(d,power-1); } for(j = 0; j < dim; j++) { for(node = 0; node < nsuper; node++) { if(distances[node] > EPSILON && d > EPSILON) lz->m[mindex(i,j,lz)] += d*supernode_wgts[node] * (z->m[mindex(i,j,z)]-center[node*dim+j]) / distances[node]; } } } } for(i = 0; i < k; i++) { free(x[i]); free(wgts[i]); } for(i = 0; i < 2*k; i++) { QuadTree_delete(qt[i]); } free(qt); free(sizes); free(curr_loc); free(x_all); free(center); free(distances); free(supernode_wgts); return lz; }