help-gsl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-gsl] Non-linear fitting and complex data


From: Francesco Abbate
Subject: Re: [Help-gsl] Non-linear fitting and complex data
Date: Fri, 29 Jan 2010 09:56:24 +0100

2010/1/28 Saurav Pathak <address@hidden>

> Hi,
>
> I am trying to fit real parameters using a complex function.  That is, the
> GSL example:
> (
> http://www.gnu.org/software/gsl/manual/html_node/Example-programs-for-Nonlinear-Least_002dSquares-Fitting.html
> )
>
> int expb_f (const gsl_vector * x, void *data,            gsl_vector * f)
>
>
> f in my case is complex.  This means, my Jacobian too is complex.
> It is not clear to me from the example how I may specify this.   Could
> someone please help?
>

Hi,

GSL does not have direct support for non-linear fit of complex data. You can
still fit your data by working on the real and imaginary part. If the
fitting parameters are real numbers this is quite is to arrange, tipically
you have to pack the data in a gsl_vector by alternating the real and
imaginary part. The Jacobian will be splitted with the same logic. I can
give you more details if it can helps.

Otherwise, if you want to fit complex data of complex parameters the affair
will get more complicated because some components of the jacobian will be
related by the cauchy-riemann equations and you need to take ths into
account. I strongly advise in this case you use only real parameters because
otherwise it gets too much complicated.

If you are interested my program, gsl shell :

http://www.nongnu.org/gsl-shell/index.html

does have direct support for non linear fit of complex data with real
parameters. In the download directory you can find the latest release
gsl-shell-0.9.6-2 with the windows binary. Here a working example for fit of
complex data:

------------------
n = 50
p0 = vector {0.55, -4, 16, 0.23}
function fmodel(x, t)
   return x[1] * exp((x[2] + 1i*x[3]) * t + 1i * x[4])
end

r = rng() -- random number generator
y = cnew(n, 1, |k,j| fmodel(p0, (k-1)/n) + 0.01 * rnd.gaussian(r))

function cexpf(x, f, J)
   for k=1, n do
      local t, y = (k-1)/n, y[k]
      if f then f:set(k, 1, fmodel(x,t) - y) end
      if J then
 local e = exp((x[2] + 1i*x[3]) * t + 1i * x[4])
 J:set(k, 1, e)
 J:set(k, 2, t * x[1] * e)
 J:set(k, 3, 1i * t * x[1] * e)
 J:set(k, 4, 1i * x[1] * e)
      end
   end
end

function print_state(s)
      print ("x: ", s.x:row_print())
      print ("chi square: ", cmul(h(s.f), s.f)[1])
end

s = csolver {fdf= cexpf, n= n, p= 4, x0= vector {2.1, -2.8, 18, 0}}
repeat
      print_state (s)
      local status = s:iterate()
until status ~= 'continue'

print_state (s)
------------------------

You can also plot the results with the following commands:
------------------
pl = plot()
lr = path(0, real(y[1])) -- the data at t=0
lf = path(0, real(fmodel(p0, 0))) -- the model at t = 0
for k=1, y:dims() do
   lr:line_to((k-1)/n, real(y[k]))
   lf:line_to((k-1)/n, real(fmodel(p0, (k-1)/n)))
end

pl:add(lr, 'black', {{'stroke'}, {'marker'}})
pl:add_line(lf)
pl:show()
------------------
Best regards,
Francesco


reply via email to

[Prev in Thread] Current Thread [Next in Thread]