It seems individual array values do not work the same way in gnuplot as normal variables.
I have tried the following code given below.
# Following code doesn't work.
reset
# Parameters and fitting curve
n = 3
array p[n]
p[1] = 1.3 ; p[2] = 0.2 ; p[3] = 0.7
f(x) = p[1] * sin( p[2] + p[3] * x )
set fit
fit f(x) 'datafile.txt' using 1:2 via p[1], p[2], p[3]
unset fit
I get the following error: line 11: unknown type in real()
Note that if I change the arrays p[1], p[2], p[3]
, to a, b, c
the code works.
# Following works.
reset
a = 1.3 ; b = 0.2 ; c = 0.7
f(x) = a * sin( b + c * x )
set fit
fit f(x) 'datafile.txt' using 1:2 via a, b, c
unset fit
Partial data is given below (should be saved as 'datafile.txt') for completeness:
# x y
0 0.0222457
0.1 0.113168
0.2 0.252268
0.3 0.378091
0.4 0.397219
0.5 0.577536
0.6 0.621418
0.7 0.695817
0.8 0.741057
0.9 0.849566
1 0.864276
So my question is:
As @Karl mentioned in the comments, you would have to assign your variables and arrays back and forth.
The following solution seems to work in an automated way, but I'm not sure whether this is really a simplification.
Maybe it makes life a bit easier if you want to change from p
to q
, or from 3 variables to 7 variables.
It uses a few not so obvious "tricks", check help arrays
, help macros
, help evaluate
, help keyentry
, help sum
, help sprintf
, ...
Code:
### workaround for fitting using array values
reset session
$Data <<EOD
# x y
0 0.0222457
0.1 0.113168
0.2 0.252268
0.3 0.378091
0.4 0.397219
0.5 0.577536
0.6 0.621418
0.7 0.695817
0.8 0.741057
0.9 0.849566
1 0.864276
EOD
# parameters and fitting curve
N = 3
array p[N]
p[1] = 1.3 ; p[2] = 0.2 ; p[3] = 0.7
myVar = 'p' # define your variable
myColX = 1
myColY = 2
f(x) = p1 * sin( p2 + p3 * x ) # fitting function, defined with p1, p2, p3, ..., pN
#=======
# from here on "everything" goes automatic with variables and arrays
print "Initial array values: ", @myVar
# defining procedures for assigning variables and/arrays back and forth
myArrToVar(var) = sprintf("do for [i=1:|%s|] { eval(sprintf('%s%s = %s[%s]',i,i)) }",var,var,'%d',var,'%d')
myVarToArr(var) = sprintf("do for [i=1:|%s|] { eval(sprintf('%s[%s] = %s%s',i,i)) }",var,var,'%d',var,'%d')
# values from array --> variables
ArrToVar = myArrToVar(myVar)
@ArrToVar
# create the via, e.g p1,p2,p3,...
myViaStr(var) = (_tmp = '', (sum[_i=1:N] (_tmp = _tmp.sprintf('%s%d%s',var,_i,_i==N?'':', '),1)), _tmp)
viaStr = myViaStr(myVar)
# actual fitting
set fit quiet nolog
fit f(x) $Data using myColX:myColY via @viaStr
# values from variables --> array
VarToArr = myVarToArr(myVar)
@VarToArr
print "Final array values: ", @myVar
set key top left
plot $Data u myColX:myColY w p pt 7 ti "Data", \
f(x) w l lc "red", \
for [i=1:N] keyentry ti sprintf('%s[%d]=%.4f',myVar,i,@myVar[i])
### end of code
Result:
Initial array values: [1.3,0.2,0.7]
Final array values: [0.9215500294371,0.0231339564404058,1.20450770853891]