#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct matrix_s{
char *name;
double **element;
long columns;
long rows;
}matrix_t;
typedef enum boolean_e{
FALSE = 0,
TRUE = 1
} boolean_t;
matrix_t *matrix_allocate(long columns, long rows, char *name)
{
long i,j;
matrix_t *m=calloc(1,sizeof(matrix_t));
m->name=malloc(strlen(name));
strcpy(m->name,name);
m->rows = rows;
m->columns = columns;
m->element=calloc(rows,sizeof(double*));
if(!m->name || !m->element)
{
fprintf(stderr,"Alloc error!");
free(m);
return 0;
}
for(i=0;i<rows;i++)
{
m->element[i]=calloc(columns,sizeof(double));
if(!m->element[i])
{
fprintf(stderr,"alloc error");
for(j=0;i<i;j++)
free(m->element[j]); //bisherigen wieder freigeben
free(m->element);
free(m->name);
free(m);
return 0;
}
}
return m;
}
boolean_t matrix_insert(matrix_t *m,long columns,long rows,double val)
{
boolean_t status=FALSE;
if(!m) return status;
if(columns<0 || rows<0 || columns>=m->columns || rows>=m->rows) return status;
m->element[rows][columns] = val;
return status=TRUE;
}
boolean_t matrix_free(matrix_t *m)
{
boolean_t status=FALSE;
if(!m) return status;
long i;
for(i=0;i<m->rows;i++)
free(m->element[i]);
free(m->element);
if(m->name) free(m->name);
free(m);
return status=TRUE;
}
void matrix_print(matrix_t *m)
{
long i,j;
if(!m) return;
for(i=0;i<m->rows;i++)
{
for(j=0;j<m->columns;j++)
printf("%5g",m->element[i][j]);
printf("\n");
}
printf("----------------\n");
}
void test_matrix(matrix_t *m)
{
long i,j;
if(!m)
{
fprintf(stderr, "Nullpointer\n");
return;
}
for(i=0;i<m->rows;i++)
{
for(j=0;j<m->columns;j++)
m->element[i][j]=i+j;
}
matrix_print(m);
}
boolean_t gauss_forward(matrix_t *m,matrix_t *rs)
{
boolean_t status=FALSE;
long i,j,k;
if(!m || !rs)
{
fprintf(stderr, "Nullpointer\n");
return status;
}
for(i=0;i<=m->columns-2;i++)
{
for(j=i+1;j<=m->rows-1;j++)
{
for(k=i+1;k<=m->columns-1;k++)
{
if((m->element[i][i])==0)
{
fprintf(stderr,"DIV 0");
return 0;
}
m->element[j][k]=m->element[j][k]-(m->element[j][i]/m->element[i][i])*m->element[i][k];
}
if((m->element[i][i])==0)
{
fprintf(stderr,"DIV 0");
return 0;
}
rs->element[j][0]=rs->element[j][0]-(m->element[j][i]/m->element[i][i])*rs->element[i][0];
for(k=0;k<=i;k++)
m->element[j][k]=0;
}
}
return status=TRUE;
}
boolean_t gauss_backward(matrix_t *m,matrix_t *rs,matrix_t *sol)
{
long i,j;
double sum=0;
boolean_t status=FALSE;
if(!m || !rs || !sol)
{
fprintf(stderr, "Nullpointer\n");
return status;
}
for(i=m->rows-1;i>=0;i--)
{
sum=0;
for(j=i;j<=m->columns-1;j++)
{
sum=sum+(m->element[i][j]*sol->element[j][0]);
}
if((m->element[i][i])==0)
{
fprintf(stderr,"DIV 0");
return 0;
}
sol->element[i][0] = (rs->element[i][0]-sum)/m->element[i][i];
}
return status=TRUE;
}
boolean_t gauss_solve(matrix_t *m, matrix_t *rs, matrix_t *sol)
{
boolean_t status=FALSE;
if(!m || !rs || !sol)
{
fprintf(stderr, "Nullpointer\n");
return status;
}
if(m->columns != m->rows)
{
fprintf(stderr, "Wrong Dimension\n");
return status;
}
if(!gauss_forward(m, rs))
{
fprintf(stderr, "Error in gauss_forward\n");
return status;
}
if(!gauss_backward(m, rs, sol))
{
fprintf(stderr, "Error in gauss_backward\n");
return status;
}
matrix_print(sol);
return status=TRUE;
}
boolean_t matrix_fill(matrix_t *m,long dim)
{
long c=0,val,i,j,k=0;
FILE *fp;
char x[10];
printf("stdin (1) or file (2) ?\n");
scanf("%ld",&c);
fflush(stdin);
switch(c)
{
case 1 : for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
{
printf("%ld.%ld.: ",i,j);
scanf("%ld",&val);
fflush(stdin);
matrix_insert(m,j,i,val);
}
break;
case 2 : if((fp=fopen("test.csv","r"))) //Trennung mit ;
{
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
{
while(x[k-1]!=';')
{
x[k]=fgetc(fp);
k++;
}
k=0;
matrix_insert(m,j,i,atof(x));
}
fclose(fp);
}
break;
}
return 1;
}
int main()
{
long c=0, i, dim;
double val=0;
matrix_t *m=0, *rs=0, *sol=0;
do
{
printf("1. Create + Fill\n");
printf("2. Print\n");
printf("3. Gauss Solve\n");
printf("0. Exit\n");
scanf("%ld", &c);
fflush(stdin);
switch(c)
{
case 1:
printf("Dimension? ");
scanf("%ld",&dim);
fflush(stdin);
m=matrix_allocate(dim,dim,"Matrix1");
matrix_fill(m,dim);
break;
case 2:
matrix_print(m);
break;
case 3:
rs=matrix_allocate(1, dim, "Right Side");
sol=matrix_allocate(1, dim, "Solve");
for(i=0;i<dim;i++)
{
printf("%d.%ld: ", 1, i+1);
scanf("%lf", &val);
rs->element[i][0]=val;
}
matrix_print(m);
printf("Right Side:\n");
matrix_print(rs);
gauss_solve(m,rs,sol);
matrix_free(m);
matrix_free(rs);
matrix_free(sol);
break;
}
} while(c!=0);
return 0;
}