You should let your compiler help you find issues by compiling with (all) warnings enabled, and deal with every warning. Only add new code when it compiles (and works thus far) without errors, so you can concentrate on that added bit of code.
Originally Posted by
sdrabb
Code:
int * get_row_vector(element *matrix[],int index){
int row_vector[3];
...
return row_vector;
}
No, you cannot return a pointer to the local array, because the local array vanishes when the function returns. You need to allocate the memory dynamically. Also, you're very confident that the matrix only has three rows and three columns. I wouldn't be; sparse matrices are usually much, much larger.
If speed or efficiency is not an issue, then the following approach should work:
Code:
#include <stdlib.h>
#include <stdio.h>
struct node {
struct node *next;
int row;
int col;
double value;
};
/* Create a new matrix element.
*/
struct node *matrix_new(const int row, const int col,
const double val,
struct node *const next)
{
struct node *element;
element = malloc(sizeof *element);
if (!element) {
fflush(stdout);
fprintf(stderr, "new_node(): Out of memory.\n");
exit(EXIT_FAILURE);
}
element->next = next;
element->row = row;
element->col = col;
element->value = value;
return element;
}
/* Return the value of a matrix element.
*/
double matrix_element(const struct node *matrix,
const int row, const int col,
const double not_found)
{
while (matrix)
if (matrix->row == row && matrix->col == col)
return matrix->value;
else
matrix = matrix->next;
return not_found;
}
/* Find the size of a matrix.
* Returns 0 if valid size, nonzero if error.
*/
int matrix_size(const struct node *matrix,
int *const maxrowto,
int *const maxcolto)
{
int maxrow = -1;
int maxcol = -1;
while (matrix) {
if (maxrow < matrix->row)
maxrow = matrix->row;
if (maxcol < matrix->col)
maxcol = matrix->col;
matrix = matrix->next;
}
if (maxrow < 0 || maxcol < 0)
return 1;
if (maxrowto)
*maxrowto = maxrow;
if (maxcolto)
*maxcolto = maxcol;
return 0;
}
struct node *matrix_multiply(const struct node *const left,
const struct node *const right)
{
struct node *result = NULL;
int left_maxrow, left_maxcol;
int right_maxrow, right_maxcol;
int maxrow, maxcol, maxn;
int row, col, n;
/* Find out matrix sizes. */
if (matrix_size(left, &left_maxrow, &left_maxcol) ||
matrix_size(right, &right_maxrow, &right_maxcol))
return NULL;
maxrow = left_maxrow;
maxcol = right_maxcol;
/* Technically, the matrices should have
* left_maxcol == right_maxrow
* but since these are sparse, they may have
* zero rows or columns as necessary,
* so we just use the larger one. */
maxn = left_maxcol;
if (maxn < right_maxrow)
maxn = right_maxrow;
/* We do the loops in inverse order, so that when we
* prepend new elements to the list, the final matrix
* will have them in the correct order.
*/
for (row = maxrow; row >= 0; row--) {
for (col = maxcol; col >= 0; col--) {
double sum = 0.0;
for (n = maxn; n >= 0; n--) {
double left_value, right_value;
left_value = matrix_element(left, row, n, 0.0);
if (left_value == 0.0)
continue;
right_value = matrix_element(right, n, col, 0.0);
if (right_value == 0.0)
continue;
sum += left_value * right_value;
}
if (sum != 0.0)
result = matrix_new(row, col, sum, result);
}
}
/* Note: result == NULL, if the matrix is a zero matrix.
* If you want, you can avoid that by adding
* if (!result)
* result = matrix_new(maxrow, maxcol, 0.0);
*/
return result;
}
Of course, the above is slower than a pickled carrot in tar, and I didn't even bother to check if it compiles.