0
votes

I have a data file 'file.dat'. Because it's short, I'll say it contains the following data

x     y1(x)      y2(x)
0     -41.2462   -41.1297
0.1   -42.6114   -39.7339
0.2   -43.7644   -38.2653
0.3   -45.0846   -36.8728
0.4   -46.2912   -35.4905
0.5   -47.3873   -34.1428
0.6   -48.3437   -32.8365

The functions y1(x) and y2(x) are supposed to be quadratic functions of the form

y1(x) = a - b*x + c*x^2,
y2(x) = a + b*x + c*x^2.

The only difference between the two is that the linear term b is inverted in the second equation (essentially they're a parabola and it's reflection across the y axis).

I'm trying to do a multi-branch fit. To make it easier, the variable a is a known constant, it's supposed to represent the point where they intersect at x=0. Due to some small error, they don't quite match up so I'm taking a to be defined as

a =  (y1(0) + y2(0))/2 = (-41.2462 - 41.1297)/2 = -41.1879.

So I've defined my gnuplot functions as

y1(x) = -41.1879 - b*x + c*x**2
y2(x) = -41.1879 + b*x + c*x**2

For the fit function, I've tried

f(x,y) = (y==0) ? y1(x):y2(x)
fit f(x,y) 'file.dat' using 1:2:3 via b, c

This gave me the values of

b = 14.8708
c = -1.57747

which yields this plot of file.dat.

The upper branch of the fit looks pretty close, but the lower branch dips way below at higher values of x. I'm hoping to find values of b and c that closely approximate both y1(x) and y2(x) simultaneously. I can eyeball it myself, but I've got 800 such similar files to work through, and I'm hoping to automate this process with a c++ script later.

I think I'm missing some important step, or have gotten some syntax wrong somewhere. Can anyone please help?

1
I don't think you can do a multi-branch fit if there are multiple data points in the same line in your data file. Note that the examples in help fit multiuse either the dataline number or the datafile index to distinguish between the branches; with your current file format you would have to distinguish them by the column number (and consider each line twice!) which I don't think is possible. You might have to change the format of your data file. - user8153

1 Answers

0
votes

You have to reformat your data file so that each line contains only a single data point. For example, if you write it like

# y1 dataset
0     -41.2462
0.1   -42.6114
0.2   -43.7644
0.3   -45.0846
0.4   -46.2912
0.5   -47.3873
0.6   -48.3437

# y2 dataset (separated by a single blank line)
0     -41.1297
0.1   -39.7339
0.2   -38.2653
0.3   -36.8728
0.4   -35.4905
0.5   -34.1428
0.6   -32.8365

then you can use the following gnuplot script:

set key left
a = -41.1879
y1(x) = a - b*x + c*x**2
y2(x) = a + b*x + c*x**2

f(x,y) = (y == 0 ? y1(x) : y2(x))
fit f(x,y) "file.dat" u 1:-1:2 via b,c

plot y1(x), y2(x), "file.dat" u 1:2 w p

It uses the pseudocolumn -1 to separate the two data sets in the fit command.

enter image description here