1

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?

Another User
  • 125
  • 3
  • 1
    Which version of gnuplot are you running? I can only reproduce this error message with gnuplot 4.0 which is about 17 years old. – theozh Jun 30 '21 at 17:18
  • At startup it says: Version 4.2 patchlevel 6 – Another User Jun 30 '21 at 17:20
  • This might be the reason. Can't you update to a newer version? Current version is 5.4 – theozh Jun 30 '21 at 17:21
  • This is on a remote server owned by my uni, unfortunately, I don't think I can do it without authorization (which I wouldn't know where to get). – Another User Jun 30 '21 at 17:22
  • Hmmm, gnuplot 4.2.6 is from 2009. So, your administrators are 12 years behind?! Let me check if there might be a way which such an old version. – theozh Jun 30 '21 at 17:35

1 Answers1

0

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

theozh
  • 22,244
  • 5
  • 28
  • 72
  • Works perfectly, just had to change the data. Quite ingenious! – Another User Jul 01 '21 at 09:28
  • @AnotherUser glad to hear :-). Why did you have to change the data? Well, in your question you didn't show data. In any case, maybe you ask your administrators to update gnuplot to a more recent version, a 12 year old version is a bit too old. – theozh Jul 01 '21 at 09:37
  • Yes my question was regarding actual data, not just an analytic function. I will definitely bring up the update the next time I speak with my professor – Another User Jul 01 '21 at 09:38
  • @AnotherUser sorry, of course you have to change the data. You don't want `sin(x)/x` but _your_ datafile. You can also easily change the columns as needed. – theozh Jul 01 '21 at 09:43
  • Yes, I figured as much, was easy enough. Thanks for the clarification! – Another User Jul 01 '21 at 09:45
  • @AnotherUser actually, you can get rid of this strange last point in the graph if you remove the last two lines of `temp2.dat` via `system(sprintf('head -n -2 %s > %s',TEMP2, TEMP1))` and then plot `TEMP1` instead of `TEMP2`. Maybe there are better ways. – theozh Jul 01 '21 at 10:04