arrays - Static Matrix multiplication to dynamic matrix in c -


i need build program make matrix multiplication. when have 2 static matrix, , function return pointer new dynamic matrix.

my problem make multiplication right when i'm moving matrix function.

main is:

    int f_matrix[ex2_size][ex2_size] = { {1,2,3}, {1,4,7},{1,5,9} }; int s_matrix[ex2_size][ex2_size] = { {9,8,7},{4,5,6},{0,9,6} }; int m1_rows = ex2_size, m1_cols = ex2_size;  int m2_rows = ex2_size, m2_cols = ex2_size; //for tester can change int **new_matrix;  if (m1_rows != m2_rows || m1_cols != m2_cols) return 0;  //for multiplying must equal matrix !!  new_matrix = multiplying(f_matrix, s_matrix, m1_rows, m1_cols); print_mtrx(new_matrix, m1_rows, m1_cols); free_mtrx(new_matrix, m1_cols); 

the problem in "multiplying" function, , here it:

int multiplying(int **a, int **b, int rows, int cols) { int **c; int i,j; c = (int**)malloc(sizeof(int*)*rows); (i = 0; < cols; i++) {     c[i] = (int*)malloc(sizeof(int)*cols);         (j = 0; j < cols; j++)             c[i][j] = (a[i][j]) * (b[i][j]); }  return c; } 

thx

assuming c99 (or c11 , implementation not define __stdc_no_vla__), simplest approach use variable length arrays (vlas) , have calling code allocate space result matrix too. multiply 2 matrices, a[m][n] , b[p][q] in order, values of n , p must equal , result matrix c[m][q].

#include <stdio.h>  static void matrix_multiply(int a_rows, int a_cols, int b_cols,                      int a[a_rows][a_cols],                      int b[a_cols][b_cols],                      int c[a_rows][b_cols]) {     (int = 0; < a_rows; i++)     {          (int j = 0; j < b_cols; j++)          {               int sum = 0;               (int k = 0; k < a_cols; k++)                   sum += a[i][k] * b[k][j];               c[i][j] = sum;          }     } }  static void print_matrix(const char *tag, int w, int n, int m, int matrix[n][m]) {     printf("%s (%dx%d):\n", tag, n, m);     (int = 0; < n; i++)     {          (int j = 0; j < m; j++)              printf("%*d", w, matrix[i][j]);          putchar('\n');     } }  int main(void) {     int a[3][4] =     {         { 41, 76, 70, 42, },         { 70, 62, 77, 74, },         { 49, 55, 43, 65, },     };     int b[4][5] =     {         { 73, 33, 42, 72, 65, },         { 69, 30, 83, 83, 64, },         { 90, 74, 84, 51, 23, },         { 62, 45, 84, 46, 43, },     };     int c[3][5];     print_matrix("a", 3, 3, 4, a);     print_matrix("b", 3, 4, 5, b);     matrix_multiply(3, 4, 5, a, b, c);     print_matrix("c", 6, 3, 5, c);     return 0; } 

output:

a (3x4):  41 76 70 42  70 62 77 74  49 55 43 65 b (4x5):  73 33 42 72 65  69 30 83 83 64  90 74 84 51 23  62 45 84 46 43 c (3x5):  17141 10703 17438 14762 10945  20906 13198 20770 17517 13471  15272  9374 15695 13276 10489 

if want dynamic memory allocation, think have pass pointer pointer vla array function value returned. leads code this, similar previous code — except (unchecked) memory allocation. note because uses static_assert, c11 program, not c99 program.

