Thread: Parameter estimation Nelder Mead

  1. #46
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by a.mlw.walker View Post
    I'm an engineer not a computer scientist.
    So tell me... are you as sloppy as an engineer as you are as a programmer?

    No that's not an insult... it's something you really should think about. I'm betting that when you are designing a project, you sit down with the requirements, analyze the task, work out a preliminary sketch and then get busy planning your invention and then finally work fastidiously creating a protype and testing the result... Why would you approach something as complex as beep-6 math programming any differently?

    Your problem is not C or even the lack of C knowledge... it's that you're approach to this whole thing is so haphazard that you can't even understand the advice you are being given...

    Best advice I can give you... same as before... sit down with a C textbook, work it page by page, example by example... then come back to this project when you're ready to take it seriously.
    Last edited by CommonTater; 08-17-2011 at 12:11 PM.

  2. #47
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    I think you might be dancing on the very question that scientists ask of engineers daily. Engineers dont spend their life devoted to one task. They learn what is required for the problem at hand. I planned this project, and successfully simulated the problem in Matlab - the programming language of scientists and engineers who require answers.
    The C part of this is the learning part of this project up until then the project was carefully worked out - start to end. Matlab is doing the expected in all situations.
    When you dont know what you are doing, you learn what is required, TEST IT, try to find the problems, learn what is required adjust it and TEST again. I learnt what was required to get the function NelderMead.c to run, I followed the fragment of information about the function to work out how to get it working. The C is running, and for one iteration it gives the same numbers as Matlab. We have agreed therefore the mathematical equations are doing the "correct" maths.
    I now do not know where to look for the next problem - to get the C working I do not have a plan. you are saying to remove the global variables and send them correctly to the functions. So that will be the next thing I do, but logically if my global variable names are not overlapping, i cant see that being the solution. however I will learn that now - get rid of ALL global variables. I will break the mathermatics into more functions - I will come back then. Still sure it is finding a local minimum though.

  3. #48
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by a.mlw.walker View Post
    No offense taken. The thing that confuses me is that for the first iteration of the problem, the printout of the C is exactly the same as the matlab. However the second iteration is different (and wrong because the matlab gives the right answers - i have the solution).
    You've done a good job figuring out the problem. Now it's not like the outputs for the second iteration happen via magic - they're based on the same calculations as the first one. So print out the values used at the start of the second loop and the results of the intermediate steps to get to the answers in both the C code and Matlab. Or compare the C output to work done by hand. Whatever mix of easy and error prone you wish to pick. Sooner or later you'll see the intermediate results diverge between the correct one and the C code. That will help you isolate the problem. Keep doing this on smaller and smaller sections of code until you narrow it down and find the problem.

    I know the thread has moved on since this post, but still, that's how you're going to have to debug. If you can figure out how to use a debugger, it'll let you look at any values along the way so you won't have to explicitly code up printf() calls so it might save some time. But the net effect is the same. At some point you're in good shape and some time after that you're not. Trace what happens between those two points and see what's broken.

    We have agreed therefore the mathematical equations are doing the "correct" maths.
    In one specific instance. Either results from the successful iteration aren't getting passed to the next one, or the second iteration exercises a bit of code that the first one doesn't. Which of the two is it? You're not going to find out by guessing.
    Last edited by KCfromNC; 08-17-2011 at 12:38 PM.

  4. #49
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    The problem is that you did a crappy job with learning --really learning-- C. By your own declaration you "learnt what was required to get the function NelderMead.c to run" and I'm guessing your programming education stopped right about there... Now you have this horrific mess of global variables, unused variables, functions that don't work as expected and code that quite frankly looks like a dog's breadfast... You did not learn what is needed to write a program that correctly solves your NelderMead function... you learned enoubh to make the function run... But there is one huge difference between getting something to compile and writing a program that works correctly.

    Sloppy doesn't work in C. (As you are slowly finding out.)

  5. #50
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    As you acknowledge, Matlab is intended for non-programmers. If you have not used any other language before, you probably have a somewhat superficial notion of what programming is about because your experience all comes from that simplified environment. This is going to be especially painful in C, which is intended to deal with many "lower level" issues not exposed to the user in Matlab. Without an understanding of those issues, you are running around blindfolded.

    Trying to skip learning the basics of the language and "wing it" is only going to end in frustration. The truth is: you are not qualified to do this. If you are an engineer, it may be useful for you to learn a general purpose programming language (C being one choice, but not necessarily the best). However, there is no way around the "learning" part.

    If a non-engineer came to you for help with a complex engineering task and admitted, "All I know about math is basic arithmetic", how long do you think it would take to give that person a grasp of the algebra, calculus, et. al. necessary in order to accomplish the task? What parts of those fundamentals do you think they will be able to just skip, and yet still be able to use all the higher level tools and concepts without problem or confusion? How worthwhile would you consider trying to help such person if they kept insisting they understand what is going on when they clearly do not ("I just need to get this part right...now this part...now this...I know what's wrong...it's just this...I don't have time for that...that doesn't matter because" ad infinitum)?

    Quote Originally Posted by a.mlw.walker View Post
    I think you might be dancing on the very question that scientists ask of engineers daily. Engineers dont spend their life devoted to one task. They learn what is required for the problem at hand.
    I understand this difference but I still think you are extrapolating beyond reason. A civil engineer may not have the same knowledge as a physicist, but they know enough to build a bridge. Becoming an engineer involves more than just dealing with a sequence of "tasks at hand"; it involves a long formal education spent learning essential basics that may or may not seem to have any application at the time. Without that, there are going to many elements of "the task at hand" which you won't even recognize, and so you won't "learn what's required". You'll just do it wrong and wonder what happened when it collapses.

    Just being a smart guy who's willing to deal "with the task at hand" does not qualify you to build the bridge, otherwise plumbers and welders and completely unskilled laypeople could design and implement all our infrastructure, right? What's the difference?

    You just don't meet the bar in this case.
    Last edited by MK27; 08-17-2011 at 01:34 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #51
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    My sides are splitting with laughter here. You guys are funny.
    Trying to skip learning the basics of the language and "wing it" is only going to end in frustration
    This is sooo true. I have programmed C before - before I learnt matlab, but never grasped a pointer or sending variables through functions.
    You are all absolutely right. I treated the C like Mtlab, learnt what the function requires and sent it that. However debugging C is a lot harder - and if you dont understand you'll never get it.
    Ok, no more sloppy C. I am going to clear up all global variables. Im also going to check the second iteration on my (very conveniently) programmable calculator.

    In terms of learning C and removing global variables, I have closed my Nelder Mead Project and started this one:
    Code:
    #include <stdio.h>
    
    float printarr(int a[], float scalar) {
        int i;
        float sum = 0;
        for(i = 0;i<5;i++) {
           sum = (sum + a[i])*scalar;
            }
            printf("sum = %f\n", sum);
    return sum;
    }
    float brain(float scalar) {
        int a[5];
        int i;
        float sum = 0;
    
        for(i = 0;i<5;i++) {
            a[i]=i;
        }
        sum = printarr(a, scalar);
        printf("sum = %f", sum);
    return 0;
    }
    
    main()
    {
        float scalar = 5;
        brain(scalar);
    }
    here I am just sending an array and a float variable. I wanted to make sure I understand this as this is what I am trying to pass around. Would anyone like to comment? Do I need a prototype for the function?
    I read somewhere, that you shouldnt pass variables back to main? Is this standard practice?
    I have passed scalar to a function and then to another function - is this the best way to do it?
    So do you usually call a function from main, that does all the calling of functions so that main doesnt need to be passed anything?
    Last edited by a.mlw.walker; 08-17-2011 at 01:54 PM.

  7. #52
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Potentially dumb question, but why are you passing in 3 as n and then ignoring it by hard-coding 5 in your objective function? Seems like those values have something to do with each other.

  8. #53
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    sorry KC, I cant see where I set n to 5? n is the number of parameters

  9. #54
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    I read somewhere, that you shouldnt pass variables back to main? Is this standard practice?
    No... it's not standard practice and there's nothing wrong with returning a value from any function into any other function. I have programs where main() is literally thousands of lines long and you aren't going to do that without calling functions that return values.

    However; the correct skeleton program in C looks like this...
    Code:
    int main (void)
     { 
        // your code here
    
       return ErrorLevel;  // usually 0
    }
    main() returns an integer ErrorLevel back to the operating system which it uses for various reasons. Most programs simply return 0, but some return values used in batch file processing and still others return actual error reports to the OS... but they ALL return something.

    Where you might see main() alone is in uC programming where most often main() is windowdressing for "OS, What OS? I don't need no stinking OS..."

  10. #55
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by a.mlw.walker View Post
    My sides are splitting with laughter here. You guys are funny.
    Funny "ha-ha" or wtf funny?

    In terms of learning C and removing global variables, I have closed my Nelder Mead Project and started this one:
    Resolving syntax conundrums and the like in short "premise test" programs is a very very wise idea. Trying to do the same within your main project code is usually a recipe for wasting time and becoming more perplexed.

    I wanted to make sure I understand this as this is what I am trying to pass around. Would anyone like to comment?
    What you have there is fine, presuming the output is what you are expecting. Two major issues you need to be aware of WRT to the passing of arguments are

    1) the difference between a local stack variable and an allocated heap variable.
    2) the difference between pass by value and pass by reference. Altho in strict, literal terms C only ever does the former, more pragmatically pointers can be understood as accomplishing the latter (for example, with an array).

    It's hard to get far until you are comfortable with pointers, BTW.

    Do I need a prototype for the function?
    You'll know if you needed a prototype because the compiler will clue you in (and always keep your compiler warnings enabled). As long as a function has been declared or defined before it is called, there will not be a problem. Prototypes are declarations; the primary purpose is to let the compiler know the function exists (and is presumably defined somewhere too). This way you can have function_a which may call function_b in its definition, and function_b which may call function_a in its definition, because both of them have already been declared (via a prototype) before hand.

    I read somewhere, that you shouldnt pass variables back to main? Is this standard practice?
    You must have misunderstood something because that would be a very bizarre practice. There's nothing wrong with passing values back to main. Perhaps this was to do with the value/reference complication. That is not peculiar to main(), but it might seem that way in a simple example.

    Code:
    #include <stdio.h>
    
    void eg1 (int *x) {
    	*x *= 2;
    	printf("eg1: %p %d\n", x, *x);
    }
    
    void eg2 (int x) {
    	x *= 2;
    	printf("eg2: %p %d\n", &x, x);
    }
    
    int main(void) {
    	int n = 2;
    
    	eg1(&n);
    	printf("%p %d\n", &n, n);
    	eg2(n);
    	printf("%p %d\n", &n, n);
    
    	return 0;
    }
    Technically, the argument to both eg1() and eg2() is "passed by value" -- in the first case, the value is a memory address for a pointer, in the second it's an integer value from a memory address. But pragmatically you might understand x as having been "passed by reference" to eg1(), and observe this makes it possible to affect n's value back in main (which could be any function; again main() does not have any special properties in this sense). Also notice that the address of x in eg2() is not the same, whereas the address used in main() and eg1() are.
    Last edited by MK27; 08-17-2011 at 02:34 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #56
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Cool.
    I am following the rules in this piece of code I have made to try to pass variables in my bigger proble - to remove the globals.
    Code:
    #include <stdio.h>
    
    float printarr(int a[], float scalar) {
        int i;
        float sum = 0;
        for(i = 0;i<5;i++) {
           sum = (sum + a[i])*scalar;
            }
            printf("sum = %f\n", sum);
    return sum;
    }
    float brain(int a[], float scalar) {
    float sum;
    // a and scalar sent to printarr
        sum = printarr(a, scalar);
        printf("sum = %f\n", sum);
    return sum;
    }
    
    main()
    {
    int a[5];
    int i;
        float sum = 0;
    
        for(i = 0;i<5;i++) {
            a[i]=i;
        }
    
        float scalar = 5;
        //sending brain scalar and array a.
        sum = brain(a, scalar);
        printf("sum = %f", sum);
    }
    C is popping up an error on thisline,
    Code:
    extern status NelderMeadSimplexMethod(n, f, xinit, length, fopt, timeout, eps, float array1[], float array2[]) //array1 and array2 allow two arrays to be passed to another function through NM
    apparantly it is expecting a bracket before float.
    and then at the beginning of the NelderMead function it says
    expected identifier or '(' before '{' token|
    Code:
    dbl	length;
    dbl	*fopt;
    int	timeout;
    dbl	eps;
    {
    	status	stat = failure;
    	int	count, i;
    
    	nvar = n;
    	objective = f;
    
    	initialize();
    	initial_simplex(xi
    Could anyone explain why because it seems the same method as in the example above, and that runs

  12. #57
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by a.mlw.walker View Post
    sorry KC, I cant see where I set n to 5? n is the number of parameters
    It's hard-coded in the for loops in function(). You pass in the value 3 for n then it's totally ignored in function - you use for (i = 0; i <= 4; i++) in the function() call. That's 5 iterations of the loop. I assumed the n value matching nvar in neidermead.c would be important but maybe they are unrelated?

    But since the code seems to diverge from the Matlab stuff in this loop :

    Code:
            for (i=0; i<=nvar; i++) {
               printf ("\t***fvalue[%d] = \n", i);
                    fvalue[i] = (*objective)(nvar, simp[i]);
            }
    And there's a dependency on n/nvar there (both explicitly and in the initialization of simp[]), it seemed suspicious.


    extern status NelderMeadSimplexMethod(n, f, xinit, length, fopt, timeout, eps, float array1[], float array2[])
    I think the compiler is complaining because you're mixing old and new ways of defining function arguments. Pick one or the other :

    int foo (int bar, float array[]) or

    Code:
    int foo(bar, array)
    int bar;
    float array[];
    Last edited by KCfromNC; 08-17-2011 at 02:42 PM.

  13. #58
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    n is number of x parameters i.e n=3 and there are the parameters are x[0], x[1], x[2].

  14. #59
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by a.mlw.walker View Post
    C is popping up an error on thisline,
    Code:
    extern status NelderMeadSimplexMethod(n, f, xinit, length, fopt, timeout, eps, float array1[], float array2[]) //array1 and array2 allow two arrays to be passed to another function through NM
    I'm presuming "n, f, xinit, length, fopt, timeout, eps" are individual labels (names) and not pre-defined types.

    Prototypes/function declarations can contain types without specific variable names, eg:

    Code:
    void my_proto(int, int, char*);  //okay
    But not vice versa:
    Code:
    void my_proto(a, b, str);  // no good unless a, b, and str are typedefs.

    apparantly it is expecting a bracket before float.
    and then at the beginning of the NelderMead function it says "expected identifier or '(' before '{' token|"
    Unfortunately, the compiler is easily thrown off by faulty nesting and missing braces. Sometimes this can be due to some other error, such as a missing colon. Keep in mind that the compiler actually makes a number of passes thru the code, and subsequent passes are interpreted on the basis of information gathered in the previous one. So errors like that can be a real pain to pinpoint, because the mistake is not where "the error" shows up; the mistake may even be in a different file that was included before the current one was parsed. This is something you develop a feel for. Using a syntax highlighting editor that reacts to braces and nesting is essential -- if you aren't, you should find one immediately.

    There does look to be a missing ) on the last line, dunno if that was just from cut n' paste.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #60
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Forget your other stuff for a while... concentrate on these smaller "learning" pieces...

    Code:
    float printarr(int a[], float scalar) {
        int i;
        float sum = 0;
        for(i = 0;i<5;i++) {
           sum = (sum + a[i])*scalar;
            }
            printf("sum = %f\n", sum);
    return sum;
    }
    float brain(int a[], float scalar) {
    float sum;
    // a and scalar sent to printarr
        sum = printarr(a, scalar);
        printf("sum = %f\n", sum);
    return sum;
    }
    
    main()
    {
    int a[5];
    int i;
        float sum = 0;
    
        for(i = 0;i<5;i++) {
            a[i]=i;
        }
    
        float scalar = 5;
        //sending brain scalar and array a.
        sum = brain(a, scalar);
        printf("sum = %f", sum);
    }
    Ok... look at main() for a minute... you defined an array a[5] as having 5 elements... Now when you pass this to a function, it decays to a pointer, the function itself does not know how big a is... So, it's often best to pass in the size of a as a parameter... like this...
    Code:
    #include <stdio.h>
    #include <math.h>
    #define sARRAY 5   // size of array
    
    
    float printarr(int *z, int size, float scalar) {
        int i;
        float sum = 0;
        for( i = 0; i < size ; i++) {
           sum = (sum + z[i])*scalar;
            }
            printf("sum = %f\n", sum);
    return sum;
    }
    
    
    float brain(int *q, int size, float scalar) {
    float sum;
    // a and scalar sent to printarr
        sum = printarr(q, size, scalar);
        printf("sum = %f\n", sum);
    return sum;
    }
    
    
    
    int main( void )
    {
        int a[sARRAY];
        int i;
        float sum = 0;
        float scalar = 5;
    
        for( i = 0; i < sARRAY; i++) {
            a[i]=i;
        }
    
        //sending brain scalar and array a.
        sum = brain(a, sARRAY, scalar);
        printf("sum = %f", sum);
    }
    There are many reasons for doing this... Most importantly it lets you change one thing (the #define) to resize an array. But also by passing in the size it allows you to re-use the same functions for arrays of differing size.

    Yes I changed the array names in the functions... to demonstrate that it is indeed pass by value... inside the printarr() function it's known as z and is really just a copy of a pointer to the array... not the array itself.

    For your question about prototypes... C compilers read the page top down, so if it encounters a call to a function it will either A) make assumptions about the function, B) warn you that it doesn't know the function or C) both. If functions are read before called, you don't need prototypes (which is why you see programs with main() last...) However; if a call to a function exists before the function itself it needs a prototype to tell the compiler what to expect.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with simple Factorial Estimation
    By Arthurdent in forum C Programming
    Replies: 7
    Last Post: 06-16-2011, 07:28 PM
  2. Probability estimation
    By Mario F. in forum General Discussions
    Replies: 3
    Last Post: 09-18-2009, 08:40 AM
  3. Replies: 6
    Last Post: 01-08-2008, 10:25 AM
  4. project help (mead,median,mode)
    By Pliskin_Vamp in forum C Programming
    Replies: 1
    Last Post: 04-09-2007, 05:08 PM
  5. area estimation of graph
    By hei in forum C Programming
    Replies: 3
    Last Post: 10-16-2001, 12:23 AM