Exemplo n.º 1
0
//////////////////////////////////////////////////
// resizable buf
//////////////////////////////////////////////////
void sBuf_init(sBuf* self)
{
    self->mBuf = (char*)MMALLOC(sizeof(char)*64);
    self->mSize = 64;
    self->mLen = 0;
    *(self->mBuf) = '\0';
}
Exemplo n.º 2
0
static char *mqreply_mmalloc(char *sbuffer, int bsz, int pid, char *req_sz)  {
  size_t msz;
  size_t *ptr;

  if (req_sz) {
    msz = atol(req_sz);
    ptr = MMALLOC(msz);
  } else { ptr = (void *)NULL; }

  snprintf(sbuffer, bsz, "0x%lx", (long)ptr);
  printf("0x%lx = mmalloc(%lu)\n", (long)ptr, msz);
  mqrc_reply(sbuffer, pid);
  return(NULL);
}
Exemplo n.º 3
0
void	frame_setname_ext(framestruc *fr, char *nm1, char *nm2, char *ext) {
	char	*buf;
	
	if (nm1 || nm2) {
		buf = MMALLOC(((nm1?strlen(nm1):0)+(nm2?strlen(nm2):0)+3)*sizeof(buf[0]));
		if (nm1)  strcpy(buf,nm1);  else  buf[0] = 0;
		if (nm2)  strcat(buf,nm2);
		if (FRNAME(fr))  FREE(FRNAME(fr));
		FRNAME(fr) = buf;
	}
	if (ext) {
		if (FREXTENS(fr))  FREE(FREXTENS(fr));
		FREXTENS(fr) = MSTRDUP(ext);
	}
}
Exemplo n.º 4
0
optionstruc*	new_comoption_ext(char *nm, int oc, int cont) {
	optionstruc	*op;
	int		i;
	
	if (!nm)  {PROGERROR("The option name must be given!");}
	if (oc<0 || oc>1)  {PROGERROR("Invalid option/command flag %d!",oc);}
	
	op = MMALLOC(sizeof(op[0]));		/* creates the option with its name */
	OPTNAME(op) = (nm?MSTRDUP(nm):NULL);
	OPTCOM(op) = oc;
	OPTCONTINUED(op) = (cont>0? cont:0);	/* a "continued" option flag - for continuing a long list of option values */
	OPTINDEX(op) = -1;
	OPTPARSG(op) = 0;  pfield_setzeroexp(&OPTPAREX(op));
	
	for (i=0; i<MAXOPTPARAMS; i++) {	/* nulls the option parameters (values) */
		OPTPARAM(op,i) = NULL;
		OPTNPARAM(op,i) = OPTNOPARAM;
	}
	OPTPARNUM(op) = 0;
	fr_aloptions++;
	return op;
}
Exemplo n.º 5
0
int	ematrix_printmore_flats(ematrix *rf, int rk, int wh) {
	static long	*save=NULL, sl=0,si;
	ematrix		*rrf;
	long		l;
	int		i,j,k, r = 1;
	
	if (wh!=1) if (!save || !sl)  {PROGERROR("must be initialized first!"); return 0;}
	if (wh==1) {
		sl = 1000;  save = MMALLOC(sl*sizeof(save[0]));
	} else if (wh==-1) {
		FREE(save);  save = NULL;  si = sl = 0;
	} else {
		if (si>=sl-4)  save = MREALLOC(save,(sl*=2)*sizeof(save[0]));
		rrf = REFMAT(rf);
			/**
			 * The previously allowed flats are stored as set bitmaps to the list
			 * save, and the new flat given by rf is compared against all saved
			 * ones bit by bit.
			 * If it equals, or it is just by the rank difference bigger, to saved
			 * one, the new flat is rejected (and not stored).
			**/
		for (i=0,l=0; i<ROWSM(rf)+COLSM(rf); i++)
			l |= 1l<<(i<ROWSM(rf)? GETREFMROW(rf,i):
					GETREFMCOL(rf,i-ROWSM(rf))+ROWSM(rrf));
		for (i=0; i<si/2 && r>=0; i++) {
			for (j=k=0; j<ROWSM(rrf)+COLSM(rrf); j++)
				k += ((l&(1l<<j))!=(save[2*i]&(1l<<j)));
			if ((k==1 && rk==save[2*i+1]) || (k==0 && rk!=save[2*i+1]))
				{PROGERROR("something wrong with the saved flats... (k=%d, %d~%ld)",k,rk,save[2*i+1]);}
			if (k<=rk-save[2*i+1])  r = -1;
		}
		if (r>=0) {
			save[si] = l;  save[si+1] = rk;
			si += 2;
		}
	}
	return r;
}
Exemplo n.º 6
0
framestruc*	new_frame(framestruc *parent) {
	framestruc	*fr;
	
	fr = MMALLOC(sizeof(fr[0]));
	FRMAGICSET(fr);		/* (a magic number is used to test correct access to frames) */
	FRNAME(fr) = FREXTENS(fr) = FRCOMMENT(fr) = NULL;
	FRSONS(fr) = NULL;
	FRNUMSONS(fr) = 0;
	FRPARENT(fr) = NULL;
	frame_setson(fr,parent);	/* adds to the parent's list of sons */
	
	FRMATRIX(fr) = NULL;	/* clears all important values in this frame */
	FRPFINDEX(fr) = FRPFINDEX_SAVE(fr) = -1;
	FRMATRIXROWS(fr) = FRMATRIXCOLS(fr) = 0;
	FRVALUESIG(fr) = 0;  pfield_setzeroexp(&FRVALUEEXP(fr));
	FRNUMBER(fr) = 0;
	FROPTIONS(fr) = NULL;
	FRCOMMANDS(fr) = NULL;
	FRLASTOPTI(fr) = -1;	/* the "index" of the last added option */
	FRDELMARK(fr) = FRTREEMARK(fr) = 0;
	fr_alframes++;
	return fr;
}
Exemplo n.º 7
0
int	grepr_generate_ext(int ch, ematrix *eg, int xpfd, ematrix ***lout) {
	ematrix		*ee,*re,**rel=NULL, **elo=NULL,**x, ***epl=NULL;
	int		i,k,p,br, ro,co, step, xp=-1, ret=0;
	char		*s, buf[100];
	
	if (!eg)  {PROGERROR("the matrix eg must be given!"); return -1;}
	ro = ROWSM(eg);  co = COLSM(eg);
	if (ro<=0 || co<=0)  {PROGERROR("the matrix eg has wrong size!"); return -1;}
	if (lout?*lout:0)  {PROGERROR("the list lout must be given empty (null)"); return -1;}
	xp = pfield_curindex();
	s = pfield_curname();
	if (xpfd>=0) pfield_switchto_fast(xpfd);
	DEBUG(CURDLEV-1,"Generating representation(s) of a %s matrix %p[%.12s] (%dx%d) over %s...\n",
			pfield_curname(),eg,EMNAME(eg)?EMNAME(eg):"",ro,co,s);
	EMATDEBUG(CURDLEV+0,eg,"\t:\t");
	if (xpfd>=0 && xp>=0) pfield_switchto_fast(xp);
			/**
			 * We allocate working data, and we prepare the submatrices rel[]
			 * of the matrix eg which display how the generated representation
			 * grows line by line (total step=ro steps).
			 * We should find a more clever order of added lines for faster
			 * computation...
			**/
	step = (ro>co? ro: co);
	rel = MMALLOC((step+2)*sizeof(rel[0]));
	if (step==ro)  re = ematrix_refer(eg,-1,-1,0,co);
	else  re = ematrix_refer(eg,0,ro,-1,-1);
	for (i=0; i<step; i++) {
		if (step==ro)  ematrix_refadd_row(re,i);
		else  ematrix_refadd_col(re,i);
		rel[i] = ematrix_copy(re);
	}
	dispose_ematrix(re);
	epl = MMALLOC((step+2)*sizeof(epl[0]));
	for (i=0; i<step+1; i++)  epl[i] = NULL;
	
			/**
			 * Here is the main backtracking code of this function.
			 * At each level k (0..step-1), we keep in epl[k] the list of
			 * partial matrices generated at this level (matching rel[k]);
			 * and we collect the full representations found in elo.
			 * At each step, we call grepr_addline() to add one more line
			 * (row) to the previous partial matrices.
			**/
	k = br = 0;
	while (k>=0) {
		if (k>=step)  {PROGERROR("cannot get here!");}
		if (alist_getlength(epl[k])>0)  {PROGERROR("cannot get nonempty list here!");}
		DEBUG(CURDLEV+2,"%*s calling GREPR at k=%d, left %d\n",2*k,"",k,(k>0?alist_getlength_part(epl[k-1]):-1));
		if (k>0) {
			ee = *epl[k-1];
			if (!ee || br) {
				dispose_alist_mats(epl[k-1]);  epl[k-1] = NULL;
				if (--k<=0)  break;  else  continue;
			} else  epl[k-1]++;
		} else  ee = NULL;
		p = grepr_addline(ee,rel[k],-1,xpfd,epl+k);
		if (p<=0)  continue;
			/**
			 * When some partial representations are generated in grepr_addline(),
			 * we store them for use in the next step; or in the result list elo.
			 * We are finished with the first representation(s) if ch<=1.
			**/
		if (k<step-1) { ++k;  continue; }
		ret += p;
		if (ch<=1)  br = 1;
		DEBUG(CURDLEV,"Found %d (%d tot) representations of %p[%.12s] (%dx%d) over %s here.\n",
				alist_getlength(epl[k]),ret,eg,EMNAME(eg)?EMNAME(eg):"",ro,co,pfield_curname());
		EMATDEBUGS(CURDLEV+2,*epl[k],"\t\t.=.\t");
		elo = alist_applist(elo,epl[k]);
		epl[k]= NULL;
	}
	
#ifndef FASTPROG	
	if (xp!=pfield_curindex())  {PROGERROR("The current pfield has changed!");}
	if (ret>0 && alist_getlength(elo)<=0)  {PROGERROR("Where is the generated representation?!");}
	DEBUG(CURDLEV-1-(ret>0),"Generated total %d representations of a matrix %p[%.12s] (%dx%d) over %s...\n",
				ret,eg,EMNAME(eg)?EMNAME(eg):"",ro,co,pfield_curname());
	if (IFRANDDEBUGLESS(222) && ch>=0) {
		if (xpfd>=0) pfield_switchto_fast(xpfd);
		ee = ematrix_copydual(eg);
		for (i=0; i<4 && i<ro && i<co; i++)
			if (SIGNM(ee,i,i)!=0)  ematrix_pivot(ee,i,i);
		if (xpfd>=0 && xp>=0) pfield_switchto_fast(xp);
		p = grepr_generate_ext(-1,ee,xpfd,NULL);
		if ((p>0)!=(ret>0))  {PROGERROR("Wrong result of a recursive call! %d!=%d",p,ret);}
	}
#endif
	if (ch==1 || ch>=3)  OUTPUT("There %s %s-representation of the matroid [%.18s] (%dx%d).\n",
				(ret>0?"+IS+ a":"is -NO-"),pfield_curname(),EMNAME(eg)?EMNAME(eg):"",ro,co);
	if (ret>0 && ch>=3)  OUTPUT(" Generated total %d representations of the matroid [%.18s] (%dx%d) over %s.\n",
				ret,EMNAME(eg)?EMNAME(eg):"",ro,co,pfield_curname());
	if (ret>0 && ch>=4)  for (x=elo; x?*x:0; x++) {
		snprintf(buf,80,"%sr%d\t",printoutpref,(int)(x-elo)+1);
		EMATOUTPUTS(*x,buf);
	}
	if (rel)  FREE(rel);  if (epl)  FREE(epl);
	if (lout)  *lout = (*lout? alist_applist(*lout,elo): elo);
	else if (elo)  dispose_alist_mats(elo);
	return ret;
}
Exemplo n.º 8
0
int read_fasta_fastq(struct read_info** ri,struct parameters* param,FILE *file) 
{
	int park_pos = -1;
	char line[MAX_LINE];
	int i;//,j;
	int seq_p = 0;
	int set = 0;
	int len = 0;
	int size = 0;
	
	ri = clear_read_info(ri, param->num_query);
	while(fgets(line, MAX_LINE, file)){
		if((line[0] == '@' && !set)|| (line[0] == '>' && !set)){
			//set sequence length of previous read
			
			//check if there is still space....
			//if(param->num_query == size){
			//	fseek (file , -  strlen(line) , SEEK_CUR);
			//	return size;
			//}
			park_pos++;
			len = 0;
			seq_p = 1;
			for(i = 1;i < MAX_LINE;i++){
				len++;
				if(iscntrl((int)line[i])){
					break;
				}
				
			}
			
			//ri[park_pos]->hits[0] = 0;
			//ri[park_pos]->strand[0] = 0;
			MMALLOC(ri[park_pos]->name,sizeof(unsigned char)* (len+1));
			for(i = 1;i < MAX_LINE;i++){
				
				if(iscntrl((int)line[i])){
					ri[park_pos]->name[i-1] = 0;
					break;
				}
				if(isspace((int)line[i])){
					ri[park_pos]->name[i-1] = ';';
				}
				
				ri[park_pos]->name[i-1] = line[i];
			}
			//fprintf(stderr,"LEN:%d	%s\n",len,ri[park_pos]->name);
			
			set = 1;
			size++;
			//get ready to read quality if present  
		}else if(line[0] == '+' && !set){
			seq_p = 0;
			set = 1;
			//reading sequence or quality  
		}else{	
			if(set){
				if(seq_p){
					len = 0;
					for(i = 0;i < MAX_LINE;i++){
						len++;
						if(iscntrl((int)line[i])){
							break;
						}
					}
					//fprintf(stderr,"SEQ LEN:%d	%s\n",len,line);
					MMALLOC(ri[park_pos]->seq,sizeof(unsigned char)* (len+1));
					
					MMALLOC(ri[park_pos]->labels, sizeof(unsigned char)* (len+1));
					
					for(i = 0;i < MAX_LINE;i++){
						if(iscntrl((int)line[i])){
							ri[park_pos]->seq[i] = 0;
							ri[park_pos]->labels[i] = 0;
							break;
						}
						ri[park_pos]->seq[i] = nuc_code[(int)line[i]];
						ri[park_pos]->labels[i] = 0;
					}
					ri[park_pos]->len = len-1;
				}else{
					len = 0;
					for(i = 0;i < MAX_LINE;i++){
						len++;
						if(iscntrl((int)line[i])){
							break;
						}
						
					}
					
					if(len-1 != ri[park_pos]->len ){
						sprintf(param->buffer,"ERROR: Length of sequence and base qualities differ!.\n");
						param->messages = append_message(param->messages, param->buffer);
						free_param(param);
						exit(EXIT_FAILURE);
					}
					
					//fprintf(stderr,"QUAL LEN:%d\n",len);
					MMALLOC(ri[park_pos]->qual,sizeof(unsigned char)* (len+1));
					for(i = 0;i < MAX_LINE;i++){
						if(iscntrl((int)line[i])){
							ri[park_pos]->qual[i] = 0;
							break;
						}
						ri[park_pos]->qual[i] = line[i];
					}
				}
			}
			set = 0;
		}
		if(param->num_query == size ){//here I know I am in the last entry AND filled the quality...
			if(!param->fasta && ri[park_pos]->qual){
				return size;
			}
			if(param->fasta && ri[park_pos]->seq){
			   
				return size;
			}
		}
	}
	return size;
}
Exemplo n.º 9
0
int read_sam_chunk(struct read_info** ri,struct parameters* param,FILE* file)
{
	//char line[MAX_LINE];
	int column = 0; 
	int i,j,g,tmp;
	
	int c = 0;
	
	ri = clear_read_info(ri, param->num_query);
	
	char *line = NULL;
	size_t len = 0;
	ssize_t read;
	while ((read = getline(&line, &len, file)) != -1) {
	//while(fgets(line, MAX_LINE, file)){
		if(line[0] != '@'){
			column = 1; //<QNAME>
			tmp = 0;
			for(j = 0;j < read;j++){
				tmp++;
				if(isspace((int)line[j])){
					break;
				}
			}
			
			MMALLOC(ri[c]->name,sizeof(unsigned char)* tmp);
			for(j = 0;j < read;j++){
				
				if(isspace((int)line[j])){
					ri[c]->name[j] = 0;
					break;
				}
				ri[c]->name[j] = line[j];
			}
			
			for(i = 0; i < read;i++){
				if(line[i] == '\n'){
					break;
				}
				if(isspace((int)line[i])){
					column++;
					switch(column){
						case 2: // <FLAG>
							tmp = atoi(line+i+1);
							ri[i]->strand = (tmp & 0x10);

							//WARNING - read should be reverse complemented if mapped to negative strand before tagdusting...
							
							/*tmp = atoi(line+i+1);
							ri[c]->strand[hit] = (tmp & 0x10);
							if(tmp == 4){
								ri[c]->hits[hit] = 0;
							}else{
								ri[c]->hits[hit] = 1;
							}
							hit++;*/
							
							break;
						case 3: // <RNAME> 
							
							break;
						case 4: // <POS>
							
							break;
						case 5: //  <MAPQ>
							
							ri[c]->mapq =  atof(line +i +1); 
							
							break;
						case 6: //  <CIGAR>
							tmp = 0;
							for(j = i+1;j < read;j++){
								tmp++;
								if(isspace((int)line[j])){
									break;
								}
							}
							
							ri[c]->cigar = malloc(sizeof(unsigned char)* tmp);
							g = 0;
							for(j = i+1;j < read;j++){
								if(isspace((int)line[j])){
									ri[c]->cigar[g] = 0;
									break;
								}
								ri[c]->cigar[g] = line[j];
								g++;
							}
							break;
						case 7: //  <MRNM>
							break;
						case 8: //  <MPOS>
							break;
						case 9: //  <ISIZE>
							break;
						case 10: // <SEQ>
							
							tmp = 0;
							for(j = i+1;j < read;j++){
								tmp++;
								if(isspace((int)line[j])){
									break;
								}
							}
							
							MMALLOC(ri[c]->seq,sizeof(unsigned char)* tmp);
							MMALLOC(ri[c]->labels,sizeof(unsigned char)* tmp);
							
							g = 0;
							for(j = i+1;j < read;j++){
								
								if(isspace((int)line[j])){
									ri[c]->seq[g] = 0;
									ri[c]->labels[g] = 0;
									break;
								}
								ri[c]->seq[g] = nuc_code[(int)line[j]];
								ri[c]->labels[g] = 0;

								g++;
							}
							
							ri[c]->len = g;
							break;
						case 11: // <QUAL>
							tmp = 0;
							for(j = i+1;j < read;j++){
								tmp++;
								if(isspace((int)line[j])){
									break;
								}
							}
							g= 0;
							MMALLOC(ri[c]->qual,sizeof(unsigned char)* tmp);
							for(j = i+1;j < read;j++){
								
								if(isspace((int)line[j])){
									ri[c]->qual[g] = 0;
									break;
								}
								ri[c]->qual[g] = line[j];
								g++;
							}
							break;
						default: 
							
									
							i = (int) read;
							break;
					}				}

			}
			tmp = byg_end("NM:i:", line  );
			if(tmp){
				ri[c]->errors = atoi(line+tmp);
				//if(ri[c]->errors > 20){
				///fprintf(stderr,"%s\n,%c,%c,%c,%d\n",line, *(line +tmp), *(line +tmp+1),*(line +tmp+2), ri[c]->errors);
				//}
				
			}else{
				ri[c]->errors = -1;
			}
			tmp = byg_end("MD:Z:", line  );
			if(tmp){
				g = 0;
				for(j = tmp ;j < read;j++){
					g++;
					if(isspace((int)line[j])){
						break;
					}
					
				}
				ri[c]->md = malloc(sizeof(unsigned char)* g);
				g = 0;
				for(j = tmp ;j < read;j++){
					
					if(isspace((int)line[j])){
						ri[c]->md[g] = 0;
						break;
					}
					ri[c]->md[g] = line[j];
					g++;
				}
			}
						
			
			
			//ri[c]->hits[hit] = 0xFFFFFFFFu;
			
			c++;
			if(c == param->num_query){
				MFREE(line);
				return c;
			}
		}
	}
	MFREE(line);
	return c;
}
Exemplo n.º 10
0
void	ematrix_printbasecirc_ext(ematrix *e, int whp, int lev, int *cix, char *bto, int mx) {
	
	ematrix		**bas, **be, *ee;
	int		i=0,j,jj,k,n, ro,co, blen,clen;
	long		l, *crc=NULL;
	
	if (bto)  {PROGERROR("Not implemented yet!"); return;}
	if (!e)  return;
	if (lev>0 && !bto)  SOUTPUT("\n");
	if (whp>1) if (ROWSM(e)>EM_MAXTOPRINT || COLSM(e)>EM_MAXTOPRINT) {
		OUTPUT("Too big matroid for extended printing, sorry.\n");  return;
	}
	ee = ematrix_copy(e);
	ro = ROWSM(ee);  co = COLSM(ee);
	if (ematrix_checkid(ee)<0 || ematrix_checkid(ee)>EM_MAXTOPRINT) {
		ematrix_resetid(ee);  SOUTPUT("\t\tResetting line id's in the matrix!!!\n");
	}
	bas = ematrix_getbases(ee);
	blen = alist_getlength(bas);
	if (!bto)  OUTPUT("Number of matroid [%.25s] bases:  %d\n",EMNAME(e)?EMNAME(e):"",blen);
	if (cix && !bto)  for (i=0; i<ro+co && cix[i]!=0; i++) {
		if (i==0)  OUTPUT("Listing all matroid [%.25s] %s containing elements (id): ",EMNAME(e)?EMNAME(e):"",whp<=10?"bases":"circuits");
		//if (cix[i]<-2*EM_MAXTOPRINT || cix[i]>2*EM_MAXTOPRINT)  cix[i] = 0;
		SOUTPUT(" %d,",cix[i]);
	}
	if (cix && !bto && i>0)  SOUTPUT("\n");
	        /**
	         * This part is used to print all bases (by their line ids).
	         * We test that the (possible) required elements from cix[] are there.
	        **/
	if (whp<=10) for (be=bas,k=0; be?*be:0; be++) {
		if (cix)  for (i=0; cix[i]; i++) {
			for (j=0; j<ro; j++)  if (ROWSID(*be,j)==cix[i])  break;
			if (j>=ro)  break;
		}
		if (cix?cix[i]:0)  continue;
		SOUTPUT("    ~\t - base (%d)\t{",++k);
		for (j=0; j<ro; j++)  SOUTPUT(" %d%s",ROWSID(*be,j),(j<ro-1?",":""));
		SOUTPUT(" }\n");
	}
	        /**
	         * This part is used to print all circuits (by their line ids).
	         * We test that the (possible) required elements from cix[] are there.
	         * Then we test that the same circuit (as a set) has not been printed
	         * out before - we store all printed circuits as bitmaps in crc[].
	        **/
	if (whp>=10) {
		if (!cix)  OUTPUT("Listing all matroid [%.25s] circuits:\n",EMNAME(e)?EMNAME(e):"");
		crc = MMALLOC(blen*co*sizeof(crc[0]));
		clen = 0;
	  for (be=bas,k=0; be?*be:0; be++) for (jj=0; jj<co; jj++) {
		if (cix)  for (i=0; cix[i]; i++) {
			for (j=0; j<ro; j++)
				if (SIGNM(*be,j,jj) && ROWSID(*be,j)==cix[i])  break;
			if (j>=ro && COLSID(*be,jj)!=cix[i])  break;
		}
		if (cix?cix[i]:0)  continue;
				/* preventing duplicated circuits (stored as bitmaps here) */
		l = 1l<<(COLSID(*be,jj)+EM_MAXTOPRINT);
		for (i=0; i<ro; i++)  if (SIGNM(*be,i,jj))
			l |= 1l<<(ROWSID(*be,i)+EM_MAXTOPRINT);
		for (j=0; j<clen; j++)  if (l==crc[j])  break;
		if (j<clen)  continue;
		crc[clen++] = l;
		n = 0;		/* printing... */
		SOUTPUT("    ~\t - circuit (%d)\t{",++k);
		for (i=0; i<ro; i++) if (SIGNM(*be,i,jj))
			{ n++;  SOUTPUT(" %d,",ROWSID(*be,i)); }
		SOUTPUT(" %d }  \tlen %d,\n",COLSID(*be,jj),n+1);
		
	}}
	if (lev>1 && !bto)  SOUTPUT("\n");
	if (crc)  FREE(crc);
	if (bas)  dispose_alist_mats(bas);
	dispose_ematrix(ee);
}
Exemplo n.º 11
0
long	ematrix_printmore_ext(ematrix *e, int lev, char *bto, int mx) {
	ematrix		**bas,**flt,**sep, **x, *ee,*xe;
	int		i,ii, j,jj,k,kk, a,ro,co, *li,*basi,**basii,
			 *orb=NULL,*orbx, *ses=NULL, bbm,bbl;
	long		hash = 0, *flts=NULL;
	
	if (bto)  bto[0] = 0;
	bbm = mx;  bbl=0;
	if (!e)  return -1;
	if (lev>0) if (ROWSM(e)*COLSM(e)>EM_MAXTOPRINTSQ || ROWSM(e)>EM_MAXTOPRINT || COLSM(e)>EM_MAXTOPRINT) {
		OUTPUT("Too big matroid for extended printing, sorry.\n");  return -1;
	}
	ee = ematrix_copy(e);
	ro = ROWSM(ee);  co = COLSM(ee);
	basi = MMALLOC(2*(ro+co+2)*sizeof(basi[0]));  li = basi+ro+co;
	basii = malloc_twodim(sizeof(basii[0][0]),ro+co,ro+co);
	for (i=0; i<ro+co; i++)  basi[i] = 0;
	for (i=0; i<ro+co; i++) for (ii=0; ii<ro+co; ii++)  basii[i][ii] = 0;
	flts = MMALLOC((ro+co+2)*sizeof(flts[0]));
	if (lev>0 && !bto)  SOUTPUT("\n");
	hash = ro+10*co;
	hash = 90909l*hash+111l*hash*hash*hash;

		/**
		 * Here we collect and print all bases - their total number, and numbers
		 * per elements (basi[]) and per element pairs (basii[][]).
		 * The bases are given as refering square submatrices of ee (not pivoted!).
		 * We add the numbers to the matroid hash value in a symmetric way.
		 *   ....... more to be added to the hash value - small flatlines???
		 * 
		 * The bases are also used later, and they are freed at the end.
		**/
	bas = ematrix_getbases_sq(ee);
	hash += alist_getlength(bas)*10101l;
	for (x=bas; x?*x:0; x++) {
		xe = ematrix_refextract_xrow(ee,*x);
		if (ROWSM(xe)+COLSM(xe)!=ro)  {PROGERROR("Something wrong with the basis size!");}
		for (i=0; i<ROWSM(xe); i++)
			li[i] = GETREFMROW(xe,i);
		for (i=0; i<COLSM(xe); i++)
			li[i+ROWSM(xe)] = GETREFMCOL(xe,i)+ro;
		for (i=0; i<ro; i++) {
			basi[li[i]]++;
			for (ii=0; ii<ro; ii++)  basii[li[i]][li[ii]]++;
		}
		dispose_ematrix(xe);
	}
	for (i=0; i<ro+co; i++) {
		hash += 505l*basi[i]+7l*basi[i]*basi[i];
		for (ii=0; ii<i; ii++)  hash += 13l*basii[i][ii]+1l*basii[i][ii]*basii[i][ii];
		if (basii[i][ii]!=basii[ii][i])  {PROGERROR("Something wrong - nonsymmetric basis pairs!");}
	}
	//************* adding small flatlines to the hash value? - here, not below, since the element
	//		magic below is slow to compute and not computed always(!)
	
	if (lev>=0) {
		if (!bto)  OUTPUT("Number of matroid [%.25s] bases:  %d\n",EMNAME(e)?EMNAME(e):"",alist_getlength(bas));
		else  SNPRINTF(bto,bbl,bbm,"Matroid  %d x %d [%.25s],  %d bases.\n",ro,co,EMNAME(e)?EMNAME(e):"",alist_getlength(bas));
	}
	if (lev>0 && !bto) {
		OUTPUT("  - per elements ");
		for (i=0; i<ro+co; i++)  SOUTPUT(" [%d: %d]%s",LIID(ee,i),basi[i],i%6==5?"\n\t\t\t":"");
		SOUTPUT("\n");
	}
	if (lev>4 && !bto) {
		SOUTPUT("\n");  OUTPUT("  - per element pairs\n");
		for (i=0,a=1; i<ro+co; i++) {
			if (a)  SOUTPUT("    ~\t ");  a = 0;
			for (ii=0; ii<ro+co; ii++)  if (basii[i][ii]>0) {
				a = 1;
				SOUTPUT("[%2d'%2d: %-3d]",LIID(ee,i),LIID(ee,ii),basii[i][ii]);
			}
			if (a)  SOUTPUT("\n");
		}
	}
		/**
		 * Here we (try to) distinguish matroid elements up to isomorphism.
		 * We either compute "magic values" for the elements - faster,
		 * or we rigorously compute the orbits of the automorphism group.
		 * For the orbits, we use the numbers of bases in basi[] and the
		 * flatline values flts[] for rough distinction, and then we use
		 * strmag_isautmap() to see which pairs of elements are really
		 * mapped to each other by the aut group.
		**/
	if (lev>0) {
		strmag_flatlines_pr(ee,flts);	/* (flts[] is globally allocated) */
		for (i=0; i<ro+co; i++)  flts[i] += 7*basi[i];
	}
	if (lev>0 && lev<=2 && !bto) {
		OUTPUT("  - elem magic ");
		for (i=0; i<ro+co; i++)  SOUTPUT(" [%d: %ld]%s",LIID(ee,i),flts[i],i%6==5?"\n\t\t\t":"");
		SOUTPUT("\n");
	}	
	if (lev>2 && ro>0) {
		if (ro+co>6)  DEBUG(CURDLEV-3,"Warning - aut orbit computation may take very long.\n");
		if (!bto)  OUTPUT("Aut group orbits of [%.25s] are (via first elem id):\n",EMNAME(e)?EMNAME(e):"");
		else  SNPRINTF(bto,bbl,bbm,"Aut group orbits ");
		if (ematrix_checkid(ee)<0 && !bto) {
			ematrix_resetid(ee);  SOUTPUT("\t\tResetting line id's in the matrix!!!\n");
		}
		orb = MMALLOC(2*(ro+co+2)*sizeof(orb[0]));
		orbx = orb+(ro+co+1);
		for (i=0; i<ro+co; i++)  orbx[i] = 1;
		if (!bto) {
			for (i=0; i<ro; i++)  orb[i] = ROWSID(ee,i);
			for (i=ro; i<ro+co; i++)  orb[i] = COLSID(ee,i-ro);
		} else  for (i=0; i<ro+co; i++)  orb[i] = i;
			/* (we print elem ids on output, but their indices to bto...) */
		if (!bto)  SOUTPUT("\t\t(%d",orb[0]);
		else  SNPRINTF(bto,bbl,bbm,"[%d",orb[0]);
		kk = ro+co;
		for (i=1; i<ro+co; i++) {
			for (j=0; j<i; j++) if (orbx[j]) {
				if (basi[i]!=basi[j] || flts[i]!=flts[j])  continue;
				//********** may we efficiently use basii[][] here???
				if (!strmag_isautmap_h(e,i,j,flts))  continue;
				orb[i] = orb[j];  orbx[i] = 0;  kk--;
			}
			if (!bto)  SOUTPUT(",%s %d",i==ro?" ":"",orb[i]);
			else  SNPRINTF(bto,bbl,bbm,",%s %d",i==ro?" ":"",orb[i]);
		}
		if (!bto)  SOUTPUT(") =%d\n",kk);
		else  SNPRINTF(bto,bbl,bbm,"] %d.\n",kk);
		FREE(orb);
	}
		/**
		 * Here we list all nontrivial flats of the matroid up to rank
		 * depending on lev, or up to the first flats found.
		 * See also ematrix_printmore_flats() below.
		 * (We currently do not use information about the printed flats
		 * in the matroid hash-value since the flats are expensive to compute.
		 * Also, the flat comp implementation works only for bounded size!)
		**/
	ematrix_printmore_flats(NULL,0,1);
	if (lev>0)
	  for (k=0,a=1; k<lev+a && k<ro; k++) {
		flt = ematrix_submatrices_sub(ee,k);
		for (x=flt,i=0; x?*x:0; x++) {
			xe = ematrix_closure(ee,*x);
			kk = ematrix_setrank(ee,xe);
			if (kk>k)  {PROGERROR("something wrong with the flat rank %d>%d",kk,k);}
			if (ROWSM(xe)+COLSM(xe)>k && k==kk)
			  if (ematrix_printmore_flats(xe,k,0)>=0) {
				if (i==0 && lev>1 && !bto)  SOUTPUT("\n");
				if (i==0 && !bto)  OUTPUT("Listing all (nontrivial) flats in [%.25s] of rank %d:\n",
							EMNAME(e)?EMNAME(e):"",k);
				if (i==0 && bto)  SNPRINTF(bto,bbl,bbm,"Flats of rank %d:",k);
				i++;
				if (i%5==0 && bto)  SNPRINTF(bto,bbl,bbm,"\n");
				if (!bto) {
				  SOUTPUT("    ~\t - rank-%d flat (%d)\t{",k,i);
				  for (j=0; j<ROWSM(xe); j++)  SOUTPUT(" %d,",ROWSID(xe,j));
				  for (j=0; j<COLSM(xe); j++)  SOUTPUT("%c %d",!j?' ':',',COLSID(xe,j));
				  SOUTPUT(" }\n");
				} else {
				  SNPRINTF(bto,bbl,bbm,"  %df{",i);
				  for (j=0; j<ROWSM(xe); j++)  SNPRINTF(bto,bbl,bbm,"%d,",GETREFMROW(xe,j));
				  for (j=0; j<COLSM(xe); j++)  SNPRINTF(bto,bbl,bbm,"%c%d",!j?' ':',',GETREFMCOL(xe,j)+ro);
				  SNPRINTF(bto,bbl,bbm,"}");
				}
			}
			dispose_ematrix(xe);
		}
		if (i==0 && k==0 && lev>1 && !bto)  SOUTPUT("\n");
		if (i==0 && !bto)  OUTPUT("There are -NO- (nontrivial) flats in [%.25s] of rank %d.\n",EMNAME(e)?EMNAME(e):"",k);
		if (i>0 && bto)  SNPRINTF(bto,bbl,bbm,"\n");
		if (flt)  dispose_alist_mats(flt);
		if (i!=0 && bto && k>=3)  break;
		if (i==0 && k>0)  a++;
	}
	ematrix_printmore_flats(NULL,0,-1);
	
		/**
		 * Here we list all nontrivial separations of the matroid up to lambda
		 * depending on lev, or up to the first separations found.
		 * (We currently do not use these information in the hash-value.)
		**/
	if (lev>1 && !bto) {
		sep = ematrix_submatrices_all(ee);
		ii = sep? alist_getlength(sep):0;
		ses = MMALLOC((ii+2)*sizeof(ses[0]));
		for (x=sep; x?*x:0; x++)
			ses[x-sep] = ematrix_whatsep(ee,*x);
		for (k=0,a=-1; k<lev+a && k<ro; k++) {
			for (jj=i=0; jj<ii; jj++) if (ses[jj]==k) {
				xe = sep[jj];
				if (ROWSM(xe)+COLSM(xe)<=k || ROWSM(xe)+COLSM(xe)>(ro+co)/2)
					continue;
				if (i==0 && lev>1)  SOUTPUT("\n");
				if (i==0)  OUTPUT("Listing all exact separations in [%.25s] of lambda %d:\n",
							EMNAME(e)?EMNAME(e):"",k+1);
				SOUTPUT("    ~\t - %d-separation (%d)\t(",k+1,++i);
				for (j=0; j<ROWSM(xe); j++)  SOUTPUT(" %d,",ROWSID(xe,j));
				SOUTPUT(" ");
				for (j=0; j<COLSM(xe); j++)  SOUTPUT(" %d,",COLSID(xe,j));
				SOUTPUT(" )\n");
			}
			if (i==0 && k==0)  SOUTPUT("\n");
			if (i==0)  OUTPUT("There are -NO- exact separations in [%.25s] of lambda %d.\n",EMNAME(e)?EMNAME(e):"",k+1);
			if (i==0 && k>0)  a++;
		}
		if (sep)  dispose_alist_mats(sep);
		FREE(ses);
	}
	
#ifndef FASTPROG		/* paranoic testing of the hash-value computation: */
	if (lev>=0 && IFRANDDEBUGLESS(111)) {
		for (ii=0; ii<4; ii++) {	/* extra testing hash with pivoted matrix */
			i = RANDOM()%ROWSM(ee);  j = RANDOM()%COLSM(ee);
			if (SIGNM(ee,i,j)!=0)  ematrix_pivot(ee,i,j);
		}
		if (hash!=ematrix_printmore_ext(ee,-1,NULL,0))  {PROGERROR("incorrect computation of matroid hash, ret=%ld",hash);}
	}		/* (ee is modified here !!!) */
#endif
	if (bas)  dispose_alist_mats(bas);
	if (flts)  FREE(flts);
	if (basi)  FREE(basi);	if (basii)  FREE(basii);
	
		/**
		 * Some other final characteristics are printed here.
		 * Representability is surveyed for some basic fields, depending on lev.
		 * Among them the matroid hash-value is printed out and always returned.
		 * So far, the matroid hash-value collects information about rank,
		 * number of bases, numbers of bases per each element and each pair of elements.
		 * You must update the version number if you change the collected information!
		**/
	if (lev>0 && !bto) {
		SOUTPUT("\n");  k = 0;
		OUTPUT("Matroid [%.25s] connectivity is %d",
				EMNAME(e)?EMNAME(e):"",kk=struct_iconnectivity(e,&k));
		if (kk==3 && k)  SOUTPUT(" (internally %d-connected).\n",kk+1);
		else  SOUTPUT(".\n");
		OUTPUT("Matroid [%.25s] girth (shortest cycle) is %d.\n",
				EMNAME(e)?EMNAME(e):"",struct_matgirth(e));
	}
	if (lev>0 && bto) {
		SNPRINTF(bto,bbl,bbm,"Connectivity  %d, girth (shortest cycle)  %d.\n",
				struct_connectivity(e),struct_matgirth(e));
	}
	if (lev>2) {
		char	*xx_fields[] = {"GF(2)","GF(3)","GF(4)","GF(5)","GF(7)","GF(8)","GF(9)"};
		if (!bto)  OUTPUT("Matroid [%.25s] representability:",EMNAME(e)?EMNAME(e):"");
		else  SNPRINTF(bto,bbl,bbm,"Representability over:");
		for (j=0; j<(int)(sizeof(xx_fields)/sizeof(xx_fields[0])); j++) {
			ii = pfield_curindex();
			pfield_switchto(xx_fields[j]);	/* (we expect all the fields defined!) */
			a = grepr_isrepresented(ee,ii)>0;
			if (!bto)  SOUTPUT(" %c%s%c",a?'+':'-',xx_fields[j],a?'+':'-');
			else  SNPRINTF(bto,bbl,bbm," %c%s%c",a?'+':'-',xx_fields[j],a?'+':'-');
			pfield_switchto_fast(ii);
		}
		if (!bto)  SOUTPUT("\n\n");  else  SNPRINTF(bto,bbl,bbm,"\n");
	}
	if (lev>=0 && !bto)  OUTPUT("Overall matroid [%.25s] hash-value (version %s):  %ld\n",
					EMNAME(e)?EMNAME(e):"",EM_HASHVER,hash);
	dispose_ematrix(ee);
	return hash;
}
Exemplo n.º 12
0
int	struct_connorder_ext(ematrix *e, int tr, int *cor, int *cp, int *cxp, int **cadj) {
	int	i,ii,j,k, r,c, cornul=0, *ud,udstack[30];
	
	if (!tr)  ematrix_transpose(e);
	if (COLSM(e)<14)  ud = udstack;
	else  ud = MMALLOC((2*COLSM(e)+2)*sizeof(ud[0]));
	if (cxp && cor)  {PROGERROR("not allowed to use cxp[] with cor[] !!"); cxp=NULL;}
	if (cor==NULL) { cornul = 1;  cor = ud+COLSM(e); }
	for (j=0; j<COLSM(e); j++)  ud[j] = cor[j] = 0;
	if (cxp)  for (j=0; j<ROWSM(e); j++)  cxp[j] = 0;
	if (cadj)  for (i=0; i<COLSM(e); i++)
		for (ii=0; ii<COLSM(e); ii++)  cadj[i][ii] = -1;
		/**
		 * We simply search the columns of e, for each one looking at the rows it
		 * has nonzero, and adding other columns which have nonzeros in this row.
		 * ud[ii] marks columns that were already reached, starting from ud[0].
		 * If k>j happens, that means we ran out of connected columns to continue
		 * the search, and we start with the first next component.
		 * (This happens always in the first run.)
		**/
	j = -1;  c = 0;  r = 1;
	for (k=0; k<COLSM(e); k++) {
		if (k>j) {
			for (ii=0; ii<COLSM(e) && ud[ii]; ii++) ;
			if (ii>=COLSM(e) || k>j+1)  {PROGERROR("must find another component here!"); break;}
			cor[++j] = ii;  ud[ii] = ++c;
			if (k>0)  r = 0;		/* next component reached in the graph -> disconnected */
		}
		for (i=0; i<ROWSM(e); i++)
		  if (SIGNM(e,i,cor[k])!=0)
			for (ii=0; ii<COLSM(e); ii++)
			  if (SIGNM(e,i,ii)!=0 && ii!=cor[k]) {
				if (!ud[ii]) {		/* next column reached in the graph */
					cor[++j] = ii;  ud[ii] = c;
				}
				if (cadj)		/* record adjacency between the columns */
					cadj[cor[k]][ii] = cadj[ii][cor[k]] = i;
			}
		if (j+1>=COLSM(e) && !cadj)  break;
	}
		/**
		 * Additional data: Store component indices for the columns and the rows
		 * of (transposed?) matrix e.
		 * These are indexed in the same way as cor[] if given (only for cp[]),
		 * or by absolute matrix line indices otherwise.
		**/
	if (cp)  for (j=0; j<COLSM(e); j++) {
		if (!cornul)  cp[j] = ud[cor[j]];
		else  cp[j] = ud[j];
	}
	if (cxp)  for (i=0; i<ROWSM(e); i++) {
		for (j=0; j<COLSM(e) && !SIGNM(e,i,j); j++) ;
		if (j<COLSM(e))  cxp[i] = ud[j];
	}
#ifndef FASTPROG
	if (DEBUGLEV>=CURDLEV+2) {
		DEBUG(CURDLEV+2,"Found%s connected col order: ",r?"":" -NO-");
		for (ii=0; ii<COLSM(e); ii++)  SDEBUG(CURDLEV+2,"%d, ",cor[ii]);
		SDEBUG(CURDLEV+2,"\n");  EMATDEBUG(CURDLEV+4,e,"\t\t\t<\t");
	}
	if (cadj && DEBUGLEV>=CURDLEV+2) {
		EMATDEBUGS(CURDLEV+2,e,"\t\tconn\t");
		DEBUG(CURDLEV+2," - cadj[][] adjacencies (-1 for no adj):\n");
		for (i=0; i<ROWSM(e); i++)  for (j=0; j<COLSM(e); j++)
			SDEBUG(CURDLEV+2,"%s% d%c",j==0?"\t\t":"",cadj[i][j],j==COLSM(e)-1?'\n':'\t');
	}
	if (j+1>=COLSM(e) && IFRANDDEBUG(33))  for (ii=0; ii<COLSM(e); ii++)
		if (!ud[ii])  {PROGERROR("wrong computation of a connected order!");}
	if (j+1<COLSM(e) && IFRANDDEBUGLESS(333)) {
		for (i=0; i<COLSM(e); i++)  for (ii=i+1; ii<COLSM(e); ii++)
			if (ud[i]!=ud[ii])  for (j=0; j<ROWSM(e); j++)
				if (SIGNM(e,j,i)!=0 && SIGNM(e,j,ii)!=0)  {PROGERROR("wrong computation of a (dis-)connected order!");}
	}
#endif
	if (ud && ud!=udstack)  FREE(ud);
	if (!tr)  ematrix_transpose(e);
	return (r?1:-1);
}
Exemplo n.º 13
0
int	struct_hasfan_ext(int ch, ematrix *e, ematrix *ec, int tr, int lo, int fan) {
	ematrix		*ee, *eec;
	char		buf[1000];
	int		i,k,kk, st,tt1,tt2,tt,ttm=0, br, ret, lf,
			*fn=NULL,*fnm, fnstack[104];
	
	if (ec)  if (!ISREFMAT(ec) || REFMAT(ec)!=e || ISTRANSPM(e)!=ISTRANSPM(ec))
		{ PROGERROR("When using ec, it must refer to e in the same transpose state"); ec = NULL; }
	if (ec && tr>=0) { PROGERROR("When using ec, do not use tr>=0"); tr = -1; }
	if (fan>=0 && fan<3) { PROGERROR("What is fan of length %d <3 ??",fan); fan = 3; }
	if (lo<0)  lo = tr? COLSM(e)-1:ROWSM(e)-1;
	buf[0] = 0;  kk = 0;
#ifndef FASTPROG
	DEBUG(CURDLEV+(ch<0),"Looking for %d-fans in %p [%s] %dx%d (tr=%d, lo=%d%s)...\n",
			fan,e,EMNAME(e)?EMNAME(e):"",ROWSM(e),COLSM(e),tr,lo,ec?", ec":"");
	EMATDEBUGS(CURDLEV+1,e,"\t\tf\t");  if (ec) EMATDEBUGS(CURDLEV+1+(ch<0),ec,"\t\t\t-\t");
	if (ch>=0 && tr>=0 && IFRANDDEBUGLESS(555)) {	/* (debug-check for 3-connectivity without lo) */
		ee = ematrix_copy(e);  ematrix_remove_rc(ee,tr,lo);
		if (!struct_isconnected(ee,3))  {PROGERROR("wrong - not 3-connected without lo=%d",lo); EMATDEBUG(0,ee,"!!\t");}
		dispose_ematrix(ee); }
#endif
	if (fan>ROWSM(e)+COLSM(e))  return 0;
	if (ch>2) {
		OUTPUT("Looking for %d%s in the matroid [%s] %dx%d...\n",
			fan,fan<0?" the longest fan":"-fans",EMNAME(e)?EMNAME(e):"",ROWSM(e),COLSM(e));
		if (tr>=0 || ec)  DEBUG(0,"Do not call fan printing with tr=%d>=0 or ec=%p.\n",tr,ec);
		if (fan<0)  DEBUG(CURDLEV-3,"Do not call all fan printing with fan=%d<0 (max fan).\n",fan);
	}
	if (ROWSM(e)+COLSM(e)<50)  fn = fnstack;
	else  fn = MMALLOC((ROWSM(e)+COLSM(e)+2)*2*sizeof(fn[0]));
	fnm = fn+ROWSM(e)+COLSM(e)+2;
	if (tr<0) {		/* no last line for the fan given - trying everything */
		st = 0;  tt1 = 0;  tt2 = 1;
	} else {		/* the last fan line is given, also determines tt by 3-connectivity */
		st = 1;  tt1 = tt2 = tr? 1:0;
		fn[0] = tr? ROWSM(e)+lo:lo;
		DEBUG(CURDLEV+2,".. hasfan pre-determined %s fn[0] = %d, tt=%d\n",tr?"col":"row",lo,tt1);
	}
		/**
		 * We cycle all choices of k lines and starting tt values (triad 0/triangle 1),
		 * beginning with a choice of fn[st], where st and tt1,tt2 depend on the input.
		 * One choice is a row for <ROWSM and a column +ROWSM otherwise.
		 * We record the longest fan length in lf, and the fan itself in fnm[].
		 * If we look only for a fan longer than the given value, we stop immediately
		 * after we find it, otherwise we search through all fans to find the longest one.
		 * As we generate our choice, we test the consecutive triples for being
		 * triangles/triads (by tt).
		**/
	ret = lf = 0;
	for (tt=tt1; tt<=tt2 && !ret; tt+=(ret?0:1)) {
	  k = st;  fn[k] = -1;
	  while (k>=st && !ret) {
			/* the value of fn[k] is the current choice - row for <ROWSM, column+ROWSM otherwise */
		if (++fn[k]>=ROWSM(e)+COLSM(e)) {
			--k;  continue;		/* (no more choices at this level) */
		}
		for (i=0; i<k; i++)  if (fn[i]==fn[k])  break;
		if (i<k)  continue;		/* (if fn[k] was already chosen previously) */
		if (ec) {
			if (fn[k]<ROWSM(e))  for (i=ROWSM(ec)-1; i>=0 && GETREFMROW(ec,i)!=fn[k]; i--) ;
			else  for (i=COLSM(ec)-1; i>=0 && GETREFMCOL(ec,i)!=fn[k]-ROWSM(e); i--) ;
			if (i<0)  continue;	/* (if fn[k] does not belong to ec if given) */
		}
		DEBUG(CURDLEV+2,"%*s. hasfan(%d) trying choice %s fn[%d] = %d (%d) for %s\n",2*k,"",fan,
				fn[k]<ROWSM(e)?"row":"col",k,fn[k]<ROWSM(e)?fn[k]:fn[k]-ROWSM(e),fn[k]<ROWSM(e)?ROWSID(e,fn[k]):COLSID(e,fn[k]-ROWSM(e)),(k+tt)%2?"triang":"triad");
		
		if (k>=2) {	/* looking for a triangle ((k+tt)%2==1) or triad ((k+tt)%2==0) at this level */
			br = struct_hasfan_triax((ch<-3?-1:0),e,(k+tt)%2,fn[k-2],fn[k-1],fn[k],1);
			if (br<=0)  continue;	/* if there was no triaxx, then cycle other choices */
		}
		if (++k>lf) {			/* records the longest fan found so far */
			lf = k;  ttm = tt;
			for (i=0; i<k; i++)  fnm[i] = fn[i];
			DEBUG(CURDLEV+2,"-%*s. hasfan(%d) found longer = %d\n",2*k,"",fan,lf);
		}
		if (k<fan || fan<0) {		/* to the next choice of line */
			fn[k] = -1;  continue;
		}
		if (k>ROWSM(e)+COLSM(e))  {PROGERROREXIT("Out of index range looking for a fan");}
		fn[k] = 11111;			/* fan of given length found here, plus printing */
		if (ch>=2 || CURDLEV-1+(ch<0)<=printlev) {
			sprintf(buf,"fan: (%s+..) ",ttm?"triangle":"triad");
			for (i=0; i<lf; i++)  snprintf((buf[800]=0,buf+strlen(buf)),50,"%s%d(%d), ",
					fn[i]<ROWSM(e)?"r":"c",fn[i]<ROWSM(e)?fn[i]:fn[i]-ROWSM(e),fn[i]<ROWSM(e)?ROWSID(e,fn[i]):COLSID(e,fn[i]-ROWSM(e)));
		}
		if (ch>2)  OUTPUT("\t[%s]#%d %s\n",EMNAME(e)?EMNAME(e):"",++kk,buf);
		else  ret = 1;		/* (this breaks the cycle, unless all printing is required) */
	}}
		/**
		 * If fan>0, then the fans of this length are recorded above, and they are
		 * all printed out if ch>2 is requested.
		 * On the other hand, fan<0 the longest fan is printed out below, separately.
		 * The return value is the longest fan, or the requested fan length, or 0.
		**/
	if (fan<=0)  ret = (lf>=3? lf:0);
	else  ret = (lf>=fan? fan:0);
	if (fan<0) if (ch>=2 || CURDLEV-1+(ch<0)<=printlev) {
		sprintf(buf,"longest fan: (%s+..) ",ttm?"triangle":"triad");
		for (i=0; i<lf; i++)  snprintf((buf[800]=0,buf+strlen(buf)),50,"%s%d(%d), ",
				fnm[i]<ROWSM(e)?"r":"c",fnm[i]<ROWSM(e)?fnm[i]:fnm[i]-ROWSM(e),fnm[i]<ROWSM(e)?ROWSID(e,fnm[i]):COLSID(e,fnm[i]-ROWSM(e)));
	}
	if (ch==2 || (ch>=2 && fan<0))  OUTPUT("\t[%s] %s\n",EMNAME(e)?EMNAME(e):"",buf);
	ee = eec = NULL;
#ifndef FASTPROG
	DEBUG(CURDLEV-1+(!ret)+(ch<0),"- hasfan(%d) test for %p [%s] (l %d, tr=%d%s) found max %d  %s.\n",
			fan,e,EMNAME(e)?EMNAME(e):"",lo,tr,ec?", ec":"",lf,fan>0?"":(ret?"+HAS+":"NO fan"));
	SDEBUG(CURDLEV-1+(!ret)+(ch<0),"\t\t\t ->  %s\n",buf);
			/* (debug-testing the full-test for diff basis of e) */
	if (ch>=0 && tr<0 && IFRANDDEBUG(222)) {
		ee = ematrix_copy(e);  EMSETNAME(ee,"rec-test");
		for (eec=ec, tt=0; tt<5; tt++) {
			i = random()%ROWSM(ee);  k = random()%COLSM(ee);
			if (SIGNM(ee,i,k)==0)  continue;
			if (ec!=NULL) {	/* (not to interfere with the matrix ec if given) */
				for (tt1=ROWSM(ec)-1; tt1>=0 && GETREFMROW(ec,tt1)!=i; tt1--) ;
				for (tt2=COLSM(ec)-1; tt2>=0 && GETREFMCOL(ec,tt2)!=k; tt2--) ;
				if (tt1>=0 && tt2>=0)  ematrix_pivot(ee,i,k);
			} else  ematrix_pivot(ee,i,k);
		}
		if (ec) { eec = ematrix_refer_all(ec);  ematrix_rerefer(eec,ee); }
		else if (random()%2==1)  ematrix_transpose(ee);
		if (ret!=(kk=struct_hasfan_ext(-1,ee,eec,-1,-1,fan)))  {PROGERROR("The result must be the same after pivoting (transpose)! ret=%d != %d",ret,kk);}
		if (ec) dispose_ematrix(eec);  dispose_ematrix(ee);
	}
#endif
	if (fn && fn!=fnstack)  FREE(fn);
	return ret;
}
Exemplo n.º 14
0
int     struct_hasbwidth3_ext(int ch, ematrix *em, char **decomp, int *ldecomp) {
	ematrix		*ee, *ex,*e1,*e2, *eu, *ef,*eff;
	ematrix		**list, **lpair, **lln,*llnst[30], **x,**y;
	int		i,j,k, a,b, r, msz;
	char		buf[400];
	
	if (ldecomp!=NULL)  {PROGERROR("return ldecomp[] is not implemented yet!"); ldecomp = NULL;}
	if (!em)  {PROGERROR("the matrix must be given here"); return -1;}
	ee = ematrix_copy(em);
	msz = ROWSM(ee)+COLSM(ee);
#ifndef	FASTPROG
	if (msz<10 || (msz<14 && IFRANDDEBUGLESS(22)) || IFRANDDEBUGLESS(222)) {
		if (!struct_isconnected(ee,3))  {PROGERROR("Can correctly test branch-width 3 only for 3-connected matrices!");}
	}
	DEBUG(CURDLEV,"Testing branch-width 3 for the matroid %p [%s]...\n",ee,EMNAME(em)?EMNAME(em):"");
#endif
	lln = (msz<28?llnst: MMALLOC((msz+2)*sizeof(lln[0])));
	list = ematrix_submatrices_sub(ee,1);
	if (alist_getlength(list)!=msz)  {PROGERROR("wrong list of singletons generated here ?!?");}
	for (x=list; x?*x:0; x++) {
		snprintf(buf,5," %d ",(ROWSM(*x)>0?ROWSID(*x,0):COLSID(*x,0)));
		EMSETNAME(*x,buf);
		lln[GETREFMLINE(ee,*x,0)] = *x;
	}
			/**
			 * We start with an initial partition  list  of the matroid into singletons.
			 * Then we cycle the next procedure until the list has one part only.
			 * Trivial cases are sorted first - a matroid on <=6 elements always
			 * has bw <=3, and if only <=3 singletons remain besides one larger
			 * part, then we are done as well.
			 * The supplementary array refers to those parts in  list  that are
			 * still singletons (by their row/column indices in ee).
			**/
	while (alist_getlength(list)>1) {
		DEBUG(CURDLEV+2,"  new cycle for list %d\n",alist_getlength(list));
		lpair = NULL;  eu = e1 = e2 = NULL;
		r = 0;
		for (x=list, a=b=0,y=NULL; *x && a<2 && b<7; x++,b++)
			 if (ROWSM(*x)+COLSM(*x)>1) { a++;  y = x; }
		if (a==0 && b<=6) {
			e1 = ematrix_refer_all(ee);  eu = ematrix_refer_all(ee);  r = 1;
		} else if (a==1 && b<=4) {
			e1 = *y;  e2 = ematrix_refextract_xall(ee,*y);
			eu = ematrix_refer_all(ee);  r = 2;
		}
			/**
			 * Here we try all pairs of parts in  list.
			 * If their union is 3-separating, and not both are singletons,
			 * then we have a new part for replacement.
			**/
		for (x=list; *x && !r; x++) for (y=x+1; *y && !r; y++) {
		  if ((a=ROWSM(*x)+COLSM(*x))>1 || (b=ROWSM(*y)+COLSM(*y))>1) {
			eu = ematrix_union(*x,*y);
			if (ematrix_whatsep(ee,eu)<3) {
				if (a>=b) { e1 = *x;  e2 = *y; }
				else { e1 = *y;  e2 = *x; }
				r = 3;
			} else {
				dispose_ematrix(eu);
			}
			/**
			 * If both in the pair are singletons, then we save this pair for
			 * later testing, and we try our luck with the line-(co)closure.
			 * If the closure has >=4 elements among singletons, then it forms
			 * a new part.
			 * We save a possible closure triple for later testing, but only
			 * if the third element is in the middle of the pair.
			**/
		  } else {
			ef = ematrix_union(*x,*y);
			lpair = alist_append(lpair,ef);
			for (k=0; k<2 && !r; k++) {
				eff = ematrix_closure_tr(ee,ef,k);
				a = 1;
				for (i=ROWSM(eff)+COLSM(eff)-1; i>=0; i--) {
					j = GETREFMLINE(ee,eff,i);
					if (lln[j]==NULL) {
						if (i<ROWSM(eff))  ematrix_remove_row(eff,i);
						else  ematrix_remove_col(eff,i-ROWSM(eff));
					} else {
						a = a && (j==GETREFMLINE(ee,*x,0) || j==GETREFMLINE(ee,*y,0)
							|| (j>GETREFMLINE(ee,*x,0) && j>GETREFMLINE(ee,*y,0)));
					}
				}
				if (ROWSM(eff)+COLSM(eff)>3) {
					e1 = eff;  eu = ematrix_refer_all(eff);  r = 1;
				} else if (a && ROWSM(eff)+COLSM(eff)==3) {
					lpair = alist_append(lpair,eff);
				} else  dispose_ematrix(eff);
			}
		  }
		  DEBUG(CURDLEV+3,"   cycle x=%d, y=%d, r=%d, pair %d\n",(int)(x-list),(int)(y-list),r,alist_getlength(lpair));
		}
			/**
			 * Then we have to try all pairs that take one non-singleton part
			 * and the other as one of the above pairs or triples,
			 * or two disjoint above pairs or triples.
			 * Again, we look at their union whether it is 3-separating.
			**/
		for (x=list; *x && !r; x++) if (ROWSM(*x)+COLSM(*x)>1) {
			for (y=lpair; (y?*y:0) && !r; y++) {
				eu = ematrix_union(*x,*y);
				if (ematrix_whatsep(ee,eu)<3) {
					e1 = *x;  e2 = ematrix_refer_all(*y);  r = 2;
				} else  dispose_ematrix(eu);
			}
		}
		for (x=lpair; (x?*x:0) && !r; x++) {
			if (ROWSM(*x)+COLSM(*x)>3)  {PROGERROR("only pairs and triples should be here");}
			for (y=x+1; *y && !r; y++)
			  if (ematrix_isdisjoint(*x,*y)) {
				eu = ematrix_union(*x,*y);
				if (ematrix_whatsep(ee,eu)<3) {
					e1 = ematrix_refer_all(*x);  e2 = ematrix_refer_all(*y);
					r = 1;
				} else  dispose_ematrix(eu);
			}
		}
		if (lpair)  dispose_alist_mats(lpair);
			/**
			 * Finally, if we have found a union (in eu) for the new part (r>0),
			 * then we have to remove the current parts of the union,
			 * print this new branch for records, and store the union into the list.
			**/
		if (r<=0)  break;
		buf[0] = 0;
		for (k=0, ex=e1; ex && k<2; k++, ex=e2) {
		  if (r>k+1) {
			snprintf(buf+strlen(buf),180,"(%s)",EMNAME(ex));
			list = alist_delete_val(list,ex);
		  } else {
			for (i=ROWSM(ex)+COLSM(ex)-1, a=0; i>=0; i--) {
				j = GETREFMLINE(ee,ex,i);
				ef = lln[j];  lln[j] = NULL;
				if (!ef)  {PROGERROR("should find only singleton elements here"); continue;}
				if (!a++)  snprintf(buf+strlen(buf),3,"(");
				if (strlen(buf)<380)  snprintf(buf+strlen(buf),5,"%s",EMNAME(ef));
				list = alist_delete_val(list,ef);
				dispose_ematrix(ef);
			}
			if (a>0)  snprintf(buf+strlen(buf),3,")");
		  }
		  dispose_ematrix(ex);
		}
		DEBUG(CURDLEV+1," - new branch found   %s\n",buf);
		EMSETNAME(eu,buf);
		list = alist_append(list,eu);
	}
			/**
			 * Here we prepare the return values and possible debug printing.
			 * We also try the result recursively on an equivalent dual matrix.
			**/
	if (alist_getlength(list)<=1) {
		r = 1;
		if (decomp && list[0])  *decomp = MSTRDUP(EMNAME(list[0]));
		if (ch>1)  OUTPUT("A width-3 branch decomposition of [%s] is:  %s\n",EMNAME(em)?EMNAME(em):"",EMNAME(list[0]));
	} else {
		r = -1;
		if (ch>1)  OUTPUT("There is NO width-3 branch decomposition of [%s].\n",EMNAME(em)?EMNAME(em):"");
	}
#ifndef	FASTPROG
	if (r>=0 && ch>=0) {
		DEBUG(CURDLEV-1,"Found a width 3 branch-decomposition of %p [%s] here\n\t\t\t\t\t%s.\n",
					ee,EMNAME(em)?EMNAME(em):"",list[0]?EMNAME(list[0]):"");
		if (msz>1 && (list[0]?ROWSM(list[0])+COLSM(list[0])!=msz:1))  {PROGERROR("wrong final partition in computation of branch-width 3");}
	} else if (ch>=0) {
		DEBUG(CURDLEV-1,"NO width 3 branch-decomposition of %p [%s] exists.\n",ee,EMNAME(em)?EMNAME(em):"");
		for (x=list,a=0; x?*x:0; x++)  a += ROWSM(*x)+COLSM(*x);
		if (a!=msz)  {PROGERROR("lost or extra elements in the partition list! %d!=%d",msz,a);}
	}
	if (IFRANDDEBUGLESS(222) && ch>=0) {
		ematrix_transpose(ee);	/* extra debug testing with pivoted dual matrix */
		for (k=0; k<4; k++) {
			i = RANDOM()%ROWSM(ee);  j = RANDOM()%COLSM(ee);
			if (SIGNM(ee,i,j)!=0)  ematrix_pivot(ee,i,j);
		}
		k = struct_hasbwidth3_ext(-1,ee,NULL,NULL);
		if (k!=r)  {PROGERROR("wrong result when recursivly calling r%d o%d !",k,r);
				EMATDEBUG(0,ee," !r!\t"); EMATDEBUG(0,em," !o!\t");}
	}	/* (ee is modified here!!!) */
#endif
	dispose_alist_mats(list);
	dispose_ematrix(ee);
	if (lln && lln!=llnst)  FREE(lln);
	return r;
}
Exemplo n.º 15
0
void	frame_printtree_ext(FILE *fout, char *buf, framestruc *fr, int verb, char *pref,
						 int maxbuf, int maxson, int maxdepth) {
	framestruc	*ff, ***yr;
	ematrix		*ffem;
	int		*ir,*lr, ii,k,l, maxsl,maxsl2;
	char		bpr[100];
	
	if (!fout && !buf)  {PROGERROR("a file or a buffer must be given!"); return;}
	if (maxbuf<0 && buf)  {PROGERROR("maxbuf limit must be given when printing to a buffer!"); maxbuf=10;}
	if (maxdepth<0)  maxdepth = PTREE_MAXDEPTH;
	if (maxson<0)  maxson = PTREE_MAXSONS;
	maxsl = maxson/2;  maxsl2 = maxson/3;
	if (maxsl<2)  maxsl = 2;
	if (buf)  buf[0] = 0;
	yr = MMALLOC((maxdepth+2)*sizeof(yr[0]));
	ir = MMALLOC(2*(maxdepth+2)*sizeof(ir[0]));  lr = ir+maxdepth+2;
	
			/**
			 * Here we print the subtree of given fr:
			 * We start a depth-first search in the tree of fr,
			 * and we print each frame when it is reached the first time.
			 * The array yr[] is used to keep the current list of sons
			 * at each level of the search - incremented along the way.
			 * The array ir[] counts the printed sons, and lr[] keeps
			 * the lengths of the whole son lists.
			**/
	yr[0] = NULL;
	for (k=0; k>=0; ) {
		if (yr[k]==NULL) {
			yr[k] = (k<=0?&fr: FRSONS(*yr[k-1]));
			ir[k] = 0;
			lr[k] = (k<=0?1: alist_getlength(yr[k]));
			if (lr[k]<=0) { k--; continue; }
		} else {
			if (k>0)  yr[k]++;
			if (k<=0 || *yr[k]==NULL) { k--; continue; }
		}
			/**
			 * We print the actual frame *yr[k]=ff, according to buf and verb.
			 * However, if the list of sons is longer than the given limit maxson,
			 * then only first half and last third of them is printed which
			 * is indicated by a printed message.
			 * Printed format depends on buf/fout and on verb.
			**/
		ff = *yr[k];  ii = ++ir[k];
		if (lr[k]>maxson && maxsl<lr[k]-maxsl2 && verb<=1) {
			if (ii==maxsl) {
			  if (!buf)
				fprintf(fout,"%s%s%*s(%d.%d-%d) \t...  skipping sons in a long list  ...\n%s",
					(verb>0?"\n":""),pref,2*k,"",k+1,maxsl,lr[k]-maxsl2,(verb>0?"\n":""));
			  else if ((int)strlen(buf)<maxbuf-99-2*k)
			  	snprintf(buf+strlen(buf),90+2*k,"%s%s%*s(%d.%d-%d) ...  skipping sons in a long list  ...\n%s",
					(verb>0?"\n":""),pref,2*k,"",k+1,maxsl,lr[k]-maxsl2,(verb>0?"\n":""));
			}
			if (ii>=maxsl && ii<=lr[k]-maxsl2)  continue;
		}
		ffem = FRMATRIX(ff);
		if (!ffem)  bpr[0] = 0;
		else  snprintf(bpr,80,"m%dx%d",ROWSM(ffem),COLSM(ffem));
		if (buf) {
			l = strlen(buf);
			if (l<maxbuf-5)  snprintf(buf+l,maxbuf-l-4,"%*s(%d.%d)fr [%.15s] %s  \"%.*s\"\n",
				2*k,"",k+1,ii,FRNAME(ff),bpr,44-3*k,FRCOMMENT(ff)?FRCOMMENT(ff):"");
			buf[maxbuf-1] = 0;
		} else if (verb<=1) {
			fprintf(fout,"%s%*s(%d.%d)fr [%.15s] %s  \"%.*s\"\n",pref,2*k,"",
				k+1,ii,FRNAME(ff),bpr,55-3*k,FRCOMMENT(ff)?FRCOMMENT(ff):"");
		} else {
			if (verb>2)  fprintf(fout,"\n");
			snprintf(bpr,80,"%s%*s(%d.%d)  ",pref,3*k,"",k+1,ii);
			frame_print_ext(fout,ff,verb-1,(verb>3),bpr);
		}
			/**
			 * We dive deeper in the tree here (after printing the frame),
			 * unless the maximal given bound maxdepth is reached.
			 * Deeper frames in the tree are simply skipped.
			**/
		if (k<maxdepth)  yr[++k] = NULL;
		else if (FRSONS(*yr[k])!=NULL) {
			if (!buf)
				fprintf(fout,"%s%s%*s(%d.x) \t...  skipping too deeply nested frames  ...\n%s",
					(verb>0?"\n":""),pref,2*k+2,"",k+2,(verb>0?"\n":""));
			else if ((int)strlen(buf)<maxbuf-99-2*k)
			  	snprintf(buf+strlen(buf),90+2*k,"%s%s%*s(%d.x) \t...  skipping too deeply nested frames  ...\n%s",
					(verb>0?"\n":""),pref,2*k+2,"",k+2,(verb>0?"\n":""));
		}
	}
	if (fout && verb>2)  fprintf(fout,"\n");
	FREE(yr);  FREE(ir);
}