/* 
   Calculates utilistaion and throughput
   Based on xlinbcg.c from the nrc example disk
   9 / 8 / 95
*/

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define NRANSI
#include "nr.h"
#include "nrutil.h"

#define NSIZE 2000000  /* Storage size for the sparse matrix */

/* Prototype for sparse matrix input from file function */
void pwbin(int n, unsigned long nmax, double sa[], unsigned long ija[]);

/* Prototypes for timing functions */
void start_time(void);
void prn_time(void);

/* Prototypes for analysis functions */
double utilisation(double p[]);
double new_util(double p[]);
double throughput(double p[], double xi);
int probabliest(double p[], int size);

/* Sparse matrix storage space */
unsigned long ija[NSIZE+1];
double sa[NSIZE+1];


/* gcla - to convert between the two */
float saf[NSIZE+1];
#define MAXDIM 1024-1
float **a;
double **ad;


int main(int argc, char *argv[])
{
	int i,ii,iter;
	double *b,*x,err;
	long size;  /* Dimension of vectors */
        double xi;  /* Value of xi for throughput calculation */
	int itmax;  /* Maximum number of allowed iterations */
	int itol;   /* Convergence test to use (1,2,3, or 4) */
	double tol; /* Desired convergence tolerance */
	int logtol;
	char file_name[64];
	FILE *result_file;
	
	/* gcla */
	double gclatotal = 0;
	long n;
	int j;
	FILE *diag;
	FILE *offd;
	char eoln;
	float fx;

	if(argc != 7) {
		printf("Calculates utilisation & throughput using an iterative method\n");
		printf("Usage:  %s dim_of_b xi   max_it conv_test tol result-file\n", argv[0]);
		printf("Eg:     %s 17846    0.01 150    1         1e-9 test.res\n", argv[0]);
		exit(1);
	}

	start_time();

        sscanf(argv[1], "%ld", &size); /* Get stuff from command line */
        sscanf(argv[2], "%lf", &xi);
        sscanf(argv[3], "%d", &itmax);
        sscanf(argv[4], "%d", &itol);   /* set to 3 in script */
        sscanf(argv[5], "%lf", &tol);
	logtol = (log10(tol) < 0.0) ? ceil(-1*log10(tol)) : 1;
	sscanf(argv[6], "%s", file_name);
/* 	result_file = fopen(file_name, "w"); */
/* 	if (result_file == NULL) { */
/* 		printf("Error opening output file %s.\n", file_name); */
/* 		exit(1); */
/* 	} */

/* 	fprintf(stderr, "got to here 1\n"); */
/* 	fflush(stderr); */

	/* Set up b and x */
	b=dvector(1,size);
	x=dvector(1,size);
	for (i=1;i<=size;i++) {
		x[i]=0.0;         /* All of x is 0.0, as an initial estimate */
		b[i]=0.0;         /* All of b is 0.0 */
	}
	b[size] = 1.0;            /* Last element of b is 1.0 */

	/* Read in A */
	pwbin(size, NSIZE, sa, ija);

	/* gcla - the above is Stephen's routine for setting up sa and
           ija. Let's use the NR routine, by first reading in the
           array into the obvious 2D structure - can I get hold of the
           routine from the book? Yes. */
#if 0	
	n = size;

	/* allocate arrays */
	a = (float **)calloc(n+1, sizeof(float));
	for (i=0;i<=n;i++) 
	    a[i] = (float *)calloc(n+1, sizeof(float));
	
	ad = (double **)calloc(n+1, sizeof(double));
	for (i=0;i<=n;i++) 
	    ad[i] = (double *)calloc(n+1, sizeof(double));
	

	/* Initialise to zero */
	for (i=1;i<=n;i++) 
	    for (j=1;j<=n;j++) {
		a[i][j]=0.0;
		ad[i][j]=0.0;
	    }
	
/* 	fprintf(stderr, "got to here 1-1\n"); */
/* 	fflush(stderr); */

	/* Now read the diagonal entries */
	diag = fopen ("pwbsolve.dia", "r");
	if (diag == NULL) {
	    fprintf(stderr, "gcla - Could not open pwbsolve.dia\n");
	    exit(1);
	}
	else
	    printf("# gcla - Found pwbsolve.dia OK;\n");

	while (getc(diag) != EOF) {
	    fscanf (diag, "%i%i%f%c", &i, &j, &fx, &eoln);
/* 	    printf("setting index %d to %f\n", j, fx); */
	    a[j][j]=fx;
	}
	fclose (diag);

/* 	fprintf(stderr, "got to here 1-2\n"); */
/* 	fflush(stderr); */

	/* Now read the off diagonal entries */
	offd = fopen ("pwbsolve.off", "r");
	if (offd == NULL) {
	    fprintf(stderr, "gcla - Could not open pwbsolve.off\n");
	    exit(1);
	}
	else
	    printf("# gcla - Found pwbsolve.off OK\n");

	while (getc(offd) != EOF) {
	    fscanf (offd, "%i%i%f%c", &i, &j, &fx, &eoln);
/* 	    printf("setting index %d,%d to %f\n", i, j, fx); */
	    a[i][j]+=fx;
	}
	fclose (offd);

/* 	fprintf(stderr, "got to here 1-2-1\n"); */
/* 	fflush(stderr); */

	for (i=1;i<=n;i++) {
	    for (j=1;j<=n;j++) {
		printf("%f ", a[i][j]);
	    }
	    printf("\n");
	}

	
/* 	fprintf(stderr, "got to here 1-3\n"); */
/* 	fflush(stderr); */

	/* convert what I've read in. Note it's using floats! */
	sprsin(a, size, 0, NSIZE, saf, ija);

/* 	fprintf(stderr, "got to here 1-4\n"); */
/* 	fflush(stderr); */

	for (i=0; i<=NSIZE; i++)
	    sa[i] = (double)(saf[i]);


/* 	fprintf(stderr, "got to here 3\n"); */
/* 	fflush(stderr); */
#endif

	/* Then, like, solve it man */
	linbcg(size,b,x,itol,tol,itmax,&iter,&err);

/* 	fprintf(stderr, "got to here 2\n"); */
/* 	fflush(stderr); */

	/* How well did we do? */
	printf("# %s %15e\n","Estimated error:",err);
	printf("# %s %6d\n","Iterations needed:",iter);
/* 	fprintf(result_file, "%s %15e\n","Estimated error:",err); */
/* 	fprintf(result_file, "%s %6d\n","Iterations needed:",iter); */
/* 	fprintf(result_file, "%s %.15lf\n", "Throughput:", throughput(x, xi)); */
/* 	fprintf(result_file, "%s %.15lf %%\n", "Old utilisation:", utilisation(x)); */
/* 	fprintf(result_file, "%s %.15lf %%\n", "New utilisation:", new_util(x)); */
/* 	fprintf(result_file, "%s %6d\n", "Probabliest:", probabliest(x, size)); */

/* 	fprintf(stderr, "got to here 5\n"); */
/* 	fflush(stderr); */

/* 	prn_time(); */

/* 	printf("\nSolution vector:\n"); */
/* 	for (ii=1;ii<=size/5;ii++) { */
/* 	    for (i=5*(ii-1)+1;i<=5*ii;i++) printf("%12.6f",x[i]); */
/* 	    printf("\n"); */
/* 	} */
/* 	for (i=1;i<=(size % 5);i++) */
/* 	    printf("%12.6f",x[5*(size/5)+i]); */
/* 	printf("\n"); */

/* 	printf("\nSolution vector:\n"); */
/* 	for (ii=1;ii<=size/5;ii++) { */
/* 	    for (i=5*(ii-1)+1;i<=5*ii;i++) printf("%.15f ",x[i]); */
/* 	    gclatotal += x[i]; */
/* 	    printf("\n"); */
/* 	} */
/* 	for (i=1;i<=(size % 5);i++) */
/* 	    printf("%.15f",x[5*(size/5)+i]); */
/* 	    gclatotal += x[5*(size/5)+i]; */
/* 	printf("\n"); */
	
/* 	printf("\nSolution vector:\n"); */
/* 	for (ii=1;ii<=size;ii++) { */
/* 	    printf("%.15f\n",x[ii]); */
/* 	    gclatotal += x[ii]; */
/* 	} */

/* 	printf("\ngclatotal was %.15f",gclatotal); */

	printf("\n# Solution vector:\n");
	for (ii=1;ii<=size;ii++) {
	    printf("P[%d]:=%.15lf:\n",ii,x[ii]);
	    gclatotal += x[ii];
	}

	printf("\n# gclatotal was %.15lf",gclatotal);

/* 	fprintf(stderr, "got to here 6\n"); */
/* 	fflush(stderr); */

	free_dvector(x,1,size);
	free_dvector(b,1,size);

/* 	fprintf(stderr, "got to here 7\n"); */
/* 	fflush(stderr); */

	return(EXIT_SUCCESS);
}
#undef NRANSI
/* (C) Copr. 1986-92 Numerical Recipes Software 51&%. */
