Search code examples
plotgnuplotnumerical-methodsderivative

Computing numerical derivative with gnuplot


I've been trying to compute numerically the derivative using gnuplot, using the scripts in this other discussion, even with the same data file. However I keep getting this error:

gnuplot> d(y) = ($0 == 0) ? (y1 = y, 1/0) : (y2 = y1, y1 = y, y1-y2)
                                ^
         "prova.g", line 7: ')' expected

I don't know what to do here. Any help?


Solution

  • Here is an example for numerical derivatives from my collection. Requires gnuplot >=5.0 and with the use of files instead of datablocks (and probably with some tweaking with gnuplot>=4.4.0).

    Script: (works with gnuplot>=5.0.0, Jan. 2015)

    ### numerical derivatives
    reset session
    
    # create some data
    MyFunction = "sin(x)/x"
    set table $Data
        set samples 150
        plot [-10:10] '+' u 1:(@MyFunction) w table
    unset table
    
    DerivX(colX) = (x0=x1,x1=column(colX),(x0+x1)/2.)
    DerivY(colY) = (y0=y1,y1=column(colY),(y1-y0)/(x1-x0))
    
    set table $Deriv1
        plot x1=y1=NaN $Data u (DerivX(1)):(DerivY(2)) w table
    unset table
    
    set table $Deriv2
        plot x1=y1=NaN $Deriv1 u (DerivX(1)):(DerivY(2)) w table
    unset table
    
    set table $Deriv3
        plot x1=y1=NaN $Deriv2 u (DerivX(1)):(DerivY(2)) w table
    unset table
    
    plot $Data   u 1:2 w l lc rgb "red"       ti MyFunction, \
         $Deriv1 u 1:2 w l lc rgb "web-green" ti "1st Derivative", \
         $Deriv2 u 1:2 w l lc rgb "blue"      ti "2nd Derivative", \
         $Deriv3 u 1:2 w l lc rgb "magenta"   ti "3rd Derivative"
    ### end of script
    

    Result:

    enter image description here

    Addition: (version for gnuplot 4.2.6, Sept. 2009)

    gnuplot 4.2.6 doesn't have datablocks and serial evaluation, but here is a cumbersome workaround without these features.

    1. for illustration, the script creates a data file SO68198576.dat (you already have your input file)

    2. plot the data file into another file TEMP1 skipping the first data line

    3. merge the files line by line into another file TEMP2 using the system command paste (either on Linux already on the system or on Windows you have to install, e.g. CoreUtils from GnuWin).

    4. now you can calculate dx and dy between two successive datapoints from column 1 and 4 and column 2 and 5, respectively.

    5. since the files have different length, the last line(s) should be skipped. This can be done by the system command head -n -2.

    That's how TEMP2 looks like:

    #Curve 0 of 1, 150 points   #Curve 0 of 1, 150 points
    #x y type   #x y type
    -10 -0.0544021  i   -9.86577 -0.0432646  i
    -9.86577 -0.0432646  i  -9.73154 -0.0310307  i
    -9.73154 -0.0310307  i  -9.59732 -0.0178886  i
    ...
    

    Script: (works with gnuplot 4.2.6, requires system commands paste and head)

    ### numerical derivative for gnuplot 4.2.6
    reset
    
    FILE = "SO68198576.dat"
    set table FILE
        set samples 150
        plot sin(x)/x
    unset table
    
    TEMP1 = FILE.'1'
    TEMP2 = FILE.'2'
    set table TEMP1
        plot FILE u 1:2 every ::1
    unset table
    
    system(sprintf('paste %s %s > %s', FILE, TEMP1, TEMP2))
    system(sprintf('head -n -2 %s > %s',TEMP2, TEMP1))
    
    x0(col) = (column(col)+column(col+3))/2.
    dx(col) = (column(col+3)-column(col))/2.
    dy(col) = (column(col+3)-column(col))/2.
    
    plot FILE u 1:2 w lp pt 7 title "Data", \
         TEMP1 u (x0(1)):(dy(2)/dx(1)) w lp pt 7 title "1st Derivative"
    ### end of script
    

    Result: (screenshot gnuplot 4.2.6)

    enter image description here