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;
}