C programming calling a function...passing (float*)X to a function - c

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.

Related

Trying to pass 2d array to function in C [duplicate]

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]);

Cast contiguous block of memory into higher-dimensional array for ease of indexing

I have a function that gets passed a linear block of memory that encodes a row-major stored higher-dimensional matrix (3d, 4d, ...).
Is there a way to cast the memory such that efficient multidimensional indexing is possible?
void do_something_in_4d(float* input, int dim1, int dim2, int dim3, int dim4) {
// input_4d = (some casting magic) input
int i = 1;
int j = 2;
int m = 3;
int n = 4;
// input_4d[i][j][m][n] == input[i*dim2*dim3*dim4 + j*dim3*dim4 + m*dim4 + n]
}
You could use C99 variable length arrays for this. Note that in case you ever need compatibility, these are not supported by any C++ version so far, and compilers like MSVC (as of 2019) don't implement them.
Now while the commonly seen form is the ability to do something like int arr[n] or int arr[w][h] as a stack variable, it does in fact work for pointers as well.
#include <stdlib.h>
#include <stdio.h>
void matrix_print(int x, int y, int z, int w, float (*matrix_4d)[y][z][w]);
void matrix_set(int x, int y, int z, int w, float (*matrix_4d)[y][z][w]);
int main()
{
int width = 3;
float matrix2[] = {0, 1, 2, 3, 4, 5};
float (*matrix_2d)[width] = (float(*)[width])matrix2;
printf("%f\n", matrix_2d[0][0]); // 0
printf("%f\n", matrix_2d[0][1]); // 1
printf("%f\n", matrix_2d[0][2]); // 2
printf("%f\n", matrix_2d[1][0]); // 3
printf("%f\n", matrix_2d[1][1]); // 4
printf("%f\n", matrix_2d[1][2]); // 5
int x=2,y=3,z=4,w=5;
float *matrix4 = malloc(sizeof(float)*x*y*z*w);
float (*matrix_4d)[y][z][w] = (float (*)[y][z][w]) matrix4;
matrix_set(x, y, z, w, matrix_4d);
printf("1D matrix\n");
for (int i = 0; i < x*y*z*w; ++i)
printf("%f\n", matrix4[i]); // 0 to 119
matrix_print(x, y, z, w, matrix_4d);
}
void matrix_set(int x, int y, int z, int w, float (*matrix_4d)[y][z][w])
{
int i = 0;
for (int xi = 0; xi < x; ++xi)
for (int yi = 0; yi < y; ++yi)
for (int zi = 0; zi < z; ++zi)
for (int wi = 0; wi < w; ++wi, ++i)
matrix_4d[xi][yi][zi][wi] = i;
}
void matrix_print(int x, int y, int z, int w, float (*matrix_4d)[y][z][w])
{
printf("4D\n");
printf("%f\n", matrix_4d[0][0][0][0]); // 0
printf("%f\n", matrix_4d[0][0][0][1]); // 1
printf("%f\n", matrix_4d[0][0][1][0]); // 5
printf("%f\n", matrix_4d[0][1][0][0]); // 20
printf("%f\n", matrix_4d[1][0][0][0]); // 24
printf("%f\n", matrix_4d[1][2][3][4]); // 119
}
You can cast the input pointer to a 3-D variable-length array pointer type and access it like a 4-D array:
float (*input_4d)[dim2][dim3][dim4] = (float (*)[dim2][dim3][dim4])input;
For readability, I'd introduce a typedef for the 3-D array:
typedef float f3d[dim2][dim3][dim4];
f3d *input_4d = (f3d *)input;
Assuming C99 compatibility, then yes, you can cast the array as a multi dimensional VLA.
float (*input_4d)[dim2][dim3][dim4] = (float(*)[dim2][dim3][dim4])input;

How to pass a 2D array to a function in C when the array is formatted like this?

