# Thread: Matlab into C Function

1. ## Matlab into C Function

Hi I have written a function in matlab that I now want to convert to C. However Matlab has matrices functions where C does not. I have converted the function and I now think that the two should be doing the same thing however the C version is calculating #QNAN0 in other words the value is tending to infinity due to a /0.

I was wondering if there is someone out there who has used both matlab and C and can tell if i have made a mistake - I cant see it

So I have solved a problem in matlab and it works brilliantly. However my boss requires the method in C. I am doing a least squares minimization using fminsearch. I am trying to replicate the function being solved for in C (I already have the neldermead function in C)

My matlab function to be solved is:

Code:
```function sse=myfit(params,Input,Actual_Output)
global c
a=params(1);
b=params(2);

x = (exp(a*2*pi)-cosh(a*b*Actual_Output))/sinh(a*b*Actual_Output);
c = -1/atanh(x);
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);```
And this is what I am trying to replicate in C:

Code:
```static double function(int n, double x[])
{
double c[5], x_coeff[5];
double Fitted_Curve[5];
double Error_Vector[5];
int i;
double Actual_Output[5]={1.2, 2.693, 4.325, 6.131, 8.125};
double Input[5]={1, 2, 3, 4, 5};
double sum = 0;

for (i = 0; i <= 4; i++)
{

x_coeff[i] = (exp(x[0]*2*pi)-cosh(x[0]*x[1]*Actual_Output[0]))/(sinh(x[0]*x[1]*Actual_Output[0]));

c[i] = (-1)/(atanh(x_coeff[i]));

Fitted_Curve[i] = (1/(x[0]*x[1]))*(c[i]-asinh(sinh(c[i])*exp(x[0]*Input[i]*2*pi)));

Error_Vector[i] = Actual_Output[i]-Fitted_Curve[i];

printf(" x_coeff(%d) =   %f  %f\n", i, x_coeff[i], c[i]);
}

for (i = 0; i <= 4; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
}

return sum;

}```
I know I am not passing the function the vectors in C but declaring them everytime, but I dont think this will effect the result as the vectors are constant?
It doesnt give the same answer (atanh(x>1) = inf) which obviously suggests they are not doing the same thing. Can anyone see where I have gone wrong?

Thanks

2. Matlab is smart enough to detect that you're computing 1/infinity and give a result of zero. C is not.

Usually, rather than just trying to map matlab to C, you are better off working back to a human-readable description of the algorithm, and working out the best way to implement that. It would probably have helped to do things using the same variable names (such as a and b), but that's a quibble on clarity only (it is harder to get code right if it is not written clearly).

3. Ok so for clarity I have changed the parameters to a and b:
Code:
```static double function(int n, double x[])
{
double c[5], x_coeff[5];
double Fitted_Curve[5];
double Error_Vector[5];
int i;
double Actual_Output[5]={1.2, 2.693, 4.325, 6.131, 8.125};
double Input[5]={1, 2, 3, 4, 5};
double a, b, sum = 0;

/*double	x0, x1;

x0 = x[0];
x1 = x[1];
return (x0-2)*(x0-2) + (x1-3)*(x1-3);
*/
a = x[0];
b=x[1];

for (i = 0; i <= 4; i++)
{

x_coeff[i] = (exp(a*2*pi)-cosh(a*b*Actual_Output[i]))/(sinh(a*b*Actual_Output[i]));

c[i] = (-1)/(atanh(x_coeff[i]));

Fitted_Curve[i] = (1/(a*b))*(c[i]-asinh(sinh(c[i])*exp(a*Input[i]*2*pi)));

Error_Vector[i] = Actual_Output[i]-Fitted_Curve[i];

printf(" x_coeff(%d) =   %f  %f\n", i, x_coeff[i], c[i]);
}

for (i = 0; i <= 4; i++)
{
sum = sum + Error_Vector[i]*Error_Vector[i];
}

return sum;

}```
where it prints x_coeff and c, I have attached some of the output in the console, where x_coeff = 1, c = -0.114905.

The human readable form is the original equation I derived. My problem is whether C is doing what I expect it to be doing:
The vectors Input and Actual_Output, are they ok here or could this be a problem?
By returning sum, that does not include x[0] and x[1], will they be updated by the function that called them? I am worried that they are not being updated?

As far as I understand, the code is calculating an x_coeff, c, Fitted_Curve, Error_Vector for each value of Input and Actual Output
then it is summing the squares of the Error_Vector variable and returning that value to the function that called it.

