patterncMinor
Matrices in C implementation
Viewed 0 times
implementationmatricesstackoverflow
Problem
I recently wrote a C implementation of Matrices with add, subtract, and multiply. I want to expand this out eventually where I can diagonalize, efficiently square, row-reduce, etc...
I was wondering if there are any more efficient ways to do what I'm currently doing (I'm really new to C and pointers/references in general) and without changing too much, getting
to work like
Here's the code below
```
/**
Matrix Multiplication
matrices.c
Matrix data structure in C.
@author Michael Asper
@version 1.0 3/29/17
*/
#include
#include
#include
typedef struct Matrix {
int rowSize;
int columnSize;
long int* matrix;
} Matrix;
/**
Randomizes the elements of a matrix
@param *m pointer to Matrix to randomize;
*/
void randomize(Matrix *m){
int i,j;
for(i = 0; i rowSize ; i++){
for(j = 0; j columnSize; j++){
(m->matrix + im->rowSize + j)= rand() % 5000;
}
}
}
/**
Returns a r x c Matrix with all 0s.
@param r The row size of the matrix
@param c The column size of the matrix
@return r x c Matrix
*/
Matrix createMatrix(int r, int c){
Matrix temp = {r, c, calloc(r c, sizeof(long int ))};
return temp;
}
/**
Returns a r x c Matrix with random numbers.
@param r The row size of the matrix
@param c The column size of the matrix
@return r x c Matrix
*/
Matrix createRandMatrix(int r, int c){
Matrix temp = createMatrix(r,c);
randomize(&temp);
return temp;
}
/**
Prints matrix.
@param *m Pointer to Matrix you want to print
*/
void printMatrix(Matrix *m){
int i,j;
for(i = 0; i rowSize ; i++){
for(j = 0; j columnSize; j++){
printf("%li ", (m->matrix + im->rowSize + j));
}
printf("\n");
}
}
/**
Adds two matrices together
@param *a pointer to first matrix (A);
@param *b pointer to second matrix (B);
@ret
I was wondering if there are any more efficient ways to do what I'm currently doing (I'm really new to C and pointers/references in general) and without changing too much, getting
*(result.matrix+ i*r + j)to work like
result[i][j]Here's the code below
```
/**
Matrix Multiplication
matrices.c
Matrix data structure in C.
@author Michael Asper
@version 1.0 3/29/17
*/
#include
#include
#include
typedef struct Matrix {
int rowSize;
int columnSize;
long int* matrix;
} Matrix;
/**
Randomizes the elements of a matrix
@param *m pointer to Matrix to randomize;
*/
void randomize(Matrix *m){
int i,j;
for(i = 0; i rowSize ; i++){
for(j = 0; j columnSize; j++){
(m->matrix + im->rowSize + j)= rand() % 5000;
}
}
}
/**
Returns a r x c Matrix with all 0s.
@param r The row size of the matrix
@param c The column size of the matrix
@return r x c Matrix
*/
Matrix createMatrix(int r, int c){
Matrix temp = {r, c, calloc(r c, sizeof(long int ))};
return temp;
}
/**
Returns a r x c Matrix with random numbers.
@param r The row size of the matrix
@param c The column size of the matrix
@return r x c Matrix
*/
Matrix createRandMatrix(int r, int c){
Matrix temp = createMatrix(r,c);
randomize(&temp);
return temp;
}
/**
Prints matrix.
@param *m Pointer to Matrix you want to print
*/
void printMatrix(Matrix *m){
int i,j;
for(i = 0; i rowSize ; i++){
for(j = 0; j columnSize; j++){
printf("%li ", (m->matrix + im->rowSize + j));
}
printf("\n");
}
}
/**
Adds two matrices together
@param *a pointer to first matrix (A);
@param *b pointer to second matrix (B);
@ret
Solution
I just wanted to comment on your question about accessing the array efficiently. You ask:
I was wondering if there are any more efficient ways to do what I'm currently doing (I'm really new to C and pointers/references in general) and without changing too much, getting
to work like
One way is to do as @mdfst13 has recommended and allocate an array of arrays. That's a fine way to do it, but it can be a performance issue when accessing the array element by element in a loop. CPUs generally optimize to access the next few bytes past the last access since you're likely to need bytes near the ones you previously accessed. If you have a separate array per row, this can throw off that optimization when you reach the end of each row. You'd want to first profile to verify that's an issue or not. If it is, another option you have is to leave it as a single allocation and simply write an accessor function. Something like:
This also allows you the opportunity to do some range checking when in debug mode by doing something like:
(Or if you want to pass a pointer in instead of passing by value, as suggested in mdfst13's answer, you could change the prototype to take a pointer to a
Now when you want to access an element of the array, you would write:
It's not as concise as just
I was wondering if there are any more efficient ways to do what I'm currently doing (I'm really new to C and pointers/references in general) and without changing too much, getting
(result.matrix+ ir + j)to work like
result[i][j]One way is to do as @mdfst13 has recommended and allocate an array of arrays. That's a fine way to do it, but it can be a performance issue when accessing the array element by element in a loop. CPUs generally optimize to access the next few bytes past the last access since you're likely to need bytes near the ones you previously accessed. If you have a separate array per row, this can throw off that optimization when you reach the end of each row. You'd want to first profile to verify that's an issue or not. If it is, another option you have is to leave it as a single allocation and simply write an accessor function. Something like:
long int getElement(const Matrix m, const int r, const int c)
{
return *(m.matrix + r * m.rowSize + c);
}This also allows you the opportunity to do some range checking when in debug mode by doing something like:
long int getElement(const Matrix m, const int r, const int c)
{
#if DEBUG
assert((r >= 0) && (r = 0) && (c < m.colSize));
#endif
return *(m.matrix + r * m.rowSize + c);
}(Or if you want to pass a pointer in instead of passing by value, as suggested in mdfst13's answer, you could change the prototype to take a pointer to a
Matrix and dereference the fields via pointer.)Now when you want to access an element of the array, you would write:
long int x = getElement(result, i, j);It's not as concise as just
result[i][j], but it's better than writing out the math every time and potentially getting it wrong in some subtle way.Code Snippets
long int getElement(const Matrix m, const int r, const int c)
{
return *(m.matrix + r * m.rowSize + c);
}long int getElement(const Matrix m, const int r, const int c)
{
#if DEBUG
assert((r >= 0) && (r < m.rowSize));
assert((c >= 0) && (c < m.colSize));
#endif
return *(m.matrix + r * m.rowSize + c);
}long int x = getElement(result, i, j);Context
StackExchange Code Review Q#159301, answer score: 6
Revisions (0)
No revisions yet.