Thread: Parameter estimation Nelder Mead

  1. #76
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    OK OK! Extern! So many mistakes to remember!
    I have just been trying to avoid touching files I didnt make incase of buggering them up, thats why I left the globals that are in the neldermead.c file
    I'll get rid of the extern at the NelderMead function - but leave it in the protoype - because thats another file - an included header file, so it does need an extern right?

    I'll also read about a guard.
    Wow Boot Camp for crappy Coders!!!!

    Edit. Got rid of the externs in mat.c too. As they are functions being called from within the project, they do not need an extern (I think).

  2. #77
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Ahh I get guards!
    If you are calling a header file that another header file also calls, then inadvertently you are calling it twice, guards stop this happening. Lets see how to build it in...

  3. #78
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by a.mlw.walker View Post
    It should run for you like it does for me now
    I compiled those using this makefile:

    Code:
    cf=-g -Wall
    
    test: main.c neldermead.o mat.o
    	gcc $(cf) neldermead.o mat.o main.c -o test -lm
    
    neldermead.o: neldermead.c opt.h
    	gcc $(cf) -c neldermead.c 
    
    mat.o: mat.c opt.h
    	gcc $(cf) -c mat.c
    
    clean:
    	-rm *.o test
    I added this to the top of "opt.h" to eliminate some warnings about malloc() not having a prototype:

    Code:
    #include <stdlib.h>
    After that, it builds and runs (I don't know what output you want), with the following warnings:

    gcc -g -Wall -c neldermead.c
    neldermead.c:32: warning: ‘fprint_simplex’ defined but not used
    neldermead.c:41: warning: ‘fprint_points’ defined but not used
    neldermead.c:51: warning: ‘fprint_generated_points’ defined but not used
    gcc -g -Wall -c mat.c
    gcc -g -Wall neldermead.o mat.o main.c -o test -lm
    main.c: In function ‘main’:
    main.c:83: warning: too many arguments for format
    main.c:50: warning: unused variable ‘tol’
    main.c:50: warning: unused variable ‘left’

    The only significant one there is "too many arguments for format".

    Valgrind (a memory profiler) leaves you with 256 bytes in 10 blocks still reachable (these are pointers which were malloc'd but never free'd). These are allocated at:

    [file:line number]
    neldermead.c:71
    neldermead.c:73
    neldermead.c:74
    neldermead.c:75
    neldermead.c:65
    neldermead.c:69
    neldermead.c:67

    You should organize your files more conventionally -- then your (very copious) use of extern would be (mostly or completely) unnecessary, and it will be easier for others to get a handle on what you are doing. To do this, you would have:

    main.c
    nendermead.c
    nendermead.h <- contains prototypes for function definitions from nendermead.c (no extern required)
    mat.c
    mat.h <- prototypes from mat.c
    opt.h <- typedefs, macros, and defines common to mat.c and nendermead.c but no prototypes

    You'd then #include mat.h + opt.h in mat.c, nendermead.h + opt.h in nendermead.c, and all three .h in main.c. That should work (there may be a few functions that do end up needing extern somewhere, but not all of them) -- if not, you are not using your compiler/linker/make system/IDE properly (which you still haven't said what that is, and it might be helpful).
    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

  4. #79
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    and I added the lines:

    #ifndef _OPT_H_
    #define _OPT_H_

    to the opt.h file

  5. #80
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by a.mlw.walker View Post
    and I added the lines:

    #ifndef _OPT_H_
    #define _OPT_H_

    to the opt.h file
    That's fine, but if you want it to function as an "include guard" you would then put:

    Code:
    #endif
    at the bottom (meaning if the file has been included/read already, the whole thing will be skipped). Sometimes needed, sometimes not.
    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. #81
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by a.mlw.walker
    and I added the lines:

    #ifndef _OPT_H_
    #define _OPT_H_

    to the opt.h file
    "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use." As such, you might want to rename your header inclusion guards, e.g., AMW_OPT_H_.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #82
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Sorry missed MK's big post.
    added that guard in opt.h
    added
    #include <stdlib.h>
    to opt.h
    The "too many arguments for format" was not enough variables in a print statement got that.
    Commented out those two variables.
    mat.c I removed all 'extern' statements, they are functions that get called.
    My Neldermead.h has no extern statement at all:
    Code:
    #ifndef H_NELDER_MEAD_H
    #define H_NELDER_MEAD_H
    
    int nelder_mead(
    double (*f)(double*, int, void*),
    int n,
    double *minval,
    double *p,
    double h,
    double tol,
    int maxevals,
    void *params);
    #endif /* H_NELDER_MEAD_H */
    I dont have a mat.h? Where did you get that?
    Then I'll do those .h combos you said, and You can see if I have sorted my externs...

  8. #83
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by a.mlw.walker View Post
    and I added the lines:

    #ifndef _OPT_H_
    #define _OPT_H_

    to the opt.h file
    Good. Notice the example on the Wikipedia page didn't have the first underscore though. That's because identifiers with leading underscores are reserved for the implementation, i.e. OS, compiler, etc. You should just do:
    Code:
    #ifndef OPT_H
    #define OPT_H
    // all your typedefs, prototypes, etc
    #endif

  9. #84
    Bit Fiddler
    Join Date
    Sep 2009
    Posts
    79
    Just to mess this up further... I've got an question for the pros here.

    Seeing that function is declared as static... It still can be called from an other source (object) file, if we're messing around with pointers?

  10. #85
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by a.mlw.walker View Post
    I dont have a mat.h? Where did you get that?
    I know. My point was that the "normal" way to do this is to have a .h for each .c that is the source for a linked object (ie, does not have a main). That .h contains the prototypes for all the functions defined in the .c. There may or may not also be a .h for main.c, and there may be other .h's with types, etc common to several objects.
    This correspondence makes it easy to understand the structure of a project, and simplifies the development process.

    The simpler you can keep things, the more complex you can get (if that makes sense ).
    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. #86
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Fader_Berg View Post
    Just to mess this up further... I've got an question for the pros here.

    Seeing that function is declared as static... It still can be called from an other source (object) file, if we're messing around with pointers?
    Yes, provided that other file has a way of getting the address of the function. E.g.
    Code:
    // foo.h
    #ifndef foo_h
    #define foo_h
    extern void (*get_foo(void))(void);
    #endif
    
    // foo.c
    #include <stdio.h>
    static void foo(void)
    {
        printf("foo\n");
    }
    
    void (*get_foo(void))(void)
    {
        printf("getting pointer to function foo at %p\n", foo);
        return foo;
    }
    
    // main.c
    #include <stdio.h>
    #include "foo.h"
    
    int main(void)
    {
        void (*foop)(void);
    
        foop = get_foo();
        printf("got pointer to static function foo at %p\n", foop);
        (*foop)();
        return 0;
    }

  12. #87
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    ok, so I have everything except a mat.h, and opt.h now has guards. I have removed the externs I came across, and have got rid of all warnings, except one that is worried about
    incompatible implicit declaration of built-in function 'malloc'
    on the line
    Code:
    	simp = alloc(dbl *, nvar+1);
    .
    Would you like another look?

  13. #88
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by a.mlw.walker
    incompatible implicit declaration of built-in function 'malloc'
    Except that that line uses alloc, not malloc. I suppose alloc is a macro? If so, use the convention of naming macros fully capitalised, e.g., ALLOC. To actually fix this problem, you should #include <stdlib.h> appropriately.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #89
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Bingo. No warnings. However same old answers

  15. #90
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Guys, I might have found something. The matlab code has been modified due to someone writing in and saying they reckon they have a better method. The code is different in the matlab for the initial simplex:
    matlab:
    Code:
    % Continue setting up the initial simplex.
    % Following improvement suggested by L.Pfeffer at Stanford
    usual_delta = 0.05;             % 5 percent deltas for non-zero terms
    zero_term_delta = 0.00025;      % Even smaller delta for zero elements of x
    for j = 1:n
        y = xin;
        if y(j) ~= 0
            y(j) = (1 + usual_delta)*y(j);
        else
            y(j) = zero_term_delta;
        end
        v(:,j+1) = y;
        x(:) = y; f = funfcn(x,varargin{:});
        fv(1,j+1) = f;
    end
    C:
    Code:
    static void initial_simplex(dbl *xinit, dbl length)
    {
    	int	i, j;
    	dbl	a, d1, d2, *v;
    
    	a = nvar + 1;
    	d1 = (sqrt(a) + nvar - 1)/sqrt(2.00)/nvar;
    	d2 = (sqrt(a) - 1)/sqrt(2.00)/nvar;
    
    	v = simp[0];
    	for (j=0; j<nvar; j++) v[j] = 0.00;
    	for (i=1; i<=nvar; i++) {
    		v = simp[i];
    		for (j=0; j<nvar; j++) {
    			v[j] = d2;
    		}
    		v[i-1] = d1;
    	}
    
    	for (i=0; i<=nvar; i++) {
    		v = simp[i];
    		scalarvector(nvar, v, length, v);
    		vectoradd(nvar, v, xinit, v);
    	}
    }
    the matlab uses a 5% measurement in each direction, although I cant quite read what the C is doing.
    Everything else is then deterministic i think

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