But this isnt the problem, the problem is the values of x_coeff are not the same as they are in matlab, i dont think this is anything to do with the loop, I think this is a maths issue???

4. 54 posts, and finally a post that contains usable information! I applaud you sir.

There's nothing wrong with Input or Actual_Output.

Nobody is updating x[0] or x[1] here in this function. If you had updated x[0] or x[1] in this function, then those changes would be seen in main (or wherever you called this function from). Matlab wasn't updating a or b as far as I could see either, so I don't know how you want x[0] or x[1] to update. The part you've written under "As far as I understand" is all correct.

I can't test the numbers until you tell me what x[0] and x[1] are, and what you've defined pi to be.

5. Hi tabstop: yeah I know not very good at posting am I. As confidence grows though... I have managed to get further with the function. I didnt before understand what the '/' was actually doing in matlab, I later found out t is taking the norm of the vector, so my function code has now been updated to calculate this. the good new is I am getting real numbers, the bad news is they dont match to my matlab:
Code:
```static double function(int n, double x[])
{
double c;
double Fitted_Curve[5];
double Error_Vector[5];
int i;
double Input[5]={1, 2, 3, 4, 5};
double a, b, sum = 0;
double Actual_Output[5]={1.2, 2.693, 4.325, 6.131, 8.125}, v1[5], v2[5], geom_inv[5], norm, norm_2, v2sum, x_coeff = 0;

a = x[0];
b=x[1];
for (i = 0; i<=4; i++)
{
v1[i] = (exp(a*2*pi)-cosh(a*b*Actual_Output[i]));
v2[i] = (sinh(a*b*Actual_Output[i]));
//printf("%f\n", v1[i]);
}
for (i = 0; i<=4; i++)
{
v2sum=v2sum+(v2[i]*v2[i]);
}
norm = sqrt(v2sum);
//printf("%f", norm);
norm_2 = norm*norm;
for (i = 0; i<=4; i++)
{
geom_inv[i] = v2[i]/norm_2;
}

for (i = 0; i<=4; i++)
{
x_coeff = x_coeff + v1[i]*geom_inv[i];

}
printf("a = %f, b = %f, x = %f\n",a,b, x_coeff);

c = (-1)/(atanh(x_coeff));
//printf(" c(%d)=  %f\n",  i, c);
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];
}

return sum;

}```
I worked this out by writing a program in C to replicate the matlab calculation of x:

Code:
```void main()
{
double Actual_Output[5]={1.2, 2.693, 4.325, 6.131, 8.125}, v1[5], v2[5], geom_inv[5], norm, norm_2, v2sum, a, b, x_coeff;
int i;

a = -1;
b=1;
for (i = 0; i<=4; i++)
{
v1[i] = (exp(a*2*pi)-cosh(a*b*Actual_Output[i]));
v2[i] = (sinh(a*b*Actual_Output[i]));
//printf("%f\n", v1[i]);
}
for (i = 0; i<=4; i++)
{
v2sum=v2sum+(v2[i]*v2[i]);
}
norm = sqrt(v2sum);
//printf("%f", norm);
norm_2 = norm*norm;
for (i = 0; i<=4; i++)
{
geom_inv[i] = v2[i]/norm_2;
}

for (i = 0; i<=4; i++)
{
x_coeff = x_coeff + v1[i]*geom_inv[i];
}
printf("%f", x_coeff);
}```
I then just added that back in to calculate x_coeff.
When the program is run by itself it calculates the same value as the matlab code for x_coeff, however run in the loop and it changes the value of x_coeff where matlab keeps it constant.
The equivelent matlab is:
Code:
```Data=[1.2 2.693 4.325 6.131 8.125]
a=1;b=1;
v1=(exp(a*2*pi)-cosh(a*b*Data));
v2=sinh(a*b*Data);
x = (exp(a*2*pi)-cosh(a*b*Data))/sinh(a*b*Data)
x1=v1*(v2/norm(v2)^2)' %Inverse Vector using Geometric Multiplication```
i.e in the above x and x1 are the same, therefore i used the basis of x1 to calculate it in C.
I started x[0] on -1, and x[1] on 1. pi is defined as 3.1415 at the moment.

6. It's a common thing for people to do: you've been working on the problem so long that you forget that we haven't. You'll do fine.

I don't see where you start your x_coeff off with any sort of initial value. You're adding things together to get this x_coeff, so you should probably set x_coeff to 0 at the beginning of the loop.

7. You saint. That was it, if you look in the top block of code in my last post x_coeff is set to 0, however v2sum was not.
Thank you!