Matlab into C Function

This is a discussion on Matlab into C Function within the C Programming forums, part of the General Programming Boards category; Hi I have written a function in matlab that I now want to convert to C. However Matlab has matrices ...

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    190

    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. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,207
    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).
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    190
    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.
    Name:  console.JPG
Views: 1254
Size:  65.6 KB
    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. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    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. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    190
    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. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    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. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    190
    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!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Matlab Help
    By anirban in forum Tech Board
    Replies: 1
    Last Post: 09-02-2010, 05:00 AM
  2. Array equivalent to MatLab's 'find' function
    By magda3227 in forum C Programming
    Replies: 2
    Last Post: 06-16-2008, 02:54 PM
  3. C++ to matlab
    By loga in forum C++ Programming
    Replies: 1
    Last Post: 02-10-2008, 12:33 AM
  4. Matlab vs. R
    By ch147 in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 11-14-2007, 10:57 AM
  5. MATLAB Help
    By Lrnr in forum Tech Board
    Replies: 2
    Last Post: 02-23-2003, 09:29 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21