Problems 6
  1. Theory:
    1. You can pass extra parameters to you functions through variables at the appropriate scope. With certain caveats: what will the following code print?

      void call(void f()){ f(); }
      double a=0; 
      void foo(){ printf( "a=%g\n", a); }
      int main() {
      	{a=1; call(foo);}
      	{a=2; call(foo);}
      	{double a=3; call(foo);}
      return 0;}
      
    2. In C-language "type conversion" (or "coersion" or "casting") is allowed with the explicit cast operator (type)variable. What does the following line mean?

      double  a = *(double*)params;
      
    3. When the 'tabulate' function from the example below exits, is the parameter 'a' changed in the scope of the caller?

    4. What is the gnuplot command to plot, say, sine and cosine functions with the same line-type?

    5. What is the gnuplot command to plot experimental data with error-bars from the file, say, "exp.dat"? How should the data points in "exp.dat" be organised? Hint: help errorbars.

    6. In gnuplot, how do you specify the ranges on the x- and y-axis?

    7. Suppose you have a data-file with several columns of data. With gnuplot, how do you plot, say, third column vs. second?

    8. In the datafile for gnuplot, how do you separate data intended for different lines on the plot?

    9. In gnuplot, how do you change the size of the plot?

    10. Suppose you have a data-file with (x,y) data organised in two columns. How do you plot, say, y2 vs. x? Hint: help plot using.

  2. Practice. Passing parameters to the argument-function (like in the 'foo' function in the example above) through the variables in the appropriate scope is not always the thing. Often you want to keep and pass the parameters to argument-function together with the function itself in a structure. Here is the exercise.
    1. Implement a function called tabulate that tabulates a double function of double argument (with some extra paramteters, which are not known to tabulate) over a given interval with a given step. The function to tabulate together with its parameters must be kept in the following structure,

      struct my_function {double (*f)(double, void*); void* params;};
      
      The params are typed void* in order not to restrict the number and types of the parameters. If foo is of our type struct function the call to the function is 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 members of the struct.

      Hint:

      void tabulate(struct my_function *f, double a, double b, double dx){
        for(; x<b; x+=dx) printf( "%g\t%g\n", a, (*f).f(a,(*f).params) );
      }
      
    2. Tabulate the three functions, sin(x), sin(2x), sin(3x) using your tabulator and plot them. Represent the function to plot, sin(kx), as
      double sinkx(double x, void* params){
        double  k=*(double*)params;
        return sin(k*x);
      }
      

      Hints:

        Tabulation:
      1. struct my_function foo; double k=1,x1=0,dx=0.1,x2=2*M_PI+dx;
        foo.f=&sinkx;
        foo.params=(void*)&k;
        k=1; tabulate(&foo,x1,x2,dx); printf("\n");
        k=2; tabulate(&foo,x1,x2,dx); printf("\n");
        k=3; tabulate(&foo,x1,x2,dx); printf("\n");
        
      2. The gnuplot script
        set terminal pdf
        set output 'plot.pdf'
        set xlabel 'x'
        set ylabel 'y'
        plot 'data.out' with lines
        
    3. Tabulate and plot several parabolas, a+bx+cx2, with different coefficients 'a', 'b', and 'c'.

      Hints:

      1. Function:
        struct abc {double a,b,c;};
        double parabola(double x, void* params){
        	struct abc p = *(struct abc *)params;
        	return p.a + p.b*x + p.c*x*x;
        }
        
      2. Tabulation:
        struct my_function foo;
        struct abc p;
        double x1=0,x2=5,dx=0.1;
        foo.f=&sinkx;
        foo.params=(void*)&p;
        p.a=1;p.b=0;p.c=0; tabulate(&foo,x1,x2,dx); printf("\n");
        p.a=0;p.b=1;p.c=0; tabulate(&foo,x1,x2,dx); printf("\n");
        p.a=0;p.b=0;p.c=1; tabulate(&foo,x1,x2,dx); printf("\n");
        
    4. 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.gp data.out ; gnuplot $<
      data.out : main             ; ./main > $@
      main     : $(obj)
      clean    :                  ; $(RM) $(obj) main data.out 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.