/* To compile, use
     cc -o makegrid makegrid.c
   To run, use
     makegrid n1 n2 n3 ...
   where ni is the number of levels for the ith factor in the grid.
   The program prompts for the level values which eventually get
   printed.  Naturally, in practice the loop starting with
   "while(!done)" could be entered as soon as the following
   information was available:
       n - the number of factors
       nlevs[] - the number of levels of each factor
       vals[][] - the values of the levels for each factor
*/

#include <stdio.h>
#include <stdlib.h>

main(int argc, char **argv)
{

  int n = argc - 1;
  int i,j,done;
  double **vals;
  int *nlevs,*lnow;

  /* n is the number of factors;  nlevs holds the number of levels for 
                                  each of the factors */
  nlevs = (int*)malloc((unsigned)(n * sizeof(int)));
  if(nlevs == NULL){
    fprintf(stderr,"Couldn't allocate space for nlevs, n=%d\n",n);
    exit(1);
    }
  for(i=0;i<n;i++)nlevs[i] = atoi(argv[i + 1]);
  
  /* lnow keeps track of the current level of each of the factors */
  lnow = (int*)malloc((unsigned)(n * sizeof(int)));
  if(lnow == NULL){
    fprintf(stderr,"Couldn't allocate space for lnow, n=%d\n",n);
    exit(1);
    }


  /* vals holds the values for the different levels of each factor */
  vals = (double**)malloc((unsigned)(n * sizeof(double*)));
  if(vals == NULL){
    fprintf(stderr,"Couldn't allocate space for vals, n=%d\n",n);
    exit(1);
    }
  for(i=0;i<n;i++){
	vals[i] = (double*)malloc((unsigned)(nlevs[i] * sizeof(double)));
	if(vals[i] == NULL){
          fprintf(stderr,"Couldn't allocate space for vals[i], nlevs[i]=%d\n",nlevs[i]);
          exit(1);
          }
      }

  for(i=0;i<n;i++){
	fprintf(stderr,"Enter the %d values for factor %d: ",nlevs[i],i + 1);
	for(j=0;j<nlevs[i];j++)scanf("%lf",vals[i] + j);
	}

  /* start each factor at the lowest level */
  for(i=0;i<n;i++)lnow[i] = 0;

  done = 0;
  while(!done){
	for(j=n-1;j>=0;j--){
	       /* if we've gone past the number of levels for a 
                  factor, increase the level of the next factor,
                  and set lnow for this factor to 0 */
		if(lnow[j] == nlevs[j]){
                       /* if we've gone past the last factor, we're done */
			if(j == 0)done = 1;
			lnow[j - 1]++;
			lnow[j] = 0;
			}
		}
	if(done)break;
        /* if we're not done yet, this is a valid combination of levels */
	for(j=0;j<n;j++)printf("%lf ",vals[j][lnow[j]]);
	printf("\n");
	lnow[n - 1]++;
	}
}

