I'm trying to change a value of an element of a complex matrix in c.
After trying to do, the printed result of the element is 0, any idea on how to fix this?
Here is my code, thanks in advance.
int main()
{
int size = 2;
double _Complex **x;
double _Complex v;
//Creating complex matrix
x = (double _Complex **)malloc( size* sizeof(double _Complex *) );
x[0] = (double _Complex *)malloc( (int)(size*size)* sizeof(double _Complex ));
for(int i = 1; i < size; i++ )
x[i] = x[0] + (unsigned long)size * i;
//Printing the matrix
printf("Before \n");
for (int h = 0; h < size; h++)
{
for (int w = 0; w < size; w++)
{
v = x[h][w];
printf( "%d + i* %d ,", creal(v), cimag(v));
}
printf("\n");
}
//Changing the value
int _Complex t = 1 + 5*_Complex_I;
x[0][0] = t;
//Print the matrix after the change
return 0;
}
After trying to do, the printed result of the element is 0, any idea on how to fix this?
Wrong format specifier
double _Complex v;
...
// printf("%d + i* %d ,", creal(v), cimag(v));
printf("%g + i* %g ,", creal(v), cimag(v));
Save time, enable all compiler warnings.
warning: format '%d' expects argument of type 'int', but argument 3 has type 'double' [-Wformat=]
Complex int types
Such types int _Complex may cause warning: ISO C does not support complex integer types [-Wpedantic]. Recommend double _Complex.
// int _Complex t = 1 + 5*_Complex_I;
double _Complex t = 1 + 5*_Complex_I;
Uninitialized data
When printing, the complex values have not been assigned. Perhaps zero them with calloc(). Cast not needed in C. Perform multiplication using size_t math. Better to take the size of the de-reference pointer, than the type - easier to code right, review and maintain.
// x[0] = (double _Complex *)malloc( (int)(size*size)* sizeof(double _Complex ));
x[0] = calloc( (size_t) size * size, sizeof x[0][0]);
Related
This question already has answers here:
How to pass a 2D array by pointer in C?
(5 answers)
Closed 4 months ago.
#include <stdio.h>
void triU(double **U, double *b, int n)
{
n--;
b[n] /= U[n][n];
for(int i = n - 1; i >= 0; i--)
{
double aux_sum = 0;
for(int j = i + 1; j <= n; j++)
aux_sum += (U[i][j] * b[j]);
b[i] = (b[i] - aux_sum) / U[i][i];
}
}
int main()
{
int n = 3;
double U[][n] = {{5, -5, 10}, {0, 2, 4}, {0, 0, -1}};
double b[] = {25, 16, -2};
triU(U, b, n);
for(int i = 0; i < n; i++)
printf("%le \n", b[i]);
return 0;
}
This is the code for what I am trying to do. I am supposed to make a method with the parameters written in that way to pass the two matrices.
However I keep getting the following error.
triU.c: In function ‘int main()’:
triU.c:21:10: error: cannot convert ‘double (*)[n]’ to ‘double**’
21 | triU(U, b, n);
| ^
| |
| double (*)[n]
triU.c:3:20: note: initializing argument 1 of ‘void triU(double**, double*, int)’
3 | void triU(double **U, double *b, int n)
| ~~~~~~~~~^
I would appreciate any help on how I am supposed to pass arrays by pointers in C.
Thank you very much.
In this call of the function triU:
triU(U, b, n);
the two-dimensional array U is implicitly converted to pointer to its first element of the type double ( * )[3]. But the corresponding function parameter has the type double ** and there is no implicit conversion between the pointer types. So the compiler issues a message.
If your compiler supports variable length arrays (and your compiler support VLAs) then declare the function like:
void triU( size_t n, double ( *U )[n], double *b );
or:
void triU( size_t n, double U[][n], double *b );
and call it like:
triU( n, U, b );
Otherwise declare the function like:
void triU( double ( *U )[3], double *b, size_t n );
or:
void triU( double U[][3], double *b, size_t n );
and call it like:
triU( U, b, n );
Pay attention to that this for loop:
for(int j = i + 1; j <= n; j++)
aux_sum += (U[i][j] * b[j]);
can invoke undefined behavior when j is equal to n because the valid range of indices is [0, n).
Also bear in mind that the length modifier in the format string in this call:
printf("%le \n", b[i]);
is redundant and has no effect. You may write:
printf("%e \n", b[i]);
I'm trying to multiply a large and random matrix (NxN) and a random vector (N), using pointers.
Why am i getting an error type "invalid operands to binary * (have 'double *' and 'double *')" ?
The error seems to be in ptr3[i][j] = ptr3[i] + ptr1[i] * ptr2[k];
but I can't figure out why this doesn't work.
I'm new to C, so I still don't get pointers very well.
int main ()
{
time_t t;
double **ptr1, **ptr2, **ptr3;
int i, j, k;
int N = 500;
ptr1 = (double **) malloc (sizeof (double *) * N);
ptr2 = (double **) malloc (sizeof (double *) * N);
ptr3 = (double **) malloc (sizeof (double *) * N);
for (i = 0; i < N; i++)
ptr1[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i++)
ptr2[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i++)
ptr3[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
ptr1[i][j] = rand ();
}
}
for (i = 0; i < N; i++) {
*ptr2[i] = rand ();
}
t = clock();
for (i = 0; i < N; i++) {
ptr3[i] = 0;
for (k = 0; k < N; k++)
ptr3[i] = ptr3[i] + ptr1[i][k] * ptr2[k];
}
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
printf("Tempo: %f segundos \n", time_taken);
printf ("\n");
return (0);
} ```
What the compiler is saying is that in the statement ptr3[i] = ptr3[i] + ptr1[i] * ptr2[k];, the bit which says ptr1[i] * ptr2[k] is attempting to * between two expressions which have the type double*. In other words, you are not allowed to multiply two pointers together. To do this properly, you need to dereference again (the [i] and [k] are dereferencing the double** to a double* already). To get this to compile, that statement should be (I added parenthesis for clarity -- they aren't actually needed):
*ptr3[i] = (*ptr3[i]) + (*ptr1[i]) * (*ptr2[k]);
That should get you to compiling, but the next problem you'll run into is a segmentation fault. Two lines above the place where you do the multiplication, you have this:
ptr3[i] = 0;
This is assigning ptr3[i] to be the null pointer, which is the same as 0 in C (other languages have a different name of this value: null, None, etc). What I think you meant to do here is:
*ptr3[i] = 0;
As an aside, since N is a known, fixed value, you can choose to not deal with all the malloc stuff by simply saying:
const int N = 500;
double ptr1[N][N];
double ptr2[N][N];
// ... and so on ...
This is declaring ptr1 as an array instead of a pointer, which is identical to a pointer in terms of memory access patterns, but different in a number of ways. Depending on what you are trying to learn, not dealing with dynamic memory (using malloc and free) might save you a little bit of headache for now.
I am fairly new to the C language. I have written a piece of code which creates two thread to calculate two different results. the code actually works but the compiling is showing errors and I want to know what is actually the error. can anyone help me? I am new to C, so I guess it might be a very silly mistake...
Errors:
q3.c: In function ‘main’:
q3.c:63:2: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
In file included from q3.c:5:0:
/usr/include/pthread.h:225:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘double * (*)(void *)’
q3.c:64:9: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
In file included from q3.c:5:0:
/usr/include/pthread.h:225:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘double * (*)(void *)’
The code:
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include<stdio.h>
#include<math.h>
#define PI 3.1415
int i, x, n;
double *sin_x(void* dimension);
double *cos_x(void* dimension);
int fact(int);
struct data
{
int ang_deg;
int no_of_terms;
};
int fact(int num)
{
int f = 0;
if (num == 1)
return 1;
else
f = num * fact(num - 1);
return f;
}
int main(int argc, char argv[])
{
printf("\nEnter x and n:\t");
scanf("%d %d", &x, &n);
struct data
{
int ang_rad;
int no_of_terms;
};
struct data dimension; // automatic allocation, all fields placed on stack
dimension.ang_rad = x;
dimension.no_of_terms = n;
pthread_t thrd1, thrd2;
int thret1, thret2;
thret1 = pthread_create(&thrd1, NULL, sin_x, (void *) &dimension);
thret2 = pthread_create(&thrd2, NULL, cos_x, (void *) &dimension);
pthread_join(thrd1, NULL );
pthread_join(thrd2, NULL );
//printf("\nthret1 = %d\n", thret1);
//printf("thret2 = %d\n", thret2);
sleep(5);
printf("Parent Thread exiting...\n");
exit(1);
return 0;
}
double *sin_x(void* dimension)
{
struct data* dim = (struct data*) dimension;
int ang_deg = dim->ang_deg;
int no_of_terms = dim->no_of_terms;
//int ang_deg, int no_of_terms
int term, j;
double value = 0.0, ang_rad = 0.0;
ang_rad = (double) ang_deg * PI / 180;
for (term = 1, j = 2; term < no_of_terms * 2; term += 2, j++)
{
value += (double) pow(-1.0, j) * pow(ang_rad, term) / fact(term);
}
printf("\nSin(%d) = %f", ang_deg, value);
double *a = &value;
return a;
}
double *cos_x(void* dimension)
{
struct data* dim = (struct data*) dimension;
int ang_deg = dim->ang_deg;
int no_of_terms = dim->no_of_terms;
int term, j;
double value = 1.0, ang_rad = 0.0;
ang_rad = (double) ang_deg * PI / 180;
for (term = 2, j = 1; term <= no_of_terms; term += 2, j++)
{
value += (double) pow(-1.0, j) * pow(ang_rad, term) / fact(term);
}
printf("\nCos(%d) = %f", ang_deg, value);
double *a = &value;
return a;
}
It's not errors, but warnings.
Your functions are :
double *sin_x (void *dimension);
double *cos_x (void *dimension);
Since a function's name is a pointer to the function, the type of sin_x is : double * (*) (void *) (literally : a pointer to a function taking a void* as argument and returning a double *), same for cos_x.
But pthread_create is waiting for the type void * (*) (void *) (a pointer to a function taking void* as argument and returning void*).
Since double* and void* are both pointers, they have the same size (8 bytes on a 64b for example), so the compiler just warn you.
Changes:
Replaced sleep() with pthread_exit(). Sleep is a poor idea for synchronization.
Corrected main()'s parameters. It should be int main(void) or int main(int argc, char**argv) or equivalent.
Removed unnecessary struct inside main().
Changed the return type of fact() to size_t, which would allow you to calculate more factorials than possible with int type.
Rewrote the factorial function to use memoization. This is more efficient way of calculating factorial since you don't need to recalculate the previous factorials that have been computed already. The array size is 64K which you can change. As it currently stands, it can calculate
first 64K factorials.
You should add eror checking for pthread_ functions.
Removed pthread_join() calls since main() thread exits. The process will exit naturally once the last thread exits.
Removed the thread values since you are not using them. If you do want to know computed values, you can add another member to struct dimension and store the result in that. This method would allow to return complex value from thread functions.
--
Here's a fully functional code with all the above changes done. For more info, read pthread_create() and manuals of other functions.
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include<stdio.h>
#include<math.h>
#define PI 3.1415
int i, x, n;
void *sin_x( void* dimension );
void *cos_x( void* dimension );
size_t fact( int );
size_t tab[64*1024] = {1};
struct data
{
int ang_deg;
int no_of_terms;
};
size_t fact( int num )
{
size_t f = 0;
if ( tab[num]) return tab[num];
f = num * fact( num - 1 );
tab[num] = f;
return f;
}
int main (int argc, char **argv)
{
printf( "\nEnter x and n:\t" );
scanf( "%d %d", &x, &n );
struct data dimension; // automatic allocation, all fields placed on stack
dimension.ang_deg = x;
dimension.no_of_terms= n;
pthread_t thrd1, thrd2;
int thret1, thret2;
thret1 = pthread_create(&thrd1, NULL, sin_x, &dimension);
thret2 = pthread_create(&thrd2, NULL, cos_x, &dimension);
printf("Parent Thread exiting...\n");
pthread_exit(0);
}
void *sin_x( void* dimension )
{
struct data* dim = dimension;
int ang_deg = dim->ang_deg;
int no_of_terms = dim->no_of_terms;
int term, j;
double value = 0.0, ang_rad = 0.0;
ang_rad = ( double ) ang_deg * PI / 180;
for ( term = 1, j = 2;term < no_of_terms*2;term += 2, j++ )
{
value += ( double ) pow( -1.0, j ) * pow( ang_rad, term ) / fact( term );
}
printf("\nSin(%d) = %f", ang_deg, value);
return 0;
}
void *cos_x( void* dimension )
{
struct data* dim = dimension;
int ang_deg = dim->ang_deg;
int no_of_terms = dim->no_of_terms;
int term, j;
double value = 1.0, ang_rad = 0.0;
ang_rad = ( double ) ang_deg * PI / 180;
for ( term = 2, j = 1;term <= no_of_terms;term += 2, j++ )
{
value += ( double ) pow( -1.0, j ) * pow( ang_rad, term ) / fact( term );
}
printf("\nCos(%d) = %f", ang_deg, value);
double *a = &value;
return 0;
}
I have the following code shown below
To call the function the code looks similar to the following:
#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[N][1];
int main(void)
{
matrix_multiply((float*) m1, (float*) m2, N, N, 1, (float*) result);
}
void matrix_multiply(float* input_matrix1, float* input_matrix2, int m, int p, int n, float* output_matrix)
{
// Matrix Multiplication Routine
// input_matrix1= input matrix (m x p)
// input_matrix2 = input matrix (p x n)
// m = number of rows in input_matrix1
// p = number of columns in input_matrix1 which should equal the number of rows in input_matrix2
// n = number of columns in input_matrix2
// output_matrix = output matrix = input_matrix1*input_matrix2 (m x n)
//.....Code that does matrix multiplication
}
I haven't come across the (float*) being used when calling a function. Can someone describe it in detail.
The notation (float *)X is a cast. The cast is necessary if the matrix multiply function is declared (or defined) before it is used, as it should be, because the types being passed to the function are not float * as the function expects but float (*)[2] (which is a pointer to an array). The casts tell the compiler 'we know more about this C than you do', even though that is a very debatable proposition.
Here is a mildly modified version of the code in the question:
#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];
void matrix_multiply(float *input_matrix1, float *input_matrix2, int m, int p, int n, float *output_matrix);
int main(void)
{
matrix_multiply( m1, m2, N, N, 1, result);
matrix_multiply(&m1[0][0], &m2[0][0], N, N, 1, &result[0][0]);
matrix_multiply((float*) m1, (float*) m2, N, N, 1, (float*) result);
}
void matrix_multiply(float *input_matrix1, float *input_matrix2, int m, int p, int n, float *output_matrix)
{
// Matrix Multiplication Routine
// input_matrix1 = input matrix (m x p)
// input_matrix2 = input matrix (p x n)
// m = number of rows in input_matrix1
// p = number of columns in input_matrix1 and the number of rows in input_matrix2
// n = number of columns in input_matrix2
// output_matrix = output matrix = input_matrix1*input_matrix2 (m x n)
//.....Code that does matrix multiplication
}
When compiled with GCC 4.7.1 on Mac OS X 10.8.4, the output is:
$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c matmul89.c
matmul89.c: In function ‘main’:
matmul89.c:10:5: warning: passing argument 1 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[2]’
matmul89.c:10:5: warning: passing argument 2 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[1]’
matmul89.c:10:5: warning: passing argument 6 of ‘matrix_multiply’ from incompatible pointer type [enabled by default]
matmul89.c:6:6: note: expected ‘float *’ but argument is of type ‘float (*)[2]’
matmul89.c: In function ‘matrix_multiply’:
matmul89.c:17:29: warning: unused parameter ‘input_matrix1’ [-Wunused-parameter]
matmul89.c:17:51: warning: unused parameter ‘input_matrix2’ [-Wunused-parameter]
matmul89.c:17:70: warning: unused parameter ‘m’ [-Wunused-parameter]
matmul89.c:17:77: warning: unused parameter ‘p’ [-Wunused-parameter]
matmul89.c:17:84: warning: unused parameter ‘n’ [-Wunused-parameter]
matmul89.c:17:94: warning: unused parameter ‘output_matrix’ [-Wunused-parameter]
$
The unused parameter warnings are reasonable; the function is still a dummy with no code. Line 10 is the call to matrix_multiply() without the casts. As you can see, GCC diagnoses that the types of the matrix arguments are not float * but are pointers arrays. The second call is the way I'd write it, avoiding any need for casts. The third call bludgeons the compiler into accepting the code with the casts, and it will in fact work correctly, but there is really no need to do the bludgeoning.
Working C99 code
If you've got C99 available, you can make use of VLAs — variable length arrays — to write the code neatly:
#include <stdio.h>
#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];
void matrix_multiply(int m, int p, int n, float matrix1[m][p], float matrix2[p][n], float output[m][n]);
void matrix_print(const char *tag, int m, int n, float matrix[m][n]);
int main(void)
{
matrix_multiply(N, N, 1, m1, m2, result);
matrix_print("m1", N, N, m1);
matrix_print("m2", N, 1, m2);
matrix_print("m3", 1, N, result);
}
void matrix_multiply(int m, int p, int n, float matrix1[m][p], float matrix2[p][n], float output[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
output[i][j] = 0.0;
for (int i = 0; i < m; i++)
for (int j = 0; j < p; j++)
for (int k = 0; k < n; k++)
output[i][k] += matrix1[i][j] * matrix2[j][k];
}
void matrix_print(const char *tag, int m, int n, float matrix[m][n])
{
printf("%s (%d x %d):\n", tag, m, n);
for (int i = 0; i < m; i++)
{
char *pad = "[";
for (int j = 0; j < n; j++)
{
printf("%s%6.3f", pad, matrix[i][j]);
pad = ", ";
}
printf("%s", " ]\n");
}
}
This compiles without warnings and produces the plausible-looking output:
m1 (2 x 2):
[ 1.000, -0.020 ]
[ 0.000, 1.000 ]
m2 (2 x 1):
[ 1.500 ]
[ 1.500 ]
m3 (1 x 2):
[ 1.470, 1.500 ]
Writing the code to simulate the address arithmetic using C89 is fiddly — far from impossible, but fiddly.
Working C89 code
#include <stdio.h>
#define N 2
static float m1[N][N] = {{1.0, -0.02}, {0.0, 1.0}};
static float m2[N][1] = {{1.5f}, {1.5f}};
static float result[1][N];
void matrix_multiply(float *matrix1, float *matrix2, int m, int p, int n, float *output);
void matrix_print(const char *tag, int m, int n, float *matrix);
int main(void)
{
matrix_multiply(&m1[0][0], &m2[0][0], N, N, 1, &result[0][0]);
matrix_print("m1", N, N, &m1[0][0]);
matrix_print("m2", N, 1, &m2[0][0]);
matrix_print("m3", 1, N, &result[0][0]);
return 0;
}
/*
** Matrix Multiplication Routine
** matrix1 = input matrix (m x p)
** matrix2 = input matrix (p x n)
** m = number of rows in matrix1
** p = number of columns in matrix1 and number of rows in matrix2
** n = number of columns in matrix2
** output = output matrix = matrix1 * matrix2 (m x n)
*/
void matrix_multiply(float *matrix1, float *matrix2, int m, int p, int n, float *output)
{
int i, j, k;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
output[i*n+j] = 0.0;
for (i = 0; i < m; i++)
for (j = 0; j < p; j++)
for (k = 0; k < n; k++)
output[i*n+k] += matrix1[i*p+j] * matrix2[j*n+k];
}
void matrix_print(const char *tag, int m, int n, float *matrix)
{
int i, j;
printf("%s (%d x %d):\n", tag, m, n);
for (i = 0; i < m; i++)
{
char *pad = "[";
for (j = 0; j < n; j++)
{
printf("%s%6.3f", pad, matrix[i*n+j]);
pad = ", ";
}
printf("%s", " ]\n");
}
}
The output for the C89 and C99 code is the same.
I have the following warnings during the compilation:
solver.c:24: warning: passing argument 2 of ‘mtrx_multiple’ from incompatible pointer type
mat.h:5: note: expected ‘double *’ but argument is of type ‘double **’
solver.c:30: warning: assignment makes pointer from integer without a cast
solver.c:39: warning: assignment makes pointer from integer without a cast
/tmp/ccmU9zRf.o: In function `vec_norm':
math.c:(.text+0x331): undefined reference to `sqrt'
collect2: ld returned 1 exit status
the lines are:
solver.c
double *cg_solve( sparse_mat_t A, double *b, double *x ) {
double *a;
double **r;
double *be;
double **p;
double **x0;
x0[0] = vec_copy(x, size);
...
line 24: r[0] = vec_subtraction( b, mtrx_multiple(A, x0), size );
line 30: x0[k+1] = vec_addition( x0[k], vec_numb_multiple(a[k], p[k], size), size );
line 39: p[k+1] = vec_addition( r[k+1], vec_numb_multiple(be[k], p[k], size), size );
}
math.h
line 5: double *mtrx_multiple (sparse_mat_t A, double *c);
The function that are used there: (math.c)
double *vec_subtraction (double *a, double *b, int n) {
double *result = malloc(sizeof(double)*n);
int i;
for(i=0; i<n; i++)
result[i] = a[i]-b[i];
return result;
}
double *vec_addition (double *a, double *b, int n) {
double *result = malloc(sizeof(double)*n);
int i;
for(i=0; i<n; i++)
result[i] = a[i]+b[i];
return result;
}
double *vec_numb_multiple (double a, double *b, int n) {
double *result = malloc(sizeof(double)*n);
int i;
for(i=0; i<n; i++)
result[i] = a*b[i];
return result;
}
double *mtrx_multiple (sparse_mat_t A, double *c) {
double *result;
int i, j;
result = malloc((A.size) * sizeof *result);
printf("c.n: %d \n", A.size);
for (i = 0; i < A.size; i++) {
int v = 0;
for (j = A.ia[i]; j < A.ia[i + 1]; j++) {
v += A.a[j] * c[A.ja[j]];
}
result[i] = v;
}
return result;
}
double vec_norm (double *a, int n){
double result;
int i;
for(i=0; i<n; i++)
result = result + ( a[i] * a[i] );
result = sqrt(result);
return result;
}
double *vec_copy (double *a, int n) {
double *result;
int i;
for(i=0; i<n; i++)
result[i] = a[i];
return result;
}
I will be grateful for any help.
EDIT
I found the solution to the x0 problem, thanks Ben. Now what left is:
solver.c:30: warning: assignment makes pointer from integer without a cast
solver.c:39: warning: assignment makes pointer from integer without a cast
/tmp/ccL4uSoH.o: In function 'vec_norm':
math.c:(.text+0x331): undefined reference to 'sqrt'
collect2: ld returned 1 exit status
Based on what you've posted, I'm going to guess that you don't have a declaration for vec_numb_multiple in scope before you call it, and the compiler is implicitly typing it to return int; that would lead to the warnings on lines 30 and 39.
The undefined reference to sqrt() means you aren't linking in the standard math library; I'm assuming you're using gcc, so you would need to add -lm to the command line.
It's a really bad idea to use a standard library file name for your own code (math.h, math.c).
replace (line 24)
r[0] = vec_subtraction( b, mtrx_multiple(A, x0), size );
with
r[0] = vec_subtraction( b, mtrx_multiple(A, x0[0]), size );
You said you whant to multiply a matrix (A I guess) with a vector, so the second argument must be a vector. x0 is a pointer to pointers which can be see as a 2D array of doubles, it means a single cell of x0 is an array of doubles (ie. what you could call a vector). This is why you want to pass x0[0], not just x0 which is : many arrays.
see John's aswer for the rest.