Problems 6
  1. Theory:
    1. When the 'tabulate' function from the exercise exits, is the parameter 'a' changed in the scope of the caller?
    2. What will the following code print?
      double k=0; 
      void foo(double x){ printf( "k*x= %g\n", k*x); }
      
      int main(void) {
        k=1; foo(1);
        k=2; foo(1);
        k=3; foo(1);
      return 0;}
      
    3. Suppose you are using 'gcc' where one can define functions inside functions. What will the following code print?
      double k=0; 
      void foo(double x){ printf( "k*x= %g\n", k*x); }
      
      int main(void) {
        double k=0;
        void foo(double x){ printf( "k*x= %g\n", 500*k*x); }
        k=1; foo(1);
        k=2; foo(1);
        k=3; foo(1);
      return 0;}
      
    4. What does the line (from the exercise)
      double  k=*(double*)params;
      
      mean?
  2. Practice:
    1. Let's do some simple thing in a compicated way. Suppose you have to plot three functions, sin(x), sin(2x), sin(3x) on the same plot. Of course you can just run pyxplot and say
      plot sin(x),sin(2*x),sin(3*x)
      
      but that's not the way the real hackers do things. Instead build a makefile project that does the job along the following lines:
      1. In order to keep the function to plot—together with its parameter—introduce the structure
        struct function {double (*f)(double, void*); void* params;};
        
        The params are typed void* in order not to restrict the type of the parameters. If foo is of our type struct function the call to the function should then be done as
        double y = foo.f(x,foo.params);
        
        Here the absence of classes in C is mostly evident: the 'method' of the struct has no direct access to the field of the struct.

        Remark: this structure is flexible enough to hold a wide class of functions with some extra parameters, for example Asin(kx+δ), a+bx+cx2 etc. For instance, the function Asin(kx+δ) can be implemented as

        struct akd {double a, k, d;};
        double asinkx(double x, void* params){
          struct akd p = *(struct akd *)params;
          return p.a*sin(p.k*x+p.d);}

      2. Implement a function, say tabulate, that tabulates our struct function over a given interval with a given step:
        void tabulate(struct function *f, double a, double dx, double b){
          for(;a<b;a+=dx)printf( "%g\t%g\n", a, (*f).f(a,(*f).params) );
        }
        
        The function 'tabulate' has to be in a separate file, named 'tabulate.c' without quotes.
      3. The function to plot, sin(kx), can be represented in a form suitable to be a member of our struct function as
        double sinkx(double x, void* params){
          double  k=*(double*)params;
          return sin(k*x);
        }
        
      4. The tabulation process can now be something like
        struct function foo; double k=1,a=0,dx=0.1,b=2*M_PI+dx;
        foo.f=&sinkx;
        foo.params=(void*)&k;
        k=1; tabulate(&foo,a,dx,b); printf("\n");
        k=2; tabulate(&foo,a,dx,b); printf("\n");
        k=3; tabulate(&foo,a,dx,b); printf("\n");
        
        Let us say that this code is in the 'main' function in the file 'main.c'.
      5. The pyxplot script to plot the tabulated data can be something like
        set terminal pdf
        set output 'plot.pdf'
        set xlabel '$x$'
        set ylabel '$y$'
        plot 'plot.data' with lines
        
        Let us say the script is in the file 'plot.pyxplot'.
      6. The makefile to build the project could then be something like
        CFLAGS = -Wall
        LDLIBS = -lm
        obj = main.o tabulate.o
        all: plot.pdf
        plot.pdf: plot.pyxplot plot.data ; pyxplot $<
        plot.data: main ; ./main > $@
        main: $(obj)
        clean: ; $(RM) $(obj) main plot.data plot.pdf
        
        You can view the plot in the pdf-file (if you have a graphical session) with the command
        evince plot.pdf
        
        if you have installed 'evince' viewer, or with the command
        gv plot.pdf
        
        if you have installed 'gv' viewer, or with the command
        firefox plot.pdf
        
        if your have the firefox browser installed.