void dsort (double a[], int left, int right) { int i,last; void dswap (double[], int, int); if(left>=right) return; dswap(a, left, (left+right)/2); last = left; for (i=left+1; i<=right; i++) if (a[i] < a[left]) dswap(a, ++last, i); dswap(a, left, last); dsort(a,left,last); dsort(a,last+1,right); }
// 递归,感觉还是没有很好掌握while 到递归的转换 Node* dsort(Head head1, Head head2, Head head,Head tmp ) { if(NULL == head1 && NULL == head) { return head2; } if(NULL == head2 && NULL == head) { return head1; } if(NULL == head1 && NULL != head) { tmp->next = head2; return head; } if(NULL == head2 && NULL != head) { tmp->next = head1; return head; } if(head1->num < head2->num) { if(NULL == head) { head = head1; tmp = head; } else { tmp->next = head1; tmp = head1; } head1 = head->next; } else { if(NULL == head) { head = head2; tmp = head; } else { tmp->next = head2; tmp = head2; } head2 = head->next; } dsort(head1, head2, head, tmp); }
int main() { int n,i,ei=0,oi=0; scanf("%d",&n); int arr[n],even[n],odd[n]; for(i=0;i<n;i++) { even[i]=odd[i]=0; } for(i=0;i<n;i++) { scanf("%d",&arr[i]); if( arr[i] & 1 ) odd[oi++] = arr[i]; else even[ei++] = arr[i]; } asort(even,n); dsort(odd,n); }
int main(){ int i; int v[] = {7, 2, 7, 2, 7, 2, 7, 2, 7, 2}; int *a = csort(v, 8); int *b = dsort(v, 8, 0, 13); for(i = 0; i < 8; i++) printf("%d ", a[i]); putchar('\n'); for(i = 0; i < 8; i++) printf("%d ", b[i]); free(a); free(b); scanf("%d", &i); return 0; }
static int compute_tree_adaboost(ETree *etree,int n,int d,double *x[],int y[], int nmodels,int stumps, int minsize) { int i,b; int *samples; double **trx; int *try; double *prob; double *prob_copy; double sumalpha; double eps; int *pred; double *margin; double sumprob; if(nmodels<1){ fprintf(stderr,"compute_tree_adaboost: nmodels must be greater than 0\n"); return 1; } if(stumps != 0 && stumps != 1){ fprintf(stderr,"compute_tree_bagging: parameter stumps must be 0 or 1\n"); return 1; } if(minsize < 0){ fprintf(stderr,"compute_tree_bagging: parameter minsize must be >= 0\n"); return 1; } etree->nclasses=iunique(y,n, &(etree->classes)); if(etree->nclasses<=0){ fprintf(stderr,"compute_tree_adaboost: iunique error\n"); return 1; } if(etree->nclasses==1){ fprintf(stderr,"compute_tree_adaboost: only 1 class recognized\n"); return 1; } if(etree->nclasses==2) if(etree->classes[0] != -1 || etree->classes[1] != 1){ fprintf(stderr,"compute_tree_adaboost: for binary classification classes must be -1,1\n"); return 1; } if(etree->nclasses>2){ fprintf(stderr,"compute_tree_adaboost: multiclass classification not allowed\n"); return 1; } if(!(etree->tree=(Tree *)calloc(nmodels,sizeof(Tree)))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(etree->weights=dvector(nmodels))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(trx=(double **)calloc(n,sizeof(double*)))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(try=ivector(n))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(prob_copy=dvector(n))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(prob=dvector(n))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } if(!(pred=ivector(n))){ fprintf(stderr,"compute_tree_adaboost: out of memory\n"); return 1; } for(i =0;i<n;i++) prob[i]=1.0/(double)n; etree->nmodels=nmodels; sumalpha=0.0; for(b=0;b<nmodels;b++){ for(i =0;i<n;i++) prob_copy[i]=prob[i]; if(sample(n, prob_copy, n, &samples, TRUE,b)!=0){ fprintf(stderr,"compute_tree_adaboost: sample error\n"); return 1; } for(i=0;i<n;i++){ trx[i] = x[samples[i]]; try[i] = y[samples[i]]; } if(compute_tree(&(etree->tree[b]),n,d,trx,try,stumps,minsize)!=0){ fprintf(stderr,"compute_tree_adaboost: compute_tree error\n"); return 1; } free_ivector(samples); eps=0.0; for(i=0;i<n;i++){ pred[i]=predict_tree(&(etree->tree[b]),x[i],&margin); if(pred[i] < -1 ){ fprintf(stderr,"compute_tree_adaboost: predict_tree error\n"); return 1; } if(pred[i]==0 || pred[i] != y[i]) eps += prob[i]; free_dvector(margin); } if(eps > 0.0 && eps < 0.5){ etree->weights[b]=0.5 *log((1.0-eps)/eps); sumalpha+=etree->weights[b]; }else{ etree->nmodels=b; break; } sumprob=0.0; for(i=0;i<n;i++){ prob[i]=prob[i]*exp(-etree->weights[b]*y[i]*pred[i]); sumprob+=prob[i]; } if(sumprob <=0.0){ fprintf(stderr,"compute_tree_adaboost: sumprob = 0\n"); return 1; } for(i=0;i<n;i++) prob[i] /= sumprob; } if(etree->nmodels<=0){ fprintf(stderr,"compute_tree_adaboost: no models produced\n"); return 1; } if(sumalpha <=0){ fprintf(stderr,"compute_tree_adaboost: sumalpha = 0\n"); return 1; } for(b=0;b<etree->nmodels;b++) etree->weights[b] /= sumalpha; free(trx); free_ivector(try); free_ivector(pred); free_dvector(prob); free_dvector(prob_copy); return 0; } static void split_node(Node *node,Node *nodeL,Node *nodeR,int classes[], int nclasses) { int **indx; double *tmpvar; int i,j,k; int **npL , **npR; double **prL , **prR; int totL,totR; double a,b; double *decrease_in_inpurity; double max_decrease=0; int splitvar; int splitvalue; int morenumerous; nodeL->priors=dvector(nclasses); nodeR->priors=dvector(nclasses); nodeL->npoints_for_class=ivector(nclasses); nodeR->npoints_for_class=ivector(nclasses); indx=imatrix(node->nvar,node->npoints); tmpvar=dvector(node->npoints); decrease_in_inpurity=dvector(node->npoints-1); npL=imatrix(node->npoints,nclasses); npR=imatrix(node->npoints,nclasses); prL=dmatrix(node->npoints,nclasses); prR=dmatrix(node->npoints,nclasses); splitvar=0; splitvalue=0; max_decrease=0; for(i=0;i<node->nvar;i++){ for(j=0;j<node->npoints;j++) tmpvar[j]=node->data[j][i]; for(j=0;j<node->npoints;j++) indx[i][j]=j; dsort(tmpvar,indx[i],node->npoints,SORT_ASCENDING); for(k=0;k<nclasses;k++) if(node->classes[indx[i][0]]==classes[k]){ npL[0][k] = 1; npR[0][k] = node->npoints_for_class[k]-npL[0][k]; } else{ npL[0][k] = 0; npR[0][k] = node->npoints_for_class[k]; } for(j=1;j<node->npoints-1;j++) for(k=0;k<nclasses;k++) if(node->classes[indx[i][j]]==classes[k]){ npL[j][k] = npL[j-1][k] +1; npR[j][k] = node->npoints_for_class[k] - npL[j][k]; } else { npL[j][k] = npL[j-1][k]; npR[j][k] = node->npoints_for_class[k] - npL[j][k]; } for(j=0;j<node->npoints-1;j++){ if(node->data[indx[i][j]][i] != node->data[indx[i][j+1]][i]){ totL = totR = 0; for(k=0;k<nclasses;k++) totL += npL[j][k]; for(k=0;k<nclasses;k++) prL[j][k] = (double) npL[j][k] / (double) totL; for(k=0;k<nclasses;k++) totR += npR[j][k]; for(k=0;k<nclasses;k++) prR[j][k] = (double) npR[j][k] /(double) totR; a = (double) totL / (double) node->npoints; b = (double) totR / (double) node->npoints ; decrease_in_inpurity[j] = gini_index(node->priors,nclasses) - a * gini_index(prL[j],nclasses) - b * gini_index(prR[j],nclasses); } } for(j=0;j<node->npoints-1;j++) if(decrease_in_inpurity[j] > max_decrease){ max_decrease = decrease_in_inpurity[j]; splitvar=i; splitvalue=j; for(k=0;k<nclasses;k++){ nodeL->priors[k]=prL[splitvalue][k]; nodeR->priors[k]=prR[splitvalue][k]; nodeL->npoints_for_class[k]=npL[splitvalue][k]; nodeR->npoints_for_class[k]=npR[splitvalue][k]; } } } node->var=splitvar; node->value=(node->data[indx[splitvar][splitvalue]][node->var]+ node->data[indx[splitvar][splitvalue+1]][node->var])/2.; nodeL->nvar=node->nvar; nodeL->nclasses=node->nclasses; nodeL->npoints=splitvalue+1; nodeL->terminal=TRUE; if(gini_index(nodeL->priors,nclasses) >0) nodeL->terminal=FALSE; nodeL->data=(double **) calloc(nodeL->npoints,sizeof(double *)); nodeL->classes=ivector(nodeL->npoints); for(i=0;i<nodeL->npoints;i++){ nodeL->data[i] = node->data[indx[splitvar][i]]; nodeL->classes[i] = node->classes[indx[splitvar][i]]; } morenumerous=0; for(k=0;k<nclasses;k++) if(nodeL->npoints_for_class[k] > morenumerous){ morenumerous = nodeL->npoints_for_class[k]; nodeL->node_class=classes[k]; } nodeR->nvar=node->nvar; nodeR->nclasses=node->nclasses; nodeR->npoints=node->npoints-nodeL->npoints; nodeR->terminal=TRUE; if(gini_index(nodeR->priors,nclasses) >0) nodeR->terminal=FALSE; nodeR->data=(double **) calloc(nodeR->npoints,sizeof(double *)); nodeR->classes=ivector(nodeR->npoints); for(i=0;i<nodeR->npoints;i++){ nodeR->data[i] = node->data[indx[splitvar][nodeL->npoints+i]]; nodeR->classes[i] = node->classes[indx[splitvar][nodeL->npoints+i]]; } morenumerous=0; for(k=0;k<nclasses;k++) if(nodeR->npoints_for_class[k] > morenumerous){ morenumerous = nodeR->npoints_for_class[k]; nodeR->node_class=classes[k]; } free_imatrix(indx, node->nvar,node->npoints); free_imatrix(npL, node->npoints,nclasses); free_imatrix(npR, node->npoints,nclasses); free_dmatrix(prL, node->npoints,nclasses); free_dmatrix(prR, node->npoints,nclasses); free_dvector(tmpvar); free_dvector(decrease_in_inpurity); }
void main(int argc, char **argv) { int fix; ulong block, newnull, cblock; vlong maxsize; uvlong length, clength; char buf[256], *dumpname, *proto, *s, *src, *status; Cdimg *cd; Cdinfo info; XDir dir; Direc *iconform, idumproot, iroot, *jconform, jdumproot, jroot, *r; Dump *dump; fix = 0; status = nil; memset(&info, 0, sizeof info); proto = "/sys/lib/sysconfig/proto/allproto"; src = "./"; info.volumename = atom("9CD"); info.volumeset = atom("9VolumeSet"); info.publisher = atom("9Publisher"); info.preparer = atom("dump9660"); info.application = atom("dump9660"); info.flags = CDdump; maxsize = 0; mk9660 = 0; fmtinstall('H', encodefmt); ARGBEGIN{ case 'D': chatty++; break; case 'M': mk9660 = 1; argv0 = "disk/mk9660"; info.flags &= ~CDdump; break; case '9': info.flags |= CDplan9; break; case ':': docolon = 1; break; case 'a': doabort = 1; break; case 'B': info.flags |= CDbootnoemu; /* fall through */ case 'b': if(!mk9660) usage(); info.flags |= CDbootable; info.bootimage = EARGF(usage()); break; case 'c': info.flags |= CDconform; break; case 'f': fix = 1; break; case 'j': info.flags |= CDjoliet; break; case 'n': now = atoi(EARGF(usage())); break; case 'm': maxsize = strtoull(EARGF(usage()), 0, 0); break; case 'o': dataoffset = atoll(EARGF(usage())); blocksize = atoi(EARGF(usage())); if(blocksize%Blocksize) sysfatal("bad block size %d -- must be multiple of 2048", blocksize); blocksize /= Blocksize; break; case 'p': proto = EARGF(usage()); break; case 'r': info.flags |= CDrockridge; break; case 's': src = EARGF(usage()); break; case 'v': info.volumename = atom(EARGF(usage())); break; case 'x': info.flags |= CDpbs; info.loader = EARGF(usage()); break; default: usage(); }ARGEND if(info.flags & CDpbs && !(info.flags & CDbootnoemu)) usage(); if(mk9660 && (fix || now || maxsize)) usage(); if(argc != 1) usage(); if(now == 0) now = (ulong)time(0); if(mk9660){ if((cd = createcd(argv[0], info)) == nil) sysfatal("cannot create '%s': %r", argv[0]); }else{ if((cd = opencd(argv[0], info)) == nil) sysfatal("cannot open '%s': %r", argv[0]); if(!(cd->flags & CDdump)) sysfatal("not a dump cd"); } /* create ISO9660/Plan 9 tree in memory */ memset(&dir, 0, sizeof dir); dir.name = atom(""); dir.uid = atom("sys"); dir.gid = atom("sys"); dir.uidno = 0; dir.gidno = 0; dir.mode = DMDIR | 0755; dir.mtime = now; dir.atime = now; dir.ctime = now; mkdirec(&iroot, &dir); iroot.srcfile = src; /* * Read new files into memory */ if(rdproto(proto, src, addprotofile, nil, &iroot) < 0) sysfatal("rdproto: %r"); if(mk9660){ dump = emalloc(sizeof *dump); dumpname = nil; }else{ /* * Read current dump tree and _conform.map. */ idumproot = readdumpdirs(cd, &dir, isostring); readdumpconform(cd); if(cd->flags & CDjoliet) jdumproot = readdumpdirs(cd, &dir, jolietstring); if(fix){ dumpname = nil; cd->nextblock = cd->nulldump+1; cd->nulldump = 0; Cwseek(cd, (vlong)cd->nextblock * Blocksize); goto Dofix; } dumpname = adddumpdir(&idumproot, now, &dir); /* note that we assume all names are conforming and thus sorted */ if(cd->flags & CDjoliet) { s = adddumpdir(&jdumproot, now, &dir); if(s != dumpname) sysfatal("dumpnames don't match %s %s", dumpname, s); } dump = dumpcd(cd, &idumproot); cd->nextblock = cd->nulldump+1; } /* * Write new files, starting where the dump tree was. * Must be done before creation of the Joliet tree so that * blocks and lengths are correct. */ if(dataoffset > (vlong)cd->nextblock * Blocksize) cd->nextblock = (dataoffset+Blocksize-1)/Blocksize; Cwseek(cd, (vlong)cd->nextblock * Blocksize); writefiles(dump, cd, &iroot); if(cd->bootimage){ findbootimage(cd, &iroot); if(cd->loader) findloader(cd, &iroot); Cupdatebootcat(cd); } /* create Joliet tree */ if(cd->flags & CDjoliet) copydirec(&jroot, &iroot); if(info.flags & CDconform) { checknames(&iroot, isbadiso9660); convertnames(&iroot, struprcpy); } else convertnames(&iroot, (void *) strcpy); // isoabstract = findconform(&iroot, abstract); // isobiblio = findconform(&iroot, biblio); // isonotice = findconform(&iroot, notice); dsort(&iroot, isocmp); if(cd->flags & CDjoliet) { // jabstract = findconform(&jroot, abstract); // jbiblio = findconform(&jroot, biblio); // jnotice = findconform(&jroot, notice); checknames(&jroot, isbadjoliet); convertnames(&jroot, (void *) strcpy); dsort(&jroot, jolietcmp); } /* * Write directories. */ writedirs(cd, &iroot, Cputisodir); if(cd->flags & CDjoliet) writedirs(cd, &jroot, Cputjolietdir); if(mk9660){ cblock = 0; clength = 0; newnull = 0; }else{ /* * Write incremental _conform.map block. */ wrconform(cd, cd->nconform, &cblock, &clength); /* jump here if we're just fixing up the cd */ Dofix: /* * Write null dump header block; everything after this will be * overwritten at the next dump. Because of this, it needs to be * reconstructable. We reconstruct the _conform.map and dump trees * from the header blocks in dump.c, and we reconstruct the path * tables by walking the cd. */ newnull = Cputdumpblock(cd); } if(info.flags & CDpbs) Cfillpbs(cd); /* * Write _conform.map. */ dir.mode = 0444; if(cd->flags & (CDconform|CDjoliet)) { if(!mk9660 && cd->nconform == 0){ block = cblock; length = clength; }else wrconform(cd, 0, &block, &length); if(mk9660) { idumproot = iroot; jdumproot = jroot; } if(length) { /* The ISO9660 name will get turned into uppercase when written. */ if((iconform = walkdirec(&idumproot, "_conform.map")) == nil) iconform = adddirec(&idumproot, "_conform.map", &dir); jconform = nil; if(cd->flags & CDjoliet) { if((jconform = walkdirec(&jdumproot, "_conform.map")) == nil) jconform = adddirec(&jdumproot, "_conform.map", &dir); } iconform->block = block; iconform->length = length; if(cd->flags & CDjoliet) { jconform->block = block; jconform->length = length; } } if(mk9660) { iroot = idumproot; jroot = jdumproot; } } if(mk9660){ /* * Patch in root directories. */ setroot(cd, cd->iso9660pvd, iroot.block, iroot.length); setvolsize(cd, cd->iso9660pvd, cd->nextblock); if(cd->flags & CDjoliet){ setroot(cd, cd->jolietsvd, jroot.block, jroot.length); setvolsize(cd, cd->jolietsvd, cd->nextblock); } }else{ /* * Write dump tree at end. We assume the name characters * are all conforming, so everything is already sorted properly. */ convertnames(&idumproot, (info.flags & CDconform) ? (void *) struprcpy : (void *) strcpy); if(cd->nulldump) { r = walkdirec(&idumproot, dumpname); assert(r != nil); copybutname(r, &iroot); } if(cd->flags & CDjoliet) { convertnames(&jdumproot, (void *) strcpy); if(cd->nulldump) { r = walkdirec(&jdumproot, dumpname); assert(r != nil); copybutname(r, &jroot); } } writedumpdirs(cd, &idumproot, Cputisodir); if(cd->flags & CDjoliet) writedumpdirs(cd, &jdumproot, Cputjolietdir); /* * Patch in new root directory entry. */ setroot(cd, cd->iso9660pvd, idumproot.block, idumproot.length); setvolsize(cd, cd->iso9660pvd, cd->nextblock); if(cd->flags & CDjoliet){ setroot(cd, cd->jolietsvd, jdumproot.block, jdumproot.length); setvolsize(cd, cd->jolietsvd, cd->nextblock); } } writepathtables(cd); if(!mk9660){ /* * If we've gotten too big, truncate back to what we started with, * fix up the cd, and exit with a non-zero status. */ Cwflush(cd); if(cd->nulldump && maxsize && Cwoffset(cd) > maxsize){ fprint(2, "too big; writing old tree back\n"); status = "cd too big; aborted"; rmdumpdir(&idumproot, dumpname); rmdumpdir(&jdumproot, dumpname); cd->nextblock = cd->nulldump+1; cd->nulldump = 0; Cwseek(cd, (vlong)cd->nextblock * Blocksize); goto Dofix; } /* * Write old null header block; this commits all our changes. */ if(cd->nulldump){ Cwseek(cd, (vlong)cd->nulldump * Blocksize); sprint(buf, "plan 9 dump cd\n"); sprint(buf+strlen(buf), "%s %lud %lud %lud %llud %lud %lud", dumpname, now, newnull, cblock, clength, iroot.block, iroot.length); if(cd->flags & CDjoliet) sprint(buf+strlen(buf), " %lud %lud", jroot.block, jroot.length); strcat(buf, "\n"); Cwrite(cd, buf, strlen(buf)); Cpadblock(cd); Cwflush(cd); } } fdtruncate(cd->fd, (vlong)cd->nextblock * Blocksize); exits(status); }
Fints mqpcheck_ASL(ASL *a, int co, fint **rowqp, Fint **colqp, real **delsqp) { typedef struct dispatch { struct dispatch *next; fint i, j, jend; } dispatch; ASL_fg *asl; Fint *colq, *colq1, nelq; Objrep *od, **pod; Static SS, *S; cde *c; cgrad *cg, **cgp, **cgq, *cq; dispatch *cd, *cd0, **cdisp, **cdisp0, *cdnext, **cdp; dyad *d, *d1, **q, **q1, **q2, **qe; expr *e; expr_n *en; fint *rowq, *rowq0, *rowq1, *s, *z; fint ftn, i, icol, j, ncom, nv, nz, nz1; int arrays, *cm, co0, pass, *vmi; ograd *og, *og1, *og2, **ogp; real *L, *U, *delsq, *delsq0, *delsq1, objadj, t, *x; term *T; ASL_CHECK(a, ASL_read_fg, "nqpcheck"); asl = (ASL_fg*)a; if (co >= n_obj || co < -n_con) return -3L; od = 0; co0 = co; if (co >= 0) { if ((pod = asl->i.Or) && (od = pod[co])) { co = od->ico; goto use_Cgrad; } else { c = obj_de + co; ogp = Ograd + co; cgp = 0; } } else { co = -1 - co; if ((cm = asl->i.cmap)) co = cm[co]; use_Cgrad: c = con_de + co; cgp = Cgrad; cgp += co; ogp = 0; } e = c->e; if (e->op == f_OPNUM) return 0; memset(S = &SS, 0, sizeof(Static)); SS.asl = asl; if (asl->i.vmap && !asl->i.vminv) /* keep vminv from being lost in free_blocks(S) below */ get_vminv_ASL(a); M1state1 = asl->i.Mbnext; M1state2 = asl->i.Mblast; nv = n_var; s_x = x = (double *)Malloc(nv*(sizeof(double)+2*sizeof(fint))); s_z = z = (fint *)(x + nv); s_s = s = z + nv; memset(s, 0, nv*sizeof(fint)); ftn = Fortran; SS.nvinc = nv - asl->i.n_var0 + asl->i.nsufext[ASL_Sufkind_var]; delsq = delsq0 = delsq1 = 0; /* silence buggy "not-initialized" warning */ colq = colq1 = 0; /* ditto */ rowq = rowq0 = rowq1 = 0; /* ditto */ cd0 = 0; /* ditto */ cdisp = cdisp0 = 0; /* ditto */ if ((ncom = ncom0 + ncom1)) { cterms = (term **)Malloc(ncom*sizeof(term*)); memset(cterms, 0, ncom*sizeof(term*)); } arrays = 1; if (rowqp) *rowqp = 0; else arrays = 0; if (colqp) *colqp = 0; else arrays = 0; if (delsqp) *delsqp = 0; else arrays = 0; zerodiv = 0; if (!(T = ewalk(S, e)) || zerodiv) { free_blocks(S); free(x); return T ? -2L : -1L; } if (cterms) cterm_free(S, cterms + ncom); if (od) { cgq = &od->cg; for(i = 0, cg = *cgp; cg; cg = cg->next) { if (cg->coef != 0.) ++i; } if (i) { cq = Malloc(i*sizeof(cgrad)); for(cg = *cgp; cg; cg = cg->next) { *cgq = cq; cgq = &cq->next; *cq = *cg; ++cq; } } *cgq = 0; } q = (dyad **)Malloc(nv*sizeof(dyad *)); qe = q + nv; objadj = dsort(S, T, (ograd **)q, cgp, ogp, arrays); nelq = nz = nz1 = 0; /* In pass 0, we the count nonzeros in the lower triangle. */ /* In pass 1, we compute the lower triangle and use column dispatch */ /* (via the cdisp array) to copy the strict lower triangle to the */ /* strict upper triangle. This ensures symmetry. */ for(pass = 0; pass < 2; pass++) { if (pass) { nelq += nelq - nz1; if (!nelq || !arrays) break; free(q); delsq1 = delsq = (double *)Malloc(nelq*sizeof(real)); rowq1 = rowq = (fint *)Malloc(nelq*sizeof(fint)); colq1 = colq = (Fint *)Malloc((nv+2)*sizeof(Fint)); nelq = ftn; delsq0 = delsq - ftn; rowq0 = rowq - ftn; q = (dyad **)Malloc(nv*(sizeof(dyad*) + sizeof(dispatch *) + sizeof(dispatch))); qe = q + nv; cdisp = (dispatch**) qe; cdisp0 = cdisp - ftn; memset(cdisp, 0, nv*sizeof(dispatch*)); cd0 = (dispatch *)(cdisp + nv); } memset(q, 0, nv*sizeof(dyad *)); for(d = T->Q; d; d = d->next) { og = d->Rq; og1 = d->Lq; i = og->varno; while(og1 && og1->varno < i) og1 = og1->next; if (og1) { q1 = q + i; *q1 = new_dyad(S, *q1, og, og1, 0); } og1 = d->Lq; i = og1->varno; while(og && og->varno < i) og = og->next; if (og) { q1 = q + i; *q1 = new_dyad(S, *q1, og1, og, 0); } } vmi = asl->i.vmap ? get_vminv_ASL((ASL*)asl) : 0; for(icol = 0, q1 = q; q1 < qe; ++icol, ++q1) { if (pass) { *colq++ = nelq; for(cd = cdisp[icol]; cd; cd = cdnext) { cdnext = cd->next; s[i = cd->i]++; x[z[nz++] = i] = delsq0[cd->j++]; if (cd->j < cd->jend) { cdp = cdisp0 + rowq0[cd->j]; cd->next = *cdp; *cdp = cd; } } } if ((d = *q1)) do { og = d->Lq; og1 = d->Rq; t = og->coef; for(; og1; og1 = og1->next) { if (!s[i = og1->varno]++) x[z[nz++] = i] = t*og1->coef; else x[i] += t*og1->coef; } if ((og1 = og->next)) { og2 = d->Rq; while (og2->varno < og1->varno) if (!(og2 = og2->next)) { while((og1 = og->next)) og = og1; break; } d->Rq = og2; } d1 = d->next; if ((og = og->next)) { i = og->varno; if (pass) { og1 = d->Rq; while(og1->varno < i) if (!(og1 = og1->next)) goto d_del; d->Rq = og1; } d->Lq = og; q2 = q + i; d->next = *q2; *q2 = d; } else { d_del: free_dyad(S, d); } } while((d = d1)); if (nz) { if (pass) { if (nz > 1) qsortv(z, nz, sizeof(fint), lcmp, NULL); for(i = nz1 = 0; i < nz; i++) { if ((t = x[j = z[i]])) { *delsq++ = t; if (vmi) j = vmi[j]; *rowq++ = j + ftn; nelq++; z[nz1++] = j; } s[j] = 0; } for(i = 0; i < nz1; i++) if ((j = z[i]) > icol && x[j]) { cd0->i = icol; cd0->j = colq[-1] + i; cd0->jend = nelq; cdp = cdisp + j; cd0->next = *cdp; *cdp = cd0++; break; } nz = 0; } else { while(nz > 0) { s[i = z[--nz]] = 0; if (x[i]) { ++nelq; if (i == icol) ++nz1; } } } } } } free(q); free_blocks(S); free(x); if (od && od->cg) M1record(od->cg); if (nelq) { if (arrays) { /* allow one more for obj. adjustment */ *colq = colq[1] = nelq; *rowqp = rowq1; *colqp = colq1; *delsqp = delsq1; } nelq -= ftn; } if (arrays) { en = (expr_n *)mem(sizeof(expr_n)); en->op = f_OPNUM_ASL; if (od) { od->opify = qp_opify_ASL; if ((t = od->c12) != 1.) for(i = 0; i < nelq; ++i) delsq1[i] *= t; objadj = t*objadj + od->c0a; for(i = 0, cg = *cgp; cg; cg = cg->next) ++i; ogp = Ograd + co0; og2 = i ? (ograd*)M1alloc(i*sizeof(ograd)) : 0; for(cg = *cgp; cg; cg = cg->next) { *ogp = og = og2++; ogp = &og->next; og->varno = cg->varno; og->coef = t*cg->coef; } *ogp = 0; c = obj_de + co0; } else if (cgp && objadj != 0.) { if (Urhsx) { L = LUrhs + co; U = Urhsx + co; } else { L = LUrhs + 2*co; U = L + 1; } if (*L > negInfinity) *L -= objadj; if (*U < Infinity) *U -= objadj; objadj = 0; } en->v = objadj; c->e = (expr *)en; } return nelq; }
/* FBP_voc algorithm */ void FBP_voc(double ALPHA, double BETA, int W, int J, int D, int NN, int OUTPUT, int nzmax, double *sr, mwIndex *ir, mwIndex *jc, double *phi, double *theta, double *mu, double threshold, int startcond) { int wi, di, i, j, k, topic, iter, rp, temp, ii; int *order, *indx_r; double mutot, totprob, xi, xitot, perp, trap = 1e-6; double JALPHA = (double) (J*ALPHA), WBETA = (double) (W*BETA); double *phitot, *thetad, *r, *munew; phitot = dvec(J); thetad = dvec(D); order = ivec(W); indx_r = ivec(J*W); munew = dvec(J); r = dvec(J*W); /* phitot */ for (wi=0; wi<W; wi++) { for (j=0; j<J; j++) { phitot[j] += phi[wi*J + j]; } } if (startcond == 1) { /* start from previously saved state */ for (wi=0; wi<W; wi++) { for (i=jc[wi]; i<jc[wi + 1]; i++) { di = (int) ir[i]; xi = sr[i]; xitot += xi; thetad[di] += xi; for (j=0; j<J; j++) { theta[di*J + j] += xi*mu[i*J + j]; // increment theta count matrix } } } } if (startcond == 0) { /* random initialization */ for (wi=0; wi<W; wi++) { for (i=jc[wi]; i<jc[wi + 1]; i++) { di = (int) ir[i]; xi = sr[i]; thetad[di] += xi; xitot += xi; // pick a random topic 0..J-1 topic = (int) (J*drand()); mu[i*J + topic] = 1.0; // assign this word token to this topic theta[di*J + topic] += xi; // increment theta count matrix } } } /* Determine random order */ for (i=0; i<W; i++) order[i] = i; // fill with increasing series for (i=0; i<(W-1); i++) { // pick a random integer between i and D rp = i + (int) ((W-i)*drand()); // switch contents on position i and position rp temp = order[rp]; order[rp] = order[i]; order[i] = temp; } for (iter=0; iter<NN; iter++) { if (OUTPUT >= 1) { if (((iter % 10)==0) && (iter != 0)) { /* calculate perplexity */ perp = 0.0; for (wi=0; wi<W; wi++) { for (i=jc[wi]; i<jc[wi + 1]; i++) { di = (int) ir[i]; xi = sr[i]; mutot = 0.0; for (j=0; j<J; j++) { mutot += (phi[wi*J + j] + BETA)/(phitot[j] + WBETA)* (theta[di*J + j] + ALPHA)/(thetad[di] + JALPHA); } perp -= (log(mutot)*xi); } } mexPrintf("\tIteration %d of %d:\t%f\n", iter, NN, exp(perp/xitot)); if ((iter % 10)==0) mexEvalString("drawnow;"); } } /* passing message mu */ /* iteration 0 */ if (iter == 0) { for (ii=0; ii<W; ii++) { wi = (int) order[ii]; for (i=jc[wi]; i<jc[wi + 1]; i++) { di = (int) ir[i]; xi = sr[i]; mutot = 0; for (j=0; j<J; j++) { theta[di*J + j] -= xi*mu[i*J + j]; munew[j] = (phi[wi*J + j] + BETA)/(phitot[j] + WBETA)*(theta[di*J + j] + ALPHA); mutot += munew[j]; } for (j=0; j<J; j++) { munew[j] /= mutot; r[wi*J + j] += xi*fabs(munew[j] - mu[i*J + j]); mu[i*J + j] = munew[j]; theta[di*J + j] += xi*mu[i*J + j]; } } dsort(J, r + wi*J, -1, indx_r + wi*J); } } else { /* iteration > 0 */ for (ii=0; ii<W; ii++) { wi = (int) order[ii]; for (j=0; j < (int) (J*threshold); j++) { k = (int) indx_r[wi*J + j]; //if (r[di*J + k]*J < trap) break; r[wi*J + k] = 0.0; } for (i=jc[wi]; i<jc[wi + 1]; i++) { di = (int) ir[i]; xi = sr[i]; mutot = 0.0; totprob = 0.0; for (j=0; j < (int) (J*threshold); j++) { k = (int) indx_r[wi*J + j]; theta[di*J + k] -= xi*mu[i*J + k]; totprob += mu[i*J + k]; munew[k] = (phi[wi*J + k] + BETA)/(phitot[k] + WBETA)*(theta[di*J + k] + ALPHA); mutot += munew[k]; } for (j=0; j < (int) (J*threshold); j++) { k = (int) indx_r[wi*J + j]; munew[k] /= mutot; munew[k] *= totprob; r[wi*J + k] += xi*fabs(munew[k] - mu[i*J + k]); mu[i*J + k] = munew[k]; theta[di*J + k] += xi*mu[i*J + k]; } } insertionsort(J, r + wi*J, indx_r + wi*J); } } } }
ssize_t mqpcheckv_ASL(ASL *a, int co, QPinfo **QPIp, void **vp) { ASL_fg *asl; AVL_Node *NQ, *NQ0; AVL_Tree *AQ; Memblock *mb; QPinfo *qpi; Objrep *od, **pod; Static *S; cde *c; cgrad *cg, **cgp, **cgq, *cq; dispatch *cd, *cd0, **cdisp, **cdisp0, *cdnext, **cdp; dyad *d, *d1, **q, **q1, **q2; expr *e; expr_n *en; int *cm, *colno, *qm, *rowq, *rowq0, *rowq1, *s, *vmi, *w, *z; int arrays, co0, ftn, i, icol, icolf, j, ncol, ncom, nv, nva, nz, nz1, pass; ograd *og, *og1, *og2, **ogp; real *L, *U, *delsq, *delsq0, *delsq1, objadj, t, *x; size_t *colq, *colq1, nelq, nelq0; term *T; ASL_CHECK(a, ASL_read_fg, "nqpcheck"); asl = (ASL_fg*)a; if (co >= n_obj || co < -n_con) return -3L; colno = 0; od = 0; co0 = co; if (co >= 0) { if ((pod = asl->i.Or) && (od = pod[co])) { co = od->ico; goto use_Cgrad; } else { c = obj_de + co; ogp = Ograd + co; cgp = 0; } } else { co = -1 - co; if ((cm = asl->i.cmap)) co = cm[co]; use_Cgrad: c = con_de + co; cgp = Cgrad; cgp += co; ogp = 0; } e = c->e; if (e->op == f_OPNUM) return 0; if (asl->i.vmap && !asl->i.vminv) get_vminv_ASL(a); nv = n_var; ncom = ncom0 + ncom1; if (!(S = *(Static**)vp)) { i = asl->i.n_var0 + asl->i.nsufext[0]; if ((nva = nv) < i) nva = i; x = (double *)Malloc(nva*(sizeof(double) +sizeof(dyad*) +sizeof(ograd*) +sizeof(dispatch*) +sizeof(dispatch) +3*sizeof(int)) + sizeof(Memblock) + sizeof(Static)); mb = (Memblock*)(x + nva); mb->prev = mb->next = 0; S = (Static*)(mb + 1); *vp = (void*)S; memset(S, 0, sizeof(Static)); S->mb0 = S->mblast = mb; s_x = x; S->asl = asl; s_q = q = (dyad**)(S+1); S->oq = (ograd**)(q + nva); S->cdisp = cdisp = (dispatch**)(S->oq + nva); S->cd0 = cd0 = (dispatch*)(cdisp + nva); s_z = z = (int*)(cd0 + nva); s_s = s = z + nva; S->w = (int*)(s + nva); memset(s, 0, nva*sizeof(int)); memset(cdisp, 0, nva*sizeof(dispatch*)); memset(q, 0, nva*sizeof(dyad *)); memset(S->w, 0, nva*sizeof(int)); if (ncom) { cterms = (term **)Malloc(ncom*(sizeof(term*)+sizeof(int))); memset(cterms, 0, ncom*sizeof(term*)); S->zct = (int*)(cterms + ncom); } S->AQ = AVL_Tree_alloc2(0, vcomp, mymalloc, 0); } else { q = s_q; x = s_x; z = s_z; s = s_s; cdisp = S->cdisp; cd0 = S->cd0; } S->mb = mb = S->mb0; S->v = &mb->x[0]; S->ve = &mb->x[Memblock_gulp]; w = S->w; freedyad = 0; freeog = 0; freeterm = 0; AQ = S->AQ; ftn = Fortran; cdisp0 = cdisp - ftn; S->nvinc = nv - asl->i.n_var0 + asl->i.nsufext[ASL_Sufkind_var]; delsq = delsq0 = delsq1 = 0; /* silence buggy "not-initialized" warning */ colq = colq1 = 0; /* ditto */ rowq = rowq0 = rowq1 = 0; /* ditto */ arrays = 0; if (QPIp) { *QPIp = 0; arrays = 1; } zerodiv = 0; if (!(T = ewalk(S, e)) || zerodiv) return T ? -2L : -1L; if (S->nzct) cterm_free(S); if (od) { cgq = &od->cg; for(i = 0, cg = *cgp; cg; cg = cg->next) { if (cg->coef != 0.) ++i; } if (i) { cq = M1alloc(i*sizeof(cgrad)); for(cg = *cgp; cg; cg = cg->next) { *cgq = cq; cgq = &cq->next; *cq = *cg; ++cq; } } *cgq = 0; } objadj = dsort(S, T, S->oq, cgp, ogp, arrays); icolf = nelq = ncol = nz = nz1 = 0; qpi = 0; /* In pass 0, we the count nonzeros in the lower triangle. */ /* In pass 1, we compute the lower triangle and use column dispatch */ /* (via the cdisp array) to copy the strict lower triangle to the */ /* strict upper triangle. This ensures symmetry. */ for(pass = 0; pass < 2; pass++) { if (pass) { if (!nelq) break; nelq += nelq - nz1; /* nz1 = number of diagonal elements */ if (!arrays) { for(qm = (int*)AVL_first(AQ, &NQ); qm; ) { *qm = 0; NQ0 = NQ; qm = (int*) AVL_next(&NQ); AVL_delnode(AQ, &NQ0); } break; } qpi = *QPIp = (QPinfo*)Malloc(sizeof(QPinfo) + nelq*(sizeof(real) + sizeof(int)) + ncol*sizeof(int) + (ncol + 1)*sizeof(size_t)); qpi->delsq = delsq = delsq1 = (double *)(qpi+1); qpi->colbeg = colq = (size_t *)(delsq + nelq); qpi->rowno = rowq = (int *)(colq + ncol + 1); qpi->colno = colno = rowq + nelq; qpi->nc = ncol; qpi->nz = nelq; nelq = ftn; delsq0 = delsq - ftn; rowq0 = rowq - ftn; } for(d = T->Q; d; d = d->next) { og = d->Rq; og1 = d->Lq; i = og->varno; while(og1 && og1->varno < i) og1 = og1->next; if (og1) { q1 = q + i; if (!w[i]) { w[i] = 1; AVL_vinsert(AQ, 0, (Element*)&w[i], 0); } *q1 = new_dyad(S, *q1, og, og1, 0); } og1 = d->Lq; i = og1->varno; while(og && og->varno < i) og = og->next; if (og) { q1 = q + i; if (!w[i]) { w[i] = 1; AVL_vinsert(AQ, 0, (Element*)&w[i], 0); } *q1 = new_dyad(S, *q1, og1, og, 0); } } vmi = asl->i.vmap ? get_vminv_ASL((ASL*)asl) : 0; for(qm = (int*)AVL_first(AQ, &NQ); qm; ) { NQ0 = NQ; icol = qm - w; nelq0 = nelq; if (pass) { *qm = 0; icolf = icol + ftn; if ((cd = cdisp[icol])) { cdisp[icol] = 0; do { cdnext = cd->next; s[i = cd->i]++; x[z[nz++] = i] = delsq0[cd->j++]; if (cd->j < cd->jend) { cdp = cdisp0 + rowq0[cd->j]; cd->next = *cdp; *cdp = cd; } } while((cd = cdnext)); } } if ((d = q[icol])) { q[icol] = 0; do { og = d->Lq; og1 = d->Rq; t = og->coef; for(; og1; og1 = og1->next) { if (!s[i = og1->varno]++) x[z[nz++] = i] = t*og1->coef; else x[i] += t*og1->coef; } if ((og1 = og->next)) { og2 = d->Rq; while (og2->varno < og1->varno) if (!(og2 = og2->next)) { while((og1 = og->next)) og = og1; goto get_d1; } d->Rq = og2; } get_d1: d1 = d->next; if ((og = og->next)) { i = og->varno; if (pass) { og1 = d->Rq; while(og1->varno < i) if (!(og1 = og1->next)) goto d_del; d->Rq = og1; } d->Lq = og; q2 = q + i; if (!w[i]) { w[i] = 1; AVL_vinsert(AQ, 0, (Element*)&w[i], 0); } d->next = *q2; *q2 = d; } else { d_del: free_dyad(S, d); } } while((d = d1)); } if (nz) { if (pass) { if (nz > 1) qsortv(z, nz, sizeof(int), lcmp, NULL); for(i = nz1 = 0; i < nz; i++) { if ((t = x[j = z[i]])) { *delsq++ = t; if (vmi) j = vmi[j]; *rowq++ = j + ftn; nelq++; z[nz1++] = j; } s[j] = 0; } if (nelq > nelq0) { *colq++ = nelq0; *colno++ = icolf; } for(i = 0; i < nz1; i++) if ((j = z[i]) > icol) { cd0->i = icol; cd0->j = nelq0 + i; cd0->jend = nelq; cdp = cdisp + j; cd0->next = *cdp; *cdp = cd0++; break; } nz = 0; } else { while(nz > 0) { s[i = z[--nz]] = 0; if (x[i]) { ++nelq; if (i == icol) ++nz1; else { if (!w[i]) AVL_vinsert(AQ, 0, (Element*)&w[i], 0); w[i] = 2; } } } if (nelq > nelq0 || w[icol] == 2) ++ncol; } } else if (!pass && w[icol] == 2) ++ncol; qm = (int*) AVL_next(&NQ); if (pass) AVL_delnode(AQ, &NQ0); } } if (colq) *colq = nelq; if (arrays) { if (nelq) nelq -= ftn; en = (expr_n *)mem(sizeof(expr_n)); en->op = f_OPNUM_ASL; if (od) { od->opify = qp_opify_ASL; if ((t = od->c12) != 1.) for(i = 0; i < nelq; ++i) delsq1[i] *= t; objadj = t*objadj + od->c0a; for(i = 0, cg = *cgp; cg; cg = cg->next) ++i; ogp = Ograd + co0; og2 = i ? (ograd*)M1alloc(i*sizeof(ograd)) : 0; for(cg = *cgp; cg; cg = cg->next) { *ogp = og = og2++; ogp = &og->next; og->varno = cg->varno; og->coef = t*cg->coef; } *ogp = 0; c = obj_de + co0; } else if (cgp && objadj != 0.) { if (Urhsx) { L = LUrhs + co; U = Urhsx + co; } else { L = LUrhs + 2*co; U = L + 1; } if (*L > negInfinity) *L -= objadj; if (*U < Infinity) *U -= objadj; objadj = 0.; } en->v = objadj; c->e = (expr *)en; } return nelq; }