/*
 * subsetmatr.c
 *
 *
 * Part of TREE-PUZZLE 5.2 (February 2005)
 *
 * (c) 2003-2005 by Heiko A. Schmidt, Korbinian Strimmer, and Arndt von Haeseler
 * (c) 1999-2003 by Heiko A. Schmidt, Korbinian Strimmer,
 *                  M. Vingron, and Arndt von Haeseler
 * (c) 1995-1999 by Korbinian Strimmer and Arndt von Haeseler
 *
 * All parts of the source except where indicated are distributed under
 * the GNU public licence.  See http://www.opensource.org for details.
 *
 * ($Id$)
 *
 */


#include "subsetmatr.h"


/**********************/
void chooserfromsubsets(cmatrix ssmatr,
                        imatrix sssets,
                        ivector sssizes,
                        int     numsets,
                        int     numspecs,
                        ivector permutation)
{
	int i;
	int currset, currspec;
	int currid;
	int first;
	int setsize, setfreesize, setcount, speccount;
	ivector isfreespec, isfreeset, freeinsubset, subsetoverlap;

	isfreespec    = new_ivector(numspecs);
	for (i = 0; i < numspecs; i++) isfreespec[i] = TRUE;

	isfreeset     = new_ivector(numsets);
	for (i = 0; i < numsets; i++) isfreeset[i] = TRUE;

	freeinsubset   = new_ivector(numspecs);
	subsetoverlap = new_ivector(numsets);
	for (i = 0; i < numsets; i++) subsetoverlap[i] = 0;

	for (i = 0; i < numsets; i++) isfreeset[i] = TRUE;

	currid = 0;
	first = TRUE;

	for (setcount=0; setcount<numsets; setcount++) {
		/* random integer in the range [0, t-1-i] */
		do {
			currset = randominteger(numsets);
		} while(!((isfreeset[currset]) && ((subsetoverlap[currset] >= 3) || first)));
fprintf(stderr, "  %3d. %3d (OVL:%d)\n", setcount, currset, subsetoverlap[currset]);
		first = FALSE;
	
		isfreeset[currset] = FALSE;
		setsize = sssizes[currset];
		setfreesize = 0;
		for (speccount=0; speccount<setsize; speccount++) {
			currspec = sssets[currset][speccount];
			if (isfreespec[currspec]) {
				freeinsubset[setfreesize++] = currspec;
			} /* if isfreespec */
		} /* for speccount < setsize */

		for (speccount=0; speccount<setfreesize; speccount++) {
			do {
				currspec = randominteger(setfreesize);
			} while(!(isfreespec[freeinsubset[currspec]]));
	
			permutation[currid++] = freeinsubset[currspec];
			isfreespec[freeinsubset[currspec]] = FALSE;

			for (i=0; i<numsets; i++) {
				if (ssmatr[i][freeinsubset[currspec]] == 1) {
					(subsetoverlap[i])++;
				} 
			} /* for i */



		} /* for speccount */

	} /* for setcount */

#if 0
	for (i = 0; i < s; i++) {
		/* random integer in the range [0, t-1-i] */
		j = randominteger(t-i);
		k = -1;
		l = -1;
		do {
			k++;
			if (isfree[k] == TRUE) l++; 
		} while ( l != j);
		slist[i] = k;
		isfree[k] = FALSE;
	}
#endif

	free_ivector(subsetoverlap);
	free_ivector(freeinsubset);
	free_ivector(isfreeset);
	free_ivector(isfreespec);

} /* chooserfromsubsets */




/**********************/
void fprintsubsets(FILE  *fp,
                  imatrix sssets,
                  ivector sssizes,
                  int     subsets,
                  int     seqs)
{
	int ss; /* subset count */
	int sp; /* subset member count */
	for (ss=0; ss<subsets; ss++) {
		fprintf(fp, "subset[%3d] = ", ss, sssizes[ss]);
		for (sp=0; sp<sssizes[ss]; sp++) {
			fprintf(fp, "%3d ", sssets[ss][sp]);
		} /* for subsets size sp */
		fprintf(fp, "(%d) ", sssizes[ss]);
		fprintf(fp, "\n");
	} /* for all subsets ss */
} /*fprintsubsets */