I'd like to make an array (called Csend) and then create a function which modifies it slightly, such as by adding 0.05 to every element. The problem I'm having is with the formatting of the array, I'm not sure how to pass it into a function properly. I've allocated the memory in this way following this guide so that I can later put it in MPI_Send and MPI_Recv.
Here is my attempt:
#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"
int main(int argc, char **argv) {
int N = 32;
int dim = 3;
float a = 10.0; // size of 3D box
int size, rank, i, j, k, q;
float **C, **Csend, **Crecv;
float stepsize = 0.05;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
float **alloc_2d_float(int rows, int cols) {
float *data = (float *)malloc(N*dim*sizeof(float));
float **array= (float **)malloc(N*sizeof(float*));
for(i=0; i<N; i++) {
array[i] = &(data[dim*i]);
}
return array;
}
C = alloc_2d_float(N,dim);
Csend = alloc_2d_float(N,dim);
Crecv = alloc_2d_float(N,dim);
if(rank == 0) {
for (i = 0; i < N; i++) {
for (j = 0; j < dim; j++) {
Csend[i][j] = (float)rand()/(float)(RAND_MAX/a);
}}
}
// FUNCTION TO MODIFY MATRIX //
float randomsteps(float *matrix, int N, int dim) {
int i, j;
for(i = 0; i < N; i = i+2) {
for (j = 0; j < dim; j++) {
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize;
}
}
return matrix;
}
C = randomsteps(Csend, 32, 3);
for (i=0; i<N; i++){
for (j=0; j<dim; j++){
printf("%f, %f\n", Csend[i][j], C[i][j]);
}
}
MPI_Finalize();
return 0;
}
The problem I'm having is that formatted like it is here, I get error messages, and formatted in ways that didn't give error messages, C was just empty.
Here is the error message:
test.c: In function ‘randomsteps’:
test.c:46: error: incompatible types when returning type ‘float *’ but ‘float’ was expected
test.c: In function ‘main’:
test.c:49: warning: passing argument 1 of ‘randomsteps’ from incompatible pointer type
test.c:39: note: expected ‘float *’ but argument is of type ‘float **’
test.c:49: error: incompatible types when assigning to type ‘float **’ from type ‘float’
Thanks for the help!
You are confusing between 1 dimensional representation of a matrix and a two dimensional pointer to pointer approach of it.
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize; -> This line implies that matrix is just linear collection and it is accessed like a matrix using index manipulation.
float **C; -> This implies you want a matrix which can be accessed as C[i][j].
Stick to any one of the representations. Also, since your function returns a matrix, the return type should be either float* (if the 2d matrix is considered linear with array manipulation) of float** if you want a 2d matrix without index manipulation access.
float* matrix = malloc(row * cols * sizeof(float)); // This is a linear version.
// matrix[i*cols + j] gives you the (i, j)th element.
float** matrix = malloc(rows * sizeof(float*));
for(int i = 0; i < rows; ++i)
matrix[i] = malloc(cols * sizeof(float));
// Now you can access matrix[i][j] as the (i, j)th element.
Here is a way to interconvert between the two formats.
float* linearize(float** matrix, unsigned int rows, unsigned int cols)
{
float* linear = malloc(rows * cols * sizeof(float));
if(linear)
{
for(unsigned int i = 0; i < rows; ++i)
for(unsigned int j = 0; j < cols; ++j)
linear[i*cols + j] = matrix[i][j] ;
}
return linear ;
}
float** unlinearize(float* linear, unsigned int rows, unsigned int cols)
{
float** matrix = malloc(rows * sizeof(float*));
if(matrix)
{
for(unsigned int i = 0; i < rows; ++i)
{
matrix[i] = malloc(cols * sizeof(float));
if(matrix[i])
{
for(unsigned int j = 0; j < cols; ++j)
matrix[i][j] = linear[i*cols + j] ;
}
}
}
return matrix ;
}

pointer to function in c code

