Expand|Select|Wrap|Line Numbers
- #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);
- }