/**********************/
void printsubsets(imatrix sssets,
                  ivector sssizes,
                  int     subsets,
                  int     seqs)
{
	fprintsubsets(stdout, sssets, sssizes, subsets, seqs);
} /*printsubsets */


/**********************/
void printssmatr(cmatrix subsetmatr,
                 int     subsets,
                 int     seqs)
{
	int n1, n2, x;
	if (subsets >= 100) {
		fprintf(stdout, "    | ");
		for (n1 = 0; n1 < subsets; n1++) {
			x = (n1-(n1%100))/100;
			if (x != 0) fprintf(stdout, "%2d", x);
			else        fprintf(stdout, "%2c", ' ');
		}
		fprintf(stdout, "\n");
	}
	if (subsets >= 10) {
		fprintf(stdout, "    | ");
		for (n1 = 0; n1 < subsets; n1++) {
			x = (n1-(n1%10))/10;
			if (x != 0) fprintf(stdout, "%2d", x);
			else        fprintf(stdout, "%2c", ' ');
		}
		fprintf(stdout, "\n");
	}
	fprintf(stdout, "seq | ");
	for (n1 = 0; n1 < subsets; n1++) fprintf(stdout, "%2d", n1%10);
	fprintf(stdout, "\n");
	fprintf(stdout, "----+-");
	for (n1 = 0; n1 < subsets; n1++) fprintf(stdout, "--");
	fprintf(stdout, "\n");

	for (n2 = 0; n2 < seqs; n2++) {
		fprintf(stdout, "s%3d| ", n2);
		for (n1 = 0; n1 < subsets; n1++) {
			fprintf(stdout, "%2c", ((1 == subsetmatr[n1][n2]) ? 'X' : '.'));
		}
		fprintf(stdout, "\n");
	}
} /* printssmatr */




/**********************/
void readssmatr(FILE    *fp,
                cmatrix *ssmatr,
                imatrix *sslists,
                ivector *sssizes,
                int     *subsets,
                int     *seqs)
{
	int setcount, speccount;

	*subsets = 0;
	*seqs = 0;

	/* read matrix coordinate sizes from file */
	fscanf(fp, "%d", subsets);
	fscanf(fp, "%d", seqs);
	printf("subsets: %d - seqs: %d\n\n", *subsets, *seqs);

	/* read to begin of the binary format matrix */
	while ('\n' != getc(fp));
	
	/* allocate memory */
	*ssmatr  = new_cmatrix(*subsets, *seqs);
	*sslists = new_imatrix(*subsets, *seqs);
	*sssizes = new_ivector(*subsets);

	/* initialze values */
	for (setcount = 0; setcount < *subsets; setcount++){
		(*sssizes)[setcount] = 0;
		for (speccount = 0; speccount < *seqs; speccount++){
			(*sslists)[setcount][speccount] = *seqs;
		} /* for speccount */
	} /* for setcount */
		

	/* read matrix from file */
	if((*subsets) * (*seqs) != fread(&((*ssmatr)[0][0]), sizeof(char), (*subsets) * (*seqs), fp)) {
		fprintf(stderr, "ERROR reading subset matrix from file!!!\n");
		tp_exit(1, NULL, FALSE, __FILE__, __LINE__, exit_wait_optn);
	}

	/* create subset lists/sizes */
	for (setcount = 0; setcount < *subsets; setcount++){
		for (speccount = 0; speccount < *seqs; speccount++){
			if ((*ssmatr)[setcount][speccount] == 1) {
				(*sslists)[setcount][((*sssizes)[setcount])] = speccount;
				((*sssizes)[setcount])++;
			} /* ssmatr == 1 */
		} /* for speccount */
	} /* for setcount */
} /* readssmatr */


/**********************/
void writessmatr(FILE    *fp, 
                 cmatrix  subsetmatr,
                 int      subsets,
                 int      seqs)
{
	fprintf(fp, " %d %d \n", subsets, seqs);
	if(subsets*seqs != fwrite(&(subsetmatr[0][0]), sizeof(char), subsets*seqs, fp)) {
		fprintf(stderr, "ERROR writing subset matrix to file!!!\n");
		tp_exit(1, NULL, FALSE, __FILE__, __LINE__, exit_wait_optn);
	}
} /* writessmatr */




