Minimizing function in Matlab and C

In summary: Error_Vector^2, the second iteration is the sum of the squares of the Error_Vector entries, and the third iteration is the sum of the squares of the Error_Vector entries plus the original value of the sum.In summary, the code to minimize a function using the NelderMead method produces different results depending on the language used. The C code produces a different first result that the MATLAB code.
  • #71
Yep, the green line fits better! :smile:
 
Physics news on Phys.org
  • #72
Im getting an error on this line:
double *Actual_Data[5] = (double *)adata;
Invalid Initializer.This function (my other function) runs but produces very different values from the matlab
Code:
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));
}

}
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
 
  • #73
a.mlw.walker said:
Im getting an error on this line:
double *Actual_Data[5] = (double *)adata;
Invalid Initializer.

Sorry, I intended:
double *Actual_Data = (double *)adata;


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

Well, is it a good solution that it found?
What is info[1], which is the found SSE?

To be honest, I'm not sure Levenberg-Marquardt will work as intended with your function, since it is not intended for a sum of absolute errors, but for a sum of squared errors.
I believe it should still work, but it may not find an optimal solution.
Nelder-Mead may be a better choice for this problem (minimizing the sum of absolute errors).
 
  • #74
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.

My third function:
Code:
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;

}
doesnt have a prototype - however it also doesn't receive the initital guess at the parameter.
It is called like:
Code:
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];
i need to pass the parameter as an array though I think not a variable
 
  • #75
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.

As long as you define your function (including the body) before using it, you don't need a function prototype.
If you need a prototype, you'll know, because the compiler will complain he doesn't know the function.

a.mlw.walker said:
I need to pass the parameter as an array though I think not a variable

I can't recall the list of parameters to your Nelder-Mead function.
But if it doesn't have a "void *data" pointer as a parameter, you need to use a different mechanism, which is as follows.

The way to do it, is to define a global variable to pass your Actual_Data[] array.
You use this global variable in your function.
And just before you call Nelder-Mead, you copy your Actual_Data[] array into the global variable.
 
  • #76
Neldermead function is like this:
Code:
status NelderMeadSimplexMethod(n, f, xinit, length, fopt, timeout, eps, array1)
my function that is failing is like this:
Code:
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;

}
I am calling both like this:
Code:
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];
It seems to me like function2 however this one doesn't ever have a value for z[0]
 
  • #77
I found the problem. z is getting there howere the maths is going haywire! v0 is not being calculated correctly - is this because of a problem with multiplying floats and doubles?
 

Attachments

  • Capture.JPG
    Capture.JPG
    13 KB · Views: 433
  • #78
It's weird to see a parameter like "float ti[6]".
I suspect it should be "double ti[6]".
The mismatch could cause your problems.

Don't you get a compiler warning?
What is the prototype of your Nelder-Mead function, and what function prototype does it expect exactly as a parameter?
 
  • #79
Hey how are you, been a while.
I am working more with the levenberg marquardt code now.
I am trying to get it to use just single precision - this is an option in levmar.h
Out of interest, what happens if a variable has been declared as double but in levmar.h i state i want single precision?
when I choose single precision I get an error - a strange one at that.
Axb_core.c|1103|error: 'FLT_EPSILON' undeclared (first use in this function)

It works fine with double but not with single. I find this odd considering the author offeres single precision accuracy.
Any ideas what the problem could be?
 

Similar threads

Replies
10
Views
2K
Replies
2
Views
1K
Replies
2
Views
1K
Replies
3
Views
4K
Replies
8
Views
2K
Replies
8
Views
2K
Replies
1
Views
2K
Back
Top