# MATLAB Minimizing function in Matlab and C

1. Aug 16, 2011

### a.mlw.walker

The foloowing code is the matlab code to minimize a function using the nelder mead method.

Code (Text):

Starting=[1 1 -1]; options=optimset('Display','iter'); Estimates=fminsearch(@myfit,Starting,options,t_d,Data) Calling: function sse=myfit(params,Input,Actual_Output) a=params(1); b=params(2); c=params(3);

Fitted_Curve = (1/(a*b))*(c-asinh(sinh(c)*exp(a*Input*2*pi)));
Error_Vector=Actual_Output-Fitted_Curve ;
sse=sum(Error_Vector.^2);

This is supposed to be the equivelent C code, however it doesnt produce the same results. Can anyone see what I may have done wrong?
Code (Text):

static double function(int n, double x[])
{
double c;
double Fitted_Curve[5];
double Error_Vector[5];
int i;
double a, b, 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};
a = x[0];
b=x[1];
c=x[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];
}
for (i = 0; i <= 4; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
}
printf("sum = %f\n", sum);
a_global = a;
b_global = b;
// x_coeff_global = x_coeff;
return sum;
}

Thanks

2. Aug 16, 2011

### I like Serena

Hi a.mlw.walker!

The C function that you're showing is functionally a match for the myFit() function that you specified as matlab code.

Do you also have an implementation of the fminsearch() function?
If so, what does it expect as input?

3. Aug 16, 2011

### a.mlw.walker

the fminsearch function is a matlab function implementing the NelderMead algorithm. I know the matlab is correct because I have the solution. However the C does not produce the same final result but does produce the same first result!!!!
Matlab produces:
a = 0.0250 b= 1.8944 c= -0.3690
C code produces
a = 3.52, b = 3.634 c= -0.000073
Check the pics:

#### Attached Files:

File size:
19.4 KB
Views:
254
• ###### sse.JPG
File size:
9.9 KB
Views:
223
4. Aug 16, 2011

### I like Serena

You pictures seem to basically show that the C function is indeed a match for the matlab function.

So either your fminsearch is not doing its work like it does in matlab.
Or, what seems more likely, the parameters are syntactically not passed properly to the function.
Or the boundary conditions are not set properly.

Did you already print the values of a, b, and c during the iterations?

What are the values in your Input[] array?

Did you already check if the given solution by the C code is actually a solution for the problem, since it may have found another minimum (if your boundary conditions are set up differently)?

5. Aug 16, 2011

### a.mlw.walker

I'll get it to print earlier values of a, b and c and post them. Yeah i plotted the points found by C and it doesnt find a curve that fits. input is just [1 2 3 4 5], thats what it is in both matlab and C.
Its a strange error considering the values for the first iteration are the same, but I know the Matlab is correct, I have the solution to that from previous work - and it is a solution. The problem is in the C.
I'll get a b and c for the first iteration

6. Aug 16, 2011

### I like Serena

While you're at it, also print the values of 'sum' (the sse) in your function, since we'd like to see if it converges or not.

7. Aug 16, 2011

### a.mlw.walker

in the C code right, not the matlab?

8. Aug 16, 2011

### I like Serena

Both! :)

9. Aug 16, 2011

### a.mlw.walker

Ok here we go. three iterations of both, matlab in white, c in black...

#### Attached Files:

File size:
47.2 KB
Views:
299
• ###### matlab 3 iter.JPG
File size:
16.4 KB
Views:
290
10. Aug 16, 2011

### I like Serena

I'm just noticing that in all your pictures the sum/sse does not match the Error_Vector.
The sum/sse should be the sum of the squared entries of the Error_vector.
In all cases (except perhaps the last) it isn't.

In your original 2 pictures the sum and sse appear to be the square of only the first entry in the Error_Vector.

So what did you print for the sum/sse?

In your last 2 pictures, there are 5 sums displayed in the console dump.
They appear to be the squares of the individual Error_Vector entries, but they should still be added.
In the matlab output, there is only one sse, that may well be the sum needed.

This means the code you have shown in the opening post apparently does not match the code you have just executed.

11. Aug 16, 2011

### a.mlw.walker

The original images were just to see whether it was doing the sum my calculator was expecting - i.e just the first Error_Vector^2. The latest images (my last post) is the actual output after three iterations from NelderMead. look at the latest images.

12. Aug 16, 2011

### a.mlw.walker

Sorry your right, the C code for sum is not producing the correct values...

13. Aug 16, 2011

### I like Serena

Yes, I believe I have.
The displayed sums for 1 iteration need to be added, and that has to be used as the result.
That should match the matlab output.

14. Aug 16, 2011

### a.mlw.walker

Hmm, sorry I had removed that in a recent debugging session. I have put it back in, and attached again the first three iterations, but its still not right
I have changed the sum code to

Code (Text):

for (i = 0; i <= 4; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
printf("sum= %f\n", sum);
}

#### Attached Files:

• ###### fittedcurelatest.JPG
File size:
44.6 KB
Views:
232
15. Aug 16, 2011

### I like Serena

All right.
Now it shows the same result for the first iteration as matlab.

As you can see, it also converges.
But it converges much faster than the matlab version.

This suggests that you're using a different algorithm.
Since you've presumably used a function with the same name (fminsearch), do you have the option of giving method-parameters?
What you have in C might for instance be the Conjugate gradient method.

(You did use a function by the name of fminsearch didn't you?)

16. Aug 16, 2011

### a.mlw.walker

The function for the C is called NelderMead.c. Fminsearch is a built in matlab function that according to Matlab is the Neldermead method. I'm not bother how fast it converges if the answer isnt correct though...

17. Aug 16, 2011

### I like Serena

There could be more than one solution.
Could you show the final a, b, c, and sse to judge that?

And perhaps you could also show the a, b, and c in each iteration to see how the algorithm progresses?

Last edited: Aug 16, 2011
18. Aug 16, 2011

### I like Serena

I just checked.
Your problem does have multiple solutions.
So perhaps you want the solution closest to your initial guess?
Or doesn't it matter to you?

19. Aug 16, 2011

### a.mlw.walker

really, mulitple solutions? i tried the values i earlier posted and it did not produce a solution - I am looking for a curve to fit data points, and the curve those values gave did not fit the data like the matlab

20. Aug 16, 2011

### I like Serena

Ah, I missed your solutions for a, b, c before.

They are both solutions.
The matlab version has an sse = 0.0037.
The C version has an sse = 0.099

This suggests that the C version stopped at a tolerance of 0.1.
You can probably tweak your parameters somewhere.

Btw, you should know that your data is almost on a straight line, and that whatever parameters you feed your formula, it's also almost a straight line.
So I think you shouldn't expect very interesting solutions.

What are you using this for?