Method: CArray#fit_nonlinear

Defined in:
lib/carray-gsl/core.rb

#fit_nonlinear(xx, sigma, procf, procdf, parms, errs) ⇒ Object



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/carray-gsl/core.rb', line 270

def fit_nonlinear (xx, sigma, procf, procdf, parms, errs)
  n  = self.elements
  np = parms.size
  parms = GSL::Vector[*parms]
  gf = Proc.new { |a, x, y, sigma, f|
    f.ca[] = (procf.call(x, a.to_a) - y) / sigma
  }
  gdf = Proc.new { |a, x, y, sigma, jac| 
    cjac = jac.ca
    df   = procdf.call(x, a.to_a)
    a.size.times do |i|
      cjac[nil, i] = df[i] / sigma
    end
  }
  func   = GSL::MultiFit::Function_fdf.alloc(gf, gdf, np)
  func.set_data(xx, self, sigma)
  lmsder = GSL::MultiFit::FdfSolver::LMSDER
  solver = GSL::MultiFit::FdfSolver.alloc(lmsder, n, np)
  solver.set(func, parms)

  iter = 0
  begin
    iter += 1
    status = solver.iterate
    status = solver.test_delta(*errs)
  end while status == GSL::CONTINUE and iter < 500

  coef  = solver.position.to_a
  chi2  = GSL::pow_2(solver.f.dnrm2)
  dof   = n - np
  covar = solver.covar(0.0).ca
  err   = Array.new(np){|i| Math::sqrt(chi2/dof*covar[i,i]) }
  return coef, err, chi2, dof, covar
end