Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
// 递归,感觉还是没有很好掌握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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
Arquivo: tree.c Projeto: Arafatk/mlpy
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);

}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
Arquivo: nqpcheck.c Projeto: gidden/mp
 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);
			}
		}
	}
}
Exemplo n.º 9
0
 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;
	}