
// x is X; y is Y; p is the number of columns of x; n is the
// number of observations; s is the number of predictors per set; 
// preds is an s-column matrix with the indices of the predictor sets
// (numbered starting from 0, not 1)

// some supporting routines not shown

// divide row, length m, by divisor
void divrowbyc(float *row, int m, float c)
{  int j;
   for (j = 0; j < m; j++) row[j] /= c;
}

// subtract c times row2 from row1
void row1minusctimesrow2(float *row1, float *row2, int m, float c)
{  int j;
   for (j = 0; j < m; j++) row1[j] -= c * row2[j];
}

// solve matrix equation Ax = b; straight Gaussian elimination, no
// pivoting etc.; A,b are destroyed, and x is placed in b
void linsolv(float *a, float *b, int n)
{  int i,j,k,ii,ij,kj,ki; float aii,aki;
   for (i = 0; i < n; i++) {
      // divide row i
      ii = onedim(i,i,n);
      aii = a[ii];
      divrowbyc(&a[onedim(i,i,n)],n-i,aii);
      b[i] = b[i] / aii;
      // now adjust rows k != i
      for (k = 0; k < n; k++) {
         if (k != i) {
            ki = onedim(k,i,n);
            aki = a[ki];
            row1minusctimesrow2(&a[ki],&a[ii],n-i+1,aki);
            b[k] = b[k] - aki * b[i];
         }
      }
      ii = -1;
   }
}

#define MAX16 65535
#define MAX16F 65535.0
float unif(void) {  return (rand() % MAX16)/MAX16F;  }

int main(int ac, char **av)
{  int i,j,n,np,np1; float sum;
//    float x[12] = 
//       {1,2.0,2.0,
//        1,1.0,3.0,
//        1,1.8,2.8,
//        1,0.5,1.6};
//     float y[4] = {6.5,7.4,7.8,4.9};
//     float bh[3],xpx[9],xpy[3];
//     doreg(x,y,4,3,xpx,xpy);
//     for (i = 0; i < 3; i++) printf("%f\n",xpy[i]);
       n = atoi(av[1]); 
       np = atoi(av[2]); 
       np1 = np + 1;
       float *x = malloc(n*np1*sizeof(float));
       float *y = malloc(n*sizeof(float));
       float *xpx = malloc(np1*np1*sizeof(float));
       float *xpy = malloc(np1*sizeof(float));
       for (i = 0; i < n; i++) {
          x[onedim(i,1,np1)] = 1;
          sum = 0.0;
          for (j = 1; j < np1; j++) {
             x[onedim(i,j,np1)] = unif();
             sum += x[onedim(i,j,np1)];
          }
          y[i] = sum + unif();
       }
       doreg(x,y,n,np1,xpx,xpy);
}

