Search code examples
pythonloopsfor-loopgnuplotequation

Gnuplot equation of state fitting loop


I am trying to make a script to fit 50 files of free energy vs volume using the Birch Murnaghan equation of state. I'm fitting for 3 parameters, emin, v0 and k0. I can't seem to get a loop to work which would loop over each file fitting it and then making 50 new files of the three fitting parameters.

   birch(x) = emin + 1.5*v0*k0/1602 * ( 0.75*(1+2*xsi)*(v0/x)**(4.0/3.0) \
-xsi/2*(v0/x)**2 - 3.0/2.0*(1+xsi)*(v0/x)**(2.0/3.0) + 0.5*(xsi+1.5) )
emin=-8
k0=2000
v0=10
xsi=0

do for [n=100:5000:100]{
   file = sprintf('free.%.f',n)
   fit birch(x) file via emin,v0,k0
   A = A.sprintf(%f,emin)
   B = B.sprintf(%f,v0)
   C = C.sprintf(%f,k0)
}

''' The data is saved in files going free.100 free.200 and so on till free.5000, does anybody know how I could do this I only really want to make a script so I don't have to manually fit all the data


Solution

  • (While I was coding @maij already posted an answer. I'll nevertheless post my example)

    You don't specify how the output files should look like. In order to write something to a file in gnuplot you can use set print <FILE>, check help set print. Check the following example:

    Code:

    ### store fitting parameters into file
    reset session
    
    myFile(n)  = sprintf("free.%d",n)
    myParamFile(n) = sprintf("free.%d.param",n)
    set key left
    
    # create some test data in files
    do for [i=100:600:100] {
        set print myFile(i)
            m = int(rand(0)*10)+0.1
            c = int(rand(0)*10)
            do for [j=1:20] {
                print sprintf("%g %g",j, m*j + 5*m*rand(0) + c)
            }
        set print
    }
    
    set fit brief nolog
    f(x) = a*x + b
    
    set multiplot layout 3,2
        do for [i=100:600:100] {
            fit f(x) myFile(i) via a,b
            set print myParamFile(i)
                print sprintf("a = %g",a)
                print sprintf("b = %g",b)
            set print
            plot myFile(i) w p pt 7 lc "blue" ti myFile(i), \
                 f(x) w l lc "red" 
        }
    unset multiplot
    ### end of code
    

    Result:

    enter image description here

    free.100.param

    a = 3.29395
    b = 8.13496
    

    free.200.param

    a = 1.99086
    b = 7.94427
    

    free.300.param

    a = 2.11392
    b = 12.3286
    

    free.400.param

    a = 3.97004
    b = 13.3108
    

    free.500.param

    a = 7.60895
    b = 15.8168
    

    free.600.param

    a = 0.0982883
    b = 8.2272