You will write a program estimate that uses a training data set to learn weights for a set of house attributes, and then applies those weights to a set of input data to calculate prices for those houses. estimate takes two arguments, which are the paths to files containing the training data and input data.

Respuesta :

Answer:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

double ** transpose(double ** m,int rows,int columns);

double ** multiply(double ** m1,double ** m2,int rows1,int rows2,int columns);

double * vmultiply(double ** m,double * v,int rows,int columns);

double ** inverse(double ** m,int rows);

int main(int argc,char ** argv) {

   FILE * f1 = NULL; //temp file variables

   FILE * f2 = NULL;

   FILE * t = NULL;

   FILE * d = NULL;

   char * filename1 = NULL;

   char * filename2 = NULL;

   char label[20] = {};  

   int columns,rows;

   double ** temp;

   double ** train;

   double ** data;

   double * prices;

   double * weights;

   double ** tr;

   double ** in;

   double ** r1;  

   double ** r2;

   double * r3;

   if (argc != 3) {

       printf("error\n");

       exit(0);

   }

   filename1 = argv[1];

   filename2 = argv[2];

   f1 = fopen(filename1,"r");

   f2 = fopen(filename2,"r");

   if (f1 == NULL || f2 == NULL) {

       printf("error\n");

       exit(0);

   }

   fscanf(f1,"%s\n",label);

   if ((strncmp(label,"train",5) == 0)) {

       t = f1;

       d = f2;

   } else {

       t = f2;

       d = f1;

   }

   fscanf(t,"%d\n",&columns);

   fscanf(t,"%d\n",&rows);

   columns++; //there are k+1 attributes

   train = (double **) malloc(rows * sizeof(double *));

   temp = (double **) malloc(rows * sizeof(double *));

 

   prices = (double *) malloc(rows * sizeof(double *));

   int i;

   for (i = 0; i < rows; i++) {

       train[i] = (double *) malloc(columns * sizeof(double));

       temp[i] = (double *) malloc(columns * sizeof(double));

       train[i][0] = 1; //make the first column all 1s

   }

   int j;

   for (i = 0; i < rows; i++) {

       for (j = 0; j < columns; j++) {

           fscanf(t,"%lf ",&temp[i][j]);

       }

       fscanf(t,"\n");

   }

   for (i = 0; i < rows; i++) {

       for (j = 1; j < columns; j++) {

           train[i][j] = temp[i][j-1];

       }

   }

   for (i = 0; i < rows; i++) {

       prices[i] = temp[i][columns-1];

   }

   tr = transpose(train,rows,columns);

   r1 = multiply(tr,train,columns,rows,columns);

   in = inverse(r1,columns);

   r2 = multiply(in,tr,columns,columns,columns);

   weights = vmultiply(r2,prices,columns,columns);

 

   fscanf(d,"%s\n",label);

   //make sure there aren't two training data file

   if (strncmp(label,"data",4) != 0) {

       printf("error\n");

       exit(0);

   }

   fscanf(d,"%d\n",&columns);

   fscanf(d,"%d\n",&rows);

   columns++; //there will me k+1 columns

 

   data = (double **) malloc(rows * sizeof(double *));

   for (i = 0; i < rows; i++) {

       data[i] = (double *) malloc(columns * sizeof(double));

       data[i][0] = 1; //make the first column all 1s

   }

   for (i = 0; i < rows; i++) {

       for (j = 1; j < columns; j++) {

           fscanf(d,"%lf ",&data[i][j]);

       }

       fscanf(d,"\n");

   }

   

   r3 = vmultiply(data,weights,rows,columns);

   for (i = 0; i < rows; i++) {

       printf("%.0f\n",r3[i]);

   }

   return 0;

}

double ** transpose(double ** m,int rows,int columns) {

 

   double ** t = (double **) malloc(columns * sizeof(double *));

   int i,j;

   for (i = 0; i < columns; i++) {

       t[i] = (double *) malloc(rows * sizeof(double));

   }

   for (i = 0; i < columns; i++) {

       for (j = 0; j < rows; j++) {

           t[i][j] = m[j][i];

       }

   }

   return t;

}

double ** multiply(double ** m1,double ** m2,int rows1,int rows2,int columns) {

   double ** t = (double **) malloc(rows1 * sizeof(double *));

   int i,j,k;

   for (i = 0; i < rows1; i++) {

       t[i] = (double *) malloc(columns * sizeof(double));

       //make every element 0 to prevent error

       for (j = 0; j < columns; j++) {

           t[i][j] = 0;

       }

   }

   for (i = 0; i < rows1; i++) {

       for (j = 0; j < columns; j++) {

           for (k = 0; k < rows2; k++) {

               t[i][j] += m1[i][k] * m2[k][j];

           }

       }

   }

   return t;

}

double * vmultiply(double ** m,double * v,int rows,int columns) {

   double * t = (double *) malloc(rows * sizeof(double));

   //make sure every element is preset to 0

   int i,j;

   for (i = 0; i < rows; i++) {

       t[i] = 0;

   }

   for (i = 0; i < rows; i++) {

       for (j = 0; j < columns; j++) {

           t[i] += m[i][j] * v[j];

       }

   }

   return t;

}

double ** inverse(double ** m,int size) {

 

   double ** id = (double **) malloc(size * sizeof(double *));

   int i,j,k;

   for (i = 0; i < size; i++) {

       id[i] = (double *) malloc(size * sizeof(double));

       for (j = 0; j < size; j++) {

           if (i == j) {

               id[i][j] = 1;

           } else {

               id[i][j] = 0;

           }

       }

   }

   for (int i = 0; i < size; i++) {

       double rec; //reciprocal value of the pivot

     

       if (m[i][i] != 1) {

           rec = 1/m[i][i];

           

           for (j = 0; j < size; j++) {

               m[i][j] *= rec;

               id[i][j] *= rec; //make the adjustment to the identity matrix

             

               if (m[i][j] == -0) m[i][j] = 0;

               if (id[i][j] == -0) id[i][j] = 0;

           }

       }

     

       for (k = i+1; k < size; k++) {

           double f; //factor of pivot value

           if (m[k][i] != 0) {

               f = m[k][i] * -1;

         

               int l;

               for (l = 0; l < size; l++) {

                   m[k][l] += (f*m[i][l]);

                   id[k][l] += (f*id[i][l]);

                 

                   if (m[k][l] == -0) m[k][l] = 0;

                   if (id[k][l] == -0) id[k][l] = 0;

               }

           }

       }

   }

  for (i = size-1; i >= 0; i--) {

      double rec;

      if (m[i][i] != 1) {

          rec = 1/m[i][i];

          for (j = 0; j < size; j++) {

              m[i][i] *= rec;

              id[i][i] *= rec;

              if (m[i][j] == -0) m[i][j] = 0;

              if (id[i][j] == -0) id[i][j] = 0;

          }

      }

      for (k = i-1; k >= 0; k--) {

           double f;

           if (m[k][i] != 0) {

               f = m[k][i] * -1;

           

               int l;

               for (l = 0; l < size; l++) {

                   m[k][l] += (f*m[i][l]);

                   id[k][l] += (f*id[i][l]);

                 

                   if (m[k][l] == -0) m[k][l] = 0;

                   if (id[k][l] == -0) id[k][l] = 0;

               }

           }

      }

  }

 

  return id;

}