i am very new in c programming. i am using a c code from the book 'numerical recipes in C' for polynomial regression. in this program i need to replace (*funcs) function with fpoly function.but i dont know how to do that and how to make changes in fpoly function to become like (*fpoly).could you please help me with that?
I really appreciate any help.
void fpoly(float x, float p[], int np)
//Fitting routine for a polynomial of degree np-1, with coefficients in the array p[1..np].
{
int j;
p[1]=1.0;
for (j=2;j<=np;j++) p[j]=p[j-1]*x;
}
void lfit( float x[], float y[], float sig[], int ndat, float a[], int ia[], int ma, float **covar, float *chisq, void (*funcs)(float, float [], int))
and here is the complete program:
void lfit(float x[], float y[], float sig[], int ndat, float a[], int ia[],
int ma, float **covar, float *chisq, void (*funcs) (float,float[], int))
/*Given a set of data points x[1..ndat], y[1..ndat] with individual standard deviations
sig[1..ndat], use χ2 minimization to fit for some or all of the coefficients a[1..ma] of
a function that depends linearly on a, y =sum(i)( ai × afunci(x)). The input array ia[1..ma]
indicates by nonzero entries those components of a that should be fitted for, and by zero entries
those components that should be held fixed at their input values. The program returns values
for a[1..ma], χ2 = chisq, and the covariance matrix covar[1..ma][1..ma]. (Parameters
held fixed will return zero covariances.)Th e user supplies a routine funcs(x,afunc,ma) that
returns the ma basis functions evaluated at x = x in the array afunc[1..ma].*/
{
void covsrt(float **covar, int ma, int ia[], int mfit);
void gaussj(float **a, int n, float **b, int m);
int i, j, k, l, m, mfit = 0;
float ym, wt, sum, sig2i, **beta, *afunc;
beta = matrix(1, ma, 1, 1);
afunc = vector(1, ma);
for (j = 1; j <= ma; j++)
if (ia[j])
mfit++;
if (mfit == 0)
nrerror("lfit: no parameters to be fitted");
for (j = 1; j <= mfit; j++) { //Initialize the (symmetric)mat rix.
for (k = 1; k <= mfit; k++)
covar[j][k] = 0.0;
beta[j][1] = 0.0;
}
for (i = 1; i <= ndat; i++) {
(*funcs) (x[i], afunc, ma);
ym = y[i];
if (mfit < ma) { //Subtract off dependences on known pieces
for (j = 1; j <= ma; j++) //of the fitting function.
if (!ia[j])
ym -= a[j] * afunc[j];
}
sig2i = 1.0 / SQR(sig[i]);
for (j = 0, l = 1; l <= ma; l++) {
if (ia[l]) {
wt = afunc[l] * sig2i;
for (j++, k = 0, m = 1; m <= l; m++)
if (ia[m])
covar[j][++k] += wt * afunc[m];
beta[j][1] += ym * wt;
}
}
}
for (j = 2; j <= mfit; j++) //Fill in above the diagonal from symmetry.
for (k = 1; k < j; k++)
covar[k][j] = covar[j][k];
gaussj(covar, mfit, beta, 1); //Matrix solution.
for (j = 0, l = 1; l <= ma; l++)
if (ia[l])
a[l] = beta[++j][1]; //Partition solution to appropriate coefficients
*chisq = 0.0;
for (i = 1; i <= ndat; i++) { //Evaluate χ2 of the fit.
(*funcs) (x[i], afunc, ma);
for (sum = 0.0, j = 1; j <= ma; j++)
sum += a[j] * afunc[j];
*chisq += SQR((y[i] - sum) / sig[i]);
}
covsrt(covar, ma, ia, mfit); //Sort covariance matrix to true order of fittin
free_vector(afunc, 1, ma); //coefficients.
free_matrix(beta, 1, ma, 1, 1);
}
In
void lfit( float [], float [], float [], int, float [], int [], int, float**, float*, void (*funcs)(float, float [], int))
"void (*funcs)(float, float [], int)" is the type signature of the function pointer.
If it is in-scope, you can just pass the name of your function (fpoly) in place of "void (*funcs)(float, float [], int)", without parentheses or anything. You can also take its address with the & operator but I believe it's equivalent:
lfit( all_the_other_args, ..., fpoly);
You could also have a local function pointer which holds fpoly:
void (*local_function_pointer_variable)(float, float [], int) = fpoly;
lfit( all_the_other_args, ..., local_function_pointer_variable);
In C the syntax of function pointer types is somehow inconvenient but hopefully you can define a type to hide this to some extent
typedef void (*poly_fitter)(float, float [], int);
poly_fitter function_pointer_var_of_type_poly_fitter = fpoly;
lfit( all_the_other_args, ..., function_pointer_var_of_type_poly_fitter)
If I understand correctly, you want to pass the function poly if so, then just pass the name of the function:
lfit(x, y,...., poly);
the lfit function has many input parameter.
1 of the parameter is address to a function. and that's why we have added * in the definition of that input parameter.
void (*funcs) (float, float[], int))
so when you calling lfit() function you can mention the address the address of your fpoly() function as the input of your lfit() function
the address of void fpoly(float x, float p[], int np) is fpoly or &fpoly
so when you call your function lfit() you can do it in this way:
lfit(x,y,...,fpoly)
or in this way:
lfit(x,y,...,&fpoly)

Dealing with warnings in c compilations

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.

Resources