a.mlw.walker
- 144
- 0
Cool! Ok, I'll get it, take a look, and see how far I can get.
void ros(double *p, double *x, int m, int n, void *data)
{
register int i;
for(i=0; i<n; ++i)
x[i]=((1.0-p[0])*(1.0-p[0]) + ROSD*(p[1]-p[0]*p[0])*(p[1]-p[0]*p[0]));
}
static double function(double *p, double *sum, int m, int n, void *data)
{
double Fitted_Curve[5] = {0};
double Error_Vector[5] = {0};
int i;
double a, b, c;
sum = 0;
// double v1[5], v2[5], geom_inv[5], norm = 0, norm_2 = 0, v2sum = 0, x_coeff = 0;
// Actual_Output[5] = {1.2, 2.693, 4.325, 6.131, 8.125};
// printf("Actual_Output[0[ = %f", Actual_Output[0]);
a = p[0];//parameters
b=p[1];
c=p[2];
for (i = 0; i <= 4; i++)
{
Fitted_Curve[i] = (1/(a*b))*(c-asinh(sinh(c)*exp(a*Input[i]*2*pi)));
Error_Vector[i] = Actual_Output[i]-Fitted_Curve[i];
printf("a(x[0]) = %f, b(x[1]) = %f, c(x[2]) = %f\n",p[0], p[1], p[2]);
printf("Fitted_Curve= %f\n", Fitted_Curve[i]);
printf("Error_Vector= %f\n", Error_Vector[i]);
}
for (i = 0; i <= 4; i++)
{
sum = sum + pow(Error_Vector[i],2);
printf("sum= %f\n", sum);
}
a_global = a;
b_global = b;
// x_coeff_global = x_coeff;
return sum;
}
int dlevmar_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata), /* functional relation describing measurements.
* A p \in R^m yields a \hat{x} \in R^n
*/
double *p, /* I/O: initial parameter estimates. On output contains the estimated solution */
double *x, /* I: measurement vector. NULL implies a zero vector */
int m, /* I: parameter vector dimension (i.e. #unknowns) */
int n, /* I: measurement vector dimension */
int itmax, /* I: maximum number of iterations */
double opts[5], /* I: opts[0-4] = minim. options [\tau, \epsilon1, \epsilon2, \epsilon3, \delta]. Respectively the
* scale factor for initial \mu, stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2 and the
* step used in difference approximation to the Jacobian. If \delta<0, the Jacobian is approximated
* with central differences which are more accurate (but slower!) compared to the forward differences
* employed by default. Set to NULL for defaults to be used.
m=3; n=5;
p[0]=1.0; p[1]=1.0; p[2]=-1.0;
for(i=0; i<n; i++) x[i]=0.0;
//ret=dlevmar_der(ros, jacros, p, x, m, n, 1000, opts, info, NULL, NULL, NULL); // with analytic Jacobian
ret=dlevmar_dif(function, p, x, m, n, 10000, NULL, info, NULL, NULL, NULL); // no Jacobian
break;
double p[5], // 5 is max(2, 3, 5)
x[16]; // 16 is max(2, 3, 5, 6, 16)
for(i=0; i<LM_INFO_SZ; ++i)
printf("%g ", info[i]);
printf("\n");
O: information regarding the minimization. Set to NULL if don't care
* info[0]= ||e||_2 at initial p.
* info[1-4]=[ ||e||_2, ||J^T e||_inf, ||Dp||_2, \mu/max[J^T J]_ii ], all computed at estimated p.
* info[5]= # iterations,
* info[6]=reason for terminating: 1 - stopped by small gradient J^T e
* 2 - stopped by small Dp
* 3 - stopped by itmax
* 4 - singular matrix. Restart from current p with increased \mu
* 5 - no further error reduction is possible. Restart with increased mu
* 6 - stopped by small ||e||_2
* 7 - stopped by invalid (i.e. NaN or Inf) "func" values; a user error
* info[7]= # function evaluations
* info[8]= # Jacobian evaluations
* info[9]= # linear systems solved, i.e. # attempts for reducing error
#define pi 3.141592653589793238462643
double Input[5] = {0, 1, 2, 3, 4};
double Actual_Output[5] = {1.2, 2.693, 4.325, 6.131, 8.125};
static double function(double *p, double *x, int m, int n, void *data)
{
double Fitted_Curve[5] = {0};
// double Error_Vector[5] = {0};
int i;
double a, b, c;
a = p[0];//parameters
b=p[1];
c=p[2];
for (i = 0; i <= 4; i++)
{
Fitted_Curve[i] = (1/(a*b))*(c-asinh(sinh(c)*exp(a*Input[i]*2*pi)));
x[i] = Actual_Output[i]-Fitted_Curve[i];
printf("a(x[0]) = %f, b(x[1]) = %f, c(x[2]) = %f\n",p[0], p[1], p[2]);
printf("Fitted_Curve= %f\n", Fitted_Curve[i]);
printf("Error_Vector= %f\n", x[i]);
}
}
int main()
{
register int i;
int problem, ret;
double p[3] = {0,0,0};
double x[5] = {0,0,0,0,0};
int n = 5;
int m;
double opts[LM_OPTS_SZ], info[LM_INFO_SZ];
char *probname[]={
"function"
};
opts[0]=LM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-20;
opts[4]= LM_DIFF_DELTA; // relevant only if the Jacobian is approximated using finite differences; specifies forward differencing
//opts[4]=-LM_DIFF_DELTA; // specifies central differencing to approximate Jacobian; more accurate but more expensive to compute!
problem=
0; // Can have more functions if user requires
#ifdef HAVE_LAPACK
#else // no LAPACK
#ifdef _MSC_VER
#pragma message("LAPACK not available, some test problems cannot be used")
#else
#warning LAPACK not available, some test problems cannot be used
#endif // _MSC_VER
#endif /* HAVE_LAPACK */
switch(problem){
default: fprintf(stderr, "unknown problem specified (#%d)! Note that some minimization problems require LAPACK.\n", problem);
exit(1);
break;
case 0:
/* function */
m=3;
p[0]=1.0; p[1]=1.0; p[2]=-1.0;
for(i=0; i<n; i++) x[i]=0.0;
//ret=dlevmar_der(ros, jacros, p, x, m, n, 1000, opts, info, NULL, NULL, NULL); // with analytic Jacobian
ret=dlevmar_dif(function, p, x, m, n, 100000, NULL, NULL, NULL, NULL, NULL); // no Jacobian
break;
} /* switch */
printf("Results for %s:\n", probname[problem]);
printf("Levenberg-Marquardt returned %d in %g iter, reason %g\nSolution: ", ret, info[5], info[6]);
for(i=0; i<m; ++i)
printf("%.7g ", p[i]);
printf("\n\nMinimization info:\n");
for(i=0; i<LM_INFO_SZ; ++i)
printf("%g ", info[i]);
printf("\n");
return 0;
}
void function(..., void *adata)
{
double *Actual_Data[5] = (double *)adata;
...
}
main()
{
double Actual_Data[5] = {...};
int ret = dlevmar_dif(..., Actual_Data);
}
void function2(double *p, double *x, int m, int n, void *data)//equations for parameters eta, phi and omega^2 that hold wheel properties
{
double c1[23], x_coeff_2[23], v1[23], v2[23];
double eta = p[0]; //parameters
double phi=p[1]; //parameters
double omega_2=p[2]; //parameters
int i;
a_global = 0.025;
b_global = 1.8944;
//c_global = -0.3690;
for (i = 0; i<23; i++)
{
v1[i] = (exp(a_global*2*pi)-cosh(a_global*b_global*init_T[i][0]));
v2[i] = sinh(a_global*b_global*init_T[i][0]);
x_coeff_2[i] = v1[i]/v2[i];
c1[i]= b_global*b_global*(x_coeff_2[i]*x_coeff_2[i]-1);
x[i] = sqrt(fabs(c1[i]*exp(-2*a_global*init_T[i][1])+eta*((1+0.5*(4*a_global*a_global+1))*cos(init_T[i][1]+phi)-2*a_global*sin(init_T[i][1]+phi))+b_global*b_global-omega_2));
}
}
a.mlw.walker said:Im getting an error on this line:
double *Actual_Data[5] = (double *)adata;
Invalid Initializer.
a.mlw.walker said:This function (my other function) runs but produces very different values from the matlab
I had to adjust it from the nelder mead (where it ran) because of the way levmar wants x[] passed back to it however the nelder mead matched the matlab. This issue is reason 2 (small Dp) again
static double rotor_function(int n, double z[],float ti[6])//equations for parameters eta, phi and omega^2 that hold wheel properties
{
double kappa = z[0], sum = 0,Rotor_Curve[6], Error_Vector[6], v0; //parameters
int i;
v0 = (1 + (kappa/2)*ti[0]*ti[0])/ti[0];
for (i = 0; i<6; i++)
{
Rotor_Curve[i] = (v0*ti[i]-(kappa/2)*pow(ti[i],2));
Error_Vector[i] = (i+1) - Rotor_Curve[i];
}
for (i = 0; i<6; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
}
printf("\n z = %f v0 = %f, sum = %f\n", z[0], v0, sum);
return sum;
}
case 2:
/* function 2*/
z[0] = 0.004;
n=1;
fopt = 0;
//This is still not running correctly, check MATLAB for correct parameter values:
if (NelderMeadSimplexMethod(n, rotor_function, z, length, &fopt, timeout, eps, ti) == success) {
printf("reaching to minimum ");
} else {
printf("timeout ");
}
kappa = z[0];
a.mlw.walker said:Hi so I have integrated the levmar and neldermead into one program so that I can use levmar to solve function1 and neldermead to solve function 2.What about prototypes tho? When do you need them and when do you not. For instance my functions function() and function2() don't have prototypes, however some other functions do have prototypes.
a.mlw.walker said:I need to pass the parameter as an array though I think not a variable
status NelderMeadSimplexMethod(n, f, xinit, length, fopt, timeout, eps, array1)
static double rotor_function(int n, double z[],float ti[6])//equations for parameters eta, phi and omega^2 that hold wheel properties
{
double kappa = z[0], sum = 0,Rotor_Curve[6], Error_Vector[6], v0; //parameters
int i;
v0 = (1 + (kappa/2)*ti[0]*ti[0])/ti[0];
for (i = 0; i<6; i++)
{
Rotor_Curve[i] = (v0*ti[i]-(kappa/2)*pow(ti[i],2));
Error_Vector[i] = (i+1) - Rotor_Curve[i];
}
for (i = 0; i<6; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
}
printf("\n z = %f v0 = %f, sum = %f\n", z[0], v0, sum);
return sum;
}
z[0] = 0.004;
n=1;
fopt = 0;
//This is still not running correctly, check MATLAB for correct parameter values:
if (NelderMeadSimplexMethod(n, rotor_function, z, length, &fopt, timeout, eps, ti) == success) {
printf("reaching to minimum ");
} else {
printf("timeout ");
}
kappa = z[0];