#include <assert.h> #include <stdio.h> #include <stdlib.h>  #ifdef __stdc_no_vla__      // c11 static_assert(0, "no vla support"); #endif  static void matrix_multiply(int a_rows, int a_cols, int b_cols,                             int a[a_rows][a_cols], int b[a_cols][b_cols],                             int (**c)[b_cols]) {     (*c) = malloc(sizeof(int [a_rows][b_cols]));  // xxx: check memory allocation!     (int = 0; < a_rows; i++)     {          (int j = 0; j < b_cols; j++)          {               int sum = 0;               (int k = 0; k < a_cols; k++)                   sum += a[i][k] * b[k][j];               (*c)[i][j] = sum;          }     } }  static void print_matrix(const char *tag, int w, int n, int m, int matrix[n][m]) {     printf("%s (%dx%d):\n", tag, n, m);     (int = 0; < n; i++)     {          (int j = 0; j < m; j++)              printf("%*d", w, matrix[i][j]);          putchar('\n');     } }  int main(void) {     enum { n = 3, m = 4, p = 4, q = 5 };     int a[n][m] =     {         { 41, 76, 70, 42, },         { 70, 62, 77, 74, },         { 49, 55, 43, 65, },     };     int b[p][q] =     {         { 73, 33, 42, 72, 65, },         { 69, 30, 83, 83, 64, },         { 90, 74, 84, 51, 23, },         { 62, 45, 84, 46, 43, },     };     static_assert(m == p, "matrix dimensions mismatched");     int (*c)[q];     print_matrix("a", 3, n, m, a);     print_matrix("b", 3, p, q, b);     matrix_multiply(n, m, q, a, b, &c);     print_matrix("c", 6, n, q, c);     free(c);     return 0; } 

this produces same output before, of course.


analyzing original code

here's fixed variant of original code.

#include <stdio.h> #include <stdlib.h>  static void free_mtrx(int **mtrx, int rows) {     (int = 0; < rows; i++)         free(mtrx[i]);     free(mtrx); }  static int **multiplying_1(int **a, int **b, int rows, int cols) {     int **c;     c = (int **)malloc(sizeof(int *) * rows);     (int = 0; < cols; i++)     {         c[i] = (int *)malloc(sizeof(int) * cols);         (int j = 0; j < cols; j++)             c[i][j] = (a[i][j]) * (b[i][j]);     }     return c; }  static void print_mtrx(const char *tag, int w, int n, int m, int **matrix) {     printf("%s (%dx%d):\n", tag, n, m);     (int = 0; < n; i++)     {         (int j = 0; j < m; j++)             printf("%*d", w, matrix[i][j]);         putchar('\n');     } }  int main(void) {     enum { ex2_size = 3, ex3_size = 3 };     int f_matrix[ex2_size][ex2_size] = { {1, 2, 3}, {1, 4, 7}, {1, 5, 9} };     int s_matrix[ex2_size][ex2_size] = { {9, 8, 7}, {4, 5, 6}, {0, 9, 6} };     int m1_rows = ex2_size, m1_cols = ex2_size;     int m2_rows = ex2_size, m2_cols = ex2_size; // tester can change     int *f[] = { &f_matrix[0][0], &f_matrix[1][0], &f_matrix[2][0] };     int *s[] = { &s_matrix[0][0], &s_matrix[1][0], &s_matrix[2][0] };     int **new_matrix;      if (m1_rows != m2_rows || m1_cols != m2_cols)         return 0;      print_mtrx("f", 3, ex2_size, ex2_size, f);     print_mtrx("s", 3, ex3_size, ex3_size, s);      new_matrix = multiplying(f, s, m1_rows, m1_cols);     print_mtrx("r", 3, m1_rows, m1_cols, new_matrix);     free_mtrx(new_matrix, m1_cols);      return 0; } 

granted, 'matrix multiplication' algorithm isn't conventional mathematical one; that's not major issue. key point int **matrix not same int matrix[n][m]. latter consists solely of integer values; former array of pointers, each of points series of integer values. prototype multiplying() in scope, compiler complained original calls. manufactured array of pointers arrays of integers when creating matrices f , s f_matrix , s_matrix. note body of print_mtrx() function identical body of print_matrix() functions in previous 2 programs. however, code generated not same because argument lists use 2 different, incompatible types matrix argument. valgrind gives program clean bill of health.

output:

f (3x3):   1  2  3   1  4  7   1  5  9 s (3x3):   9  8  7   4  5  6   0  9  6 r (3x3):   9 16 21   4 20 42   0 45 54 

Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -