I am trying to calculate the Jacobian matrix (numerical, at a given point) of a given equation. Now, I don't know the dimension of the equation beforehand, so I can't just do something like
static double f(double x1, x2)
{
return x1 * x1 - 2 * x1 * x2;
}
so instead, I am getting the input values as an array like so
static double f(double xArray[])
{
return xArray[0] * xArray[0] - 2 * xArray[1] * xArray[0];
}
void jacobian(double xArray[], double jacob_matrix, size_t size,
double f(double xArray[], size_t))
{
// calculations
}
However, when I try to call the function from main like
int main(void)
{
double x_input[4] = {1., 1., 3., 4.};
double jacob_matrix[4];
jacobian(x_input, jacob_matrix, 4, f(x_input, 4));
return 0;
}
I get incompatible type for argument 4 of 'jacobian' I imagine this has to do with my array being casted into a pointer, but I can't figure out how to fix this.
2 Answers 2
You need to pass the function pointer to f, not the result of calling f.
Try:
jacobian(x_input, jacob_matrix, 4, f);
3 Comments
jacobian, not its arguments I suppose? Does f choose its input array to be xArray because of ` void jacobian(double xArray[], double jacob_matrix, size_t size, double f(double xArray[], size_t)) ` ?jacob_matrix is a scalar of type double. Probably you would like to change it to double jacob_matrix[].jacob_matrix is as you've suggested.For the function signature:
void jacobian(double xArray[], double jacob_matrix, size_t size,
double f(double xArray[], size_t))
For the second argument, if you're going to pass an array you need the argument to be a pointer, double* jacob_matrix or double jacob_matrix[].
For the 4th argument, the passed function arguments should match the caller signature, so in your case you are passing a function which is of type double (*)(double *), but the caller expects a function of type double (*)(double *, size_t), so one of them should be changed to match, either add a second argument to the called function, or remove the second argument of the caller function signature.
#include <stdio.h>
static double f(double xArray[])
{
return xArray[0] * xArray[0] - 2 * xArray[1] * xArray[0];
}
void jacobian(double xArray[], double* jacob_matrix, size_t size,
double f(double xArray[]))
{
printf("%f", f(xArray)); // for example
}
int main(void)
{
double x_input[4] = {1., 1., 3., 4.};
double jacob_matrix[4];
jacobian(x_input, jacob_matrix, 4, f);
return 0;
}
Note that my approach only addresses the code correctness and not the mathematical part, i.e. the jacobian calculation.
8 Comments
void jacob(double f(double x)) when x is of type double. In the case of pointer, can we just use the function signature as void jacobian(double xArray[], double* jacob_matrix, size_t size, double f(double* )) But I guess in this case, then f cannot match its input argument with x_input.typedef for the function type would increase readability.x_input is passed correctly, an array passed as argument of a function will decay to a pointer to its first element, so it is correct.double (*)(double *), but the caller expects a function of type double (*)(double *, size_t), so one of them should be changed to match, either add a second argument to the called function, or remove the second argument of the caller function signature.void jacobian(double xArray[], double* jacob_matrix, size_t size, double f(double xArray[])) { double a[] = {5}; printf("%f", f(a)); }
ffunctionstatic double f...