I am trying to find the right parameters to input to my code to produced the desired results. Instead of guessing and checking I am using a root find to find the parameters that give the desired results. There are two variables that are free to vary, but I was having difficulty running the root finder. I changed the code to solve for each variable individually and found out that I was having trouble optimizing one variable.
It seems that the problem is that gsl_multiroot_iterate is guessing nan for x1 after the first iteration. At least that is what the value of x1 is returning in the function() call after that point, when I put in a printf statement for x1.
The simulation I am running only allows values of x1 between 0 and 1. It could be possible that this is causing the issue, though I check in the simulation to make sure x1 is between 0 and 1, and never throws an issue besides when x1 is nan. Is there anyway to set a range for what values the iteration tries for x1? And would anyone know what the iteration tries using nan for x1?
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multiroots.h>
struct rparams{
double target1;
};
int function(const gsl_vector * x, void *params, gsl_vector * f);
int main(int argc, char* argv[]) {
double target1;
sscanf(argv[1],"%lf",&target1);
const gsl_multiroot_fsolver_type *T;
gsl_multiroot_fsolver *s;
int status;
unsigned int iter = 0;
const size_t n = 1;
struct rparams p;
p.target1 = target1;
gsl_multiroot_function f = {&function, n, &p};
double x_init[1] = {.1};
gsl_vector * x = gsl_vector_alloc(n);
gsl_vector_set(x, 0, x_init[0]);
T = gsl_multiroot_fsolver_hybrid;
s = gsl_multiroot_fsolver_alloc(T, 1);
gsl_multiroot_fsolver_set(s, &f, x);
print_state(iter, s);
do
{
iter++;
status = gsl_multiroot_fsolver_iterate (s);
print_state(iter, s);
/* check if solver is stuck */
if (status){
break;
}
status = gsl_multiroot_test_residual (s->f, 1e-7);
}
while (status == GSL_CONTINUE && iter < 1000);
printf("status = %s\n", gsl_strerror (status));
gsl_multiroot_fsolver_free (s);
gsl_vector_free (x);
return 0;
}
int function(const gsl_vector * x, void *params, gsl_vector * f){
double target1 = ((struct rparams *) params)->target1;
double x1 = gsl_vector_get(x, 0);
/* Run simulation here using x1 parameter */
/* Assign output to temp1, which I am trying to match to target1 */
const double y1 = temp1 - target1;
gsl_vector_set (f, 0, y1);
return GSL_SUCCESS;
}