Hi everyone,
I'm trying to get use with the fitting procedures available with NEURON.
I've troubles with the fit_praxis function that i didn't managed to solve despite the documentation and the other topic posted by jennap.
Here is a simple code doing the fitting of 5 points with a sinusoidal function.
There is no problem with the function .fit which works perfectly. Troubles with fit_praxis bgin when you uncomment line 76!
Thank you for any piece of advice,
//////////////////////////////////////////////////////////////////////////
objref gg, dat, indep, vac, fitsine, carrier
gg = new Graph()
dat = new Vector(5) //Contains the Data to fit
dat.x[0] = 0.544
dat.x[1] = 0.9589
dat.x[2] = 0
dat.x[3] = -0.9589
dat.x[4] = -0.544
sta = -10 //Abciss starting point
sto = 10 //Abciss ending point
binW = (sto - sta) / (dat.size() -1) //Interval between 2 points
indep = new Vector(5) //
indep.indgen(sta,sto,binW) //
freq = 1 / ( 2 * PI)
func mysin() { // A generic sinusoid
return $2 * sin(2 * PI * (freq * $1 - $3/360.)) + $4 // It accepts 4 input arguments ($1, ..$4)..
} // $1 is the time (axis), $2 is the amplitude, $3 is the phase, $4 is the offset
////////////////////////FIT////////////////////////////////////////
print "fitting..."
vac = new Vector() //
vac.indgen(sta,sto,0.01) //
fitsine = new Vector(dat.size()) //The fitted function
carrier = new Vector(vac.size()) //The "true" sinusoid
MSE = 999 //Mean Square Error
Offset = 0.5
Amplitude = 2
Phase = 50
print MSE, Offset, Amplitude, Phase
while (MSE > 950) {
MSE = dat.fit(fitsine, "mysin", indep, &Amplitude, &Phase, &Offset)
print "process"
}
print MSE, Offset, Amplitude, Phase
i=0
while (i < vac.size()) {
carrier.x = mysin(vac.x, Amplitude, Phase, Offset)
i = i + 1
}
gg.size(sta, sto, -2, 2)
carrier.plot(gg, vac, 2,10)
fitsine.plot(gg, indep, 3,1)
/////////////////////////////PRAXIS/////////////////////////////////////////
print "praxis.."
objref vec
vec = new Vector(3) //Should contains the parameters to be fitted
vec.x[0]= 1 / ( 2 * PI)
vec.x[1]= 1
vec.x[2]= 0
print vec.x[0] , vec.x[1], vec.x[2]
func mysin2() {
return $&2[1] * sin(2 * PI * ($&2[0] * indep - $&2[2]/360.))
}
attr_praxis(50, 1000, 0)
//fit_praxis(3,"mysin2",&vec.x[0])
print MSE, vec.x[0] , vec.x[1], vec.x[2]
//////////////////////////////////////////////////////////////////////////////
gg.flush()
Fit praxis
OK!
The way to make it works is to correctly implement the error function:
This code works with the both fitting procedures
++
v
//////////////////////////////////////
objref gg, dat, indep, vac, fitsine, carrier, carrier2
gg = new Graph()
dat = new Vector(5) //Contains the Data to fit
dat.x[0] = 0.544
dat.x[1] = 0.9589
dat.x[2] = 0
dat.x[3] = -0.9589
dat.x[4] = -0.544
sta = -10 //Abciss starting point
sto = 10 //Abciss ending point
binW = (sto - sta) / (dat.size() -1) //Interval between 2 points
indep = new Vector(5) //
indep.indgen(sta,sto,binW) //
freq = 1 / ( 2 * PI)
func mysin() { // A generic sinusoid
return $2 * sin(2 * PI * (freq * $1 - $3/360.)) + $4 // It accepts 4 input arguments ($1, ..$4)..
} // $1 is the time (axis), $2 is the amplitude, $3 is the phase, $4 is the offset
////////////////////////FIT////////////////////////////////////////
print "fitting..."
vac = new Vector() //
vac.indgen(sta,sto,0.01) //
fitsine = new Vector(dat.size()) //The fitted function
carrier = new Vector(vac.size()) //The "true" sinusoid
carrier2 = new Vector(vac.size()) //The "true" sinusoid
MSE = 999 //Mean Square Error
Offset = 0.5
Amplitude = 2
Phase = 50
print MSE, Offset, Amplitude, Phase
while (MSE > 950) {
MSE = dat.fit(fitsine, "mysin", indep, &Amplitude, &Phase, &Offset)
print "process"
}
print MSE, Offset, Amplitude, Phase
i=0
while (i < vac.size()) {
carrier.x = mysin(vac.x, Amplitude, Phase, Offset)
i = i + 1
}
gg.size(sta, sto, -2, 2)
carrier.plot(gg, vac, 2,10)
fitsine.plot(gg, indep, 3,1)
/////////////////////////////PRAXIS/////////////////////////////////////////
print "praxis.."
objref vec
vec = new Vector(3) //Should contains the parameters to be fitted
vec.x[0]= 0
vec.x[1]= 0
print vec.x[0] , vec.x[1], vec.x[2]
func mysin2() { // A generic sinusoid
return $2 * sin(2 * PI * (freq * $1 - $3/360.)) // It accepts 4 input arguments ($1, ..$4)..
}
func err(){
a = 0
for(i=0;i<5;i=i+1){
y = (dat.x- $&2[0] * sin(2 * PI * (freq * indep.x - $&2[1]/360.)))
a = a + y * y
}
return sqrt(a)
}
attr_praxis(0.01, 1000, 0)
fit_praxis(2,"err",&vec.x[0])
print a, vec.x[0], vec.x[1]
i=0
while (i < vac.size()) {
carrier2.x = mysin2(vac.x, vec.x[0], vec.x[1])
i = i + 1
}
carrier2.plot(gg, vac, 4,10)
//////////////////////////////////////////////////////////////////////////////
gg.flush()
The way to make it works is to correctly implement the error function:
This code works with the both fitting procedures
++
v
//////////////////////////////////////
objref gg, dat, indep, vac, fitsine, carrier, carrier2
gg = new Graph()
dat = new Vector(5) //Contains the Data to fit
dat.x[0] = 0.544
dat.x[1] = 0.9589
dat.x[2] = 0
dat.x[3] = -0.9589
dat.x[4] = -0.544
sta = -10 //Abciss starting point
sto = 10 //Abciss ending point
binW = (sto - sta) / (dat.size() -1) //Interval between 2 points
indep = new Vector(5) //
indep.indgen(sta,sto,binW) //
freq = 1 / ( 2 * PI)
func mysin() { // A generic sinusoid
return $2 * sin(2 * PI * (freq * $1 - $3/360.)) + $4 // It accepts 4 input arguments ($1, ..$4)..
} // $1 is the time (axis), $2 is the amplitude, $3 is the phase, $4 is the offset
////////////////////////FIT////////////////////////////////////////
print "fitting..."
vac = new Vector() //
vac.indgen(sta,sto,0.01) //
fitsine = new Vector(dat.size()) //The fitted function
carrier = new Vector(vac.size()) //The "true" sinusoid
carrier2 = new Vector(vac.size()) //The "true" sinusoid
MSE = 999 //Mean Square Error
Offset = 0.5
Amplitude = 2
Phase = 50
print MSE, Offset, Amplitude, Phase
while (MSE > 950) {
MSE = dat.fit(fitsine, "mysin", indep, &Amplitude, &Phase, &Offset)
print "process"
}
print MSE, Offset, Amplitude, Phase
i=0
while (i < vac.size()) {
carrier.x = mysin(vac.x, Amplitude, Phase, Offset)
i = i + 1
}
gg.size(sta, sto, -2, 2)
carrier.plot(gg, vac, 2,10)
fitsine.plot(gg, indep, 3,1)
/////////////////////////////PRAXIS/////////////////////////////////////////
print "praxis.."
objref vec
vec = new Vector(3) //Should contains the parameters to be fitted
vec.x[0]= 0
vec.x[1]= 0
print vec.x[0] , vec.x[1], vec.x[2]
func mysin2() { // A generic sinusoid
return $2 * sin(2 * PI * (freq * $1 - $3/360.)) // It accepts 4 input arguments ($1, ..$4)..
}
func err(){
a = 0
for(i=0;i<5;i=i+1){
y = (dat.x- $&2[0] * sin(2 * PI * (freq * indep.x - $&2[1]/360.)))
a = a + y * y
}
return sqrt(a)
}
attr_praxis(0.01, 1000, 0)
fit_praxis(2,"err",&vec.x[0])
print a, vec.x[0], vec.x[1]
i=0
while (i < vac.size()) {
carrier2.x = mysin2(vac.x, vec.x[0], vec.x[1])
i = i + 1
}
carrier2.plot(gg, vac, 4,10)
//////////////////////////////////////////////////////////////////////////////
gg.flush()