views:

174

answers:

2

Hi, 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
+2  A: 

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).

John Bode
A: 

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.

Ben