Code:
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
struct SMatrix
{
double** pValues;
int nR,nC;
};
#define MAX_COLUMN 30
#define MAX_ROW 30
void menu();
int input_operation();
void evaluate(int operation, float matrix[][MAX_ROW]);
void addition(float matrix[][MAX_ROW]);
void scalar_multiplication(float matrix[][MAX_ROW]);
void matrix_multiplication(float matrix[][MAX_ROW]);
void transpose(float matrix[][MAX_ROW]);
struct SMatrix* inverse(float matrix[][MAX_ROW]);
struct SMatrix* invert(float matrix[][MAX_ROW], int n);
struct SMatrix* echelon(float m[(2*MAX_COLUMN)][MAX_ROW], int n);
int find_max_row(float m[(2*MAX_COLUMN)][MAX_ROW], int cur_column, int start_row, int end);
void reduce_echelon(float m[(2*MAX_COLUMN)][MAX_ROW], int index, int n);
void reverse_echelon(float m[][MAX_ROW], int index, int n);
void canonical_form(float m[][MAX_ROW], int index, int n);
float get_product(float a[][MAX_ROW], float b[][MAX_ROW], int cur_col, int cur_row, int p);
int get_size();
float get_values();
int input_scalar();
void print_matrix(float m[][MAX_ROW], int column, int row);
/*
* This function is used to obtain the inverse of a matrix nxn. If the matrix input is not a
* square matrix, it prints out a message indicating that matrix is not invertible.
* Arguments:
* matrix: an array where the values of the matrix are stored
* size: an array where the size of the matrix are temporarily stored when obtained from the user
* column, row: the size of the matrix
* i, cur_column, cur_row: indices, counters
*
*/
struct SMatrix* inverse(struct SMatrix* A)
{
int i,j;
float matrix[30][MAX_ROW];
for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
matrix[i][j]=A->pValues[i][j];
}
}
int column=A->nR;
return invert(matrix, column);
}
/*
* This function is a subfunction of inverse. It creates an augmented matrix M[A|I] used to
* work with Gaussian Elimination to get the inverse of a matrix where A is the matrix and
* I is the identity matrix.
* Arguments:
* matrix: an array where the values of the matrix input are stored
* m: an array where the values of the augmented matrix are stored
* i: the identity matrix
*
*/
struct SMatrix* invert(float matrix[][MAX_ROW], int n)
{
float m[(2*MAX_COLUMN)][MAX_ROW]; /*augmented matrix*/
float i[MAX_COLUMN][MAX_ROW]; /*identity*/
int cur_row;
int cur_column;
/*identity*/
for (cur_row = 0; cur_row < n; cur_row++)
{
for (cur_column = 0; cur_column < n; cur_column++)
{
if (cur_row == cur_column)
{
i[cur_column][cur_row] = 1;
}
else
{
i[cur_column][cur_row] = 0;
}
}
}
/*augmented matrix, 1st half*/
for (cur_row = 0; cur_row < n; cur_row++)
{
for (cur_column = 0; cur_column < n; cur_column++)
{
m[cur_column][cur_row] = matrix[cur_column][cur_row];
}
}
/*augmented matrix, 2nd half*/
for (cur_row = 0; cur_row < n; cur_row++)
{
for (cur_column = n; cur_column < (2 * n); cur_column++)
{
m[cur_column][cur_row] = i[(cur_column - n)][cur_row];
}
}
return echelon(m, n);
}
/*
* This is a subfunction of inverse where the augmented matrix is being reduced to echelon
* form. If through the process of row operations a row zeros is obtained at the left side of
* the augmented matrix or if any of the diagonal values is zero, it prints out an error
* message that the matrix has no inverse.
* Arguments:
* m: the augmented matrix
* n: the size of the matrix being inverted
* inverse: an array to store the values of the inverted matrix
* temp: a temporary storage
*/
struct SMatrix* echelon(float m[(2*MAX_COLUMN)][MAX_ROW], int n)
{
int i; /*counter*/
int cur_row;
int cur_column;
float inverse[MAX_COLUMN][MAX_ROW];
float temp;
/*pivoting and swapping of rows*/
for (i = 0; i < (n-1); i++)
{
for (cur_row = i; cur_row < n; cur_row++)
{
int row_index_max = find_max_row(m, i, cur_row, n);
for (cur_column = 0; cur_column < (2*n); cur_column++)
{
temp = m[cur_column][cur_row];
m[cur_column][cur_row] = m[cur_column][row_index_max];
m[cur_column][row_index_max] = temp;
}
}
reduce_echelon(m, i, n);
if (m[i][i] == 0)
{
printf("\nMatrix has no inverse!\n\n");
}
}
/*reverse row operations*/
for (i = (n-1); i > 0;i--)
{
reverse_echelon(m, i, n);
}
/*reduces m to canonical form*/
for (i = 0; i < n; i++)
{
canonical_form(m, i, n);
}
/*gets the inverse*/
for (cur_row = 0; cur_row < n; cur_row++)
{
for (cur_column = 0; cur_column < n; cur_column++)
{
inverse[cur_column][cur_row] = m[(cur_column + n)][cur_row];
}
}
int r,t;
struct SMatrix* Y;
Y->nC=3;
Y->nR=3;
for (r=0;r<3;r++)
{
for (t=0;t<3;t++)
{
Y->pValues[r][t]=inverse[r][t];
}
}
return (Y);
}
/*
* This function is used to obtain the row which has the leading non-zero entry, an important
* parameter in doing elementary row operations in obtaining the echelon form of an augmented
* matrix.
* Arguments:
* m: the augmented matrix
* cur_column, start_row, end: indices and counters
* index_max_row: the index of the row which has the leading non-zero entry
* Returns a value.
*
*/
int find_max_row(float m[(2*MAX_COLUMN)][MAX_ROW], int cur_column, int start_row, int end)
{
int index_max_row = start_row;
int cur_row;
for (cur_row = start_row; cur_row < end; cur_row++)
{
if (m[cur_column][cur_row] > m[cur_column][index_max_row])
{
index_max_row = cur_row;
}
}
return index_max_row;
}
/*
* This function is used to get the echelon form of the augmented matrix.
* Arguments:
* m: the augmented matrix
* index: the current index of the values of the augmented matrix being reduced to echelon
* n: the size of the matrix nxn being inverted
* temp: temporary storage
* factor: the factor used to reduce the values of the matrix into echelon
*
*/
void reduce_echelon(float m[(2*MAX_COLUMN)][MAX_ROW], int index, int n)
{
int cur_row;
int cur_column;
float temp;
float factor;
for (cur_row = index; cur_row < (n-1); cur_row++)
{
factor = m[index][(cur_row + 1)]/m[index][index];
for (cur_column = index; cur_column < (n * 2); cur_column++)
{
temp = m[cur_column][(cur_row + 1)] - (factor * m[cur_column][index]);
m[cur_column][(cur_row + 1)] = temp;
}
}
}
/*
* This function is used for the reverse elementary row operations.
*
*/
void reverse_echelon(float m[(2*MAX_COLUMN)][MAX_ROW], int index, int n)
{
int cur_row;
int cur_column;
float temp;
float factor;
for (cur_row = index; cur_row > 0; cur_row--)
{
factor = m[index][(cur_row - 1)]/m[index][index];
for (cur_column = index; cur_column < (2 * n); cur_column++)
{
temp = m[cur_column][(cur_row - 1)] - (factor * m[cur_column][index]);
m[cur_column][(cur_row -1)] = temp;
}
}
}
/*
* This function is used to obtain the canonical form of the reduced echolon form of the
* augmented matrix.
*
*/
void canonical_form(float m[(2*MAX_COLUMN)][MAX_ROW], int index, int n)
{
int cur_column;
float temp;
float factor;
factor = m[index][index];
for (cur_column = index; cur_column < (n*2); cur_column++)
{
temp = m[cur_column][index]/factor;
m[cur_column][index] = temp;
}
}
/*
* This function is used to obtain the value of ijth entry of the product matrix.
* Arguments:
* a, b: arrays where the values of the matrices A and B are stored
* cur_col: the index of the current column value of the product
* p: equivalent to the row of A and column of B
* sum: the value of the ijth entry of the product of matrices A and B
* product: temporary storage of the product of the ith row of A and jth column of B
* Returns a value.
*
*/
float get_product(float a[][MAX_ROW], float b[][MAX_ROW], int cur_col, int cur_row, int p)
{
float sum = 0;
float product;
int i;
for (i = 0; i < p; i++)
{
product = a[cur_col][i] * b[i][cur_row];
sum = sum + product;
}
return sum;
}
/*
* This function is used to get the size of a matrix.
* Arguments:
* n: a variable where to store the size input by the user
* Returns a value.
*
*/
int get_size()
{
int n;
scanf("%d", &n);
return n;
}
/*
* This function is used to get the values of a matrix. It scans values in fractional form
* (+|-)value_1/value_2 or in decimal form (+|-)value_1.value_2 where:
* +,- is the sign
* value_1 is the numerator (fractional form) and whole number (decimal form)
* value_2 is the denominator (fractional form) and decimal value up to 2 digits (decimal form)
* Arguments:
* matrix: an array to store the values of the matrix
* cur_column, cur_row: the indices where to store the value in the array
*
*/
float get_values()
{
int n;
scanf("%d", &n);
return n;
/*
if (dummy == SLASH)
{
value = (float)(value_1/value_2);
}
else if (dummy == POINT)
{
value = (float)((value_1 * 100)+ value_2)/ 100;
}
if (sign == POS)
{
value = value;
}
else if (sign == NEG)
{
value = -(value);
}
*/
// matrix[cur_column][cur_row] = value;
}
/*
* This function displays the resulting matrix derived from the operations.
* Arguments:
* msg: the message from which the matrix was derived
* matrix: an array where the values of the matrix are stored
* column, row: the size of the matrix
*
*/
void print_matrix(float matrix[][MAX_ROW], int column, int row)
{
int cur_row;
int cur_column;
printf("Size: %d %d\n", column, row);
for (cur_row = 0; cur_row < row; cur_row++)
{
for (cur_column = 0; cur_column < column; cur_column++)
{
if (matrix[cur_column][cur_row] >= 0)
{
printf("+%f ", matrix[cur_column][cur_row]);
}
else
{
printf("%f ", matrix[cur_column][cur_row]);
}
}
printf("\n");
}
}
void PrintMatrix(struct SMatrix* pM)
{
int r,c;
for (r=0;r<pM->nR;r++)
{
for(c=0;c<pM->nC;c++)
{
printf("%5.5f\t\t", pM->pValues[r][c]);
}
printf("\n");
}
}
/*
* This function obtains the scalar constant where the value can be any integer (+/-).
* Arguments:
* value: where the integer is stored
* sign: where the sign of the integer is stored
* POS: constant character equivalent to (+) sign
* NEG: constant character equivalent to (-) sign
* Returns a value.
*
*/
enum MFILLTYPE{MFT_NONE, MFT_ZEORS, MFT_ONES, MFT_RAND, MFT_JEDENTITY};
struct SMatrix* CreateMatrix(int nR,int nC,enum MFILLTYPE fillType)
{
int r,c;
struct SMatrix* pRM;
pRM =(struct SMatrix*)malloc(sizeof(struct SMatrix));
pRM->nR = nR;
pRM->nC = nC;
//Allocate the matrix, the matrix is an array of pointer to rows pointers
pRM->pValues = (double**)malloc(nR * sizeof(double*));
//Allocate the rows, each row will point to all row elements for(r=0;r<nR;r++)
for (r=0;r<nR;r++)
pRM->pValues[r] = (double*)malloc(nC * sizeof(double));
if(fillType!=MFT_NONE)
{
for(r=0;r<nR;r++)
for(c=0;c<nC;c++)
{
switch(fillType)
{
case MFT_ZEORS:
pRM->pValues[r][c] = 0; break;
case MFT_ONES:
pRM->pValues[r][c] = 1; break;
case MFT_RAND:
pRM->pValues[r][c] = (rand()%100)/100.0; break;
}
}
}
return pRM;
}
void main ()
{
struct SMatrix *A,*B;
A=CreateMatrix(3,3,MFT_RAND);
B=inverse(A);
PrintMatrix(B);
}
Comment