use ffi;
use libc::c_void;
use VectorF64;
pub struct MultiFitFSolverType {
s: *mut ffi::gsl_multifit_fsolver_type,
}
impl ffi::FFI<ffi::gsl_multifit_fsolver_type> for MultiFitFSolverType {
fn wrap(r: *mut ffi::gsl_multifit_fsolver_type) -> MultiFitFSolverType {
MultiFitFSolverType {
s: r,
}
}
fn soft_wrap(r: *mut ffi::gsl_multifit_fsolver_type) -> MultiFitFSolverType {
Self::wrap(r)
}
fn unwrap_shared(s: &MultiFitFSolverType) -> *const ffi::gsl_multifit_fsolver_type {
s.s as *const _
}
fn unwrap_unique(s: &mut MultiFitFSolverType) -> *mut ffi::gsl_multifit_fsolver_type {
s.s
}
}
pub struct MultiFitFSolver {
s: *mut ffi::gsl_multifit_fsolver,
}
impl MultiFitFSolver {
pub fn new(t: &MultiFitFSolverType, n: usize, p: usize) -> Option<MultiFitFSolver> {
let tmp = unsafe { ffi::gsl_multifit_fsolver_alloc(ffi::FFI::unwrap_shared(t), n, p) };
if tmp.is_null() {
None
} else {
Some(MultiFitFSolver {
s: tmp,
})
}
}
pub fn set(&mut self, f: &mut MultiFitFunction, x: &mut VectorF64) -> ::Value {
::Value::from(unsafe {
ffi::gsl_multifit_fsolver_set(self.s, f, ffi::FFI::unwrap_shared(x))
})
}
pub fn iterate(&mut self) -> ::Value {
::Value::from(unsafe { ffi::gsl_multifit_fsolver_iterate(self.s) })
}
pub fn name(&self) -> String {
unsafe {
let tmp = ffi::gsl_multifit_fsolver_name(self.s);
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(tmp).to_bytes()).to_string()
}
}
pub fn position(&self) -> VectorF64 {
unsafe { ffi::FFI::wrap(ffi::gsl_multifit_fsolver_position(self.s)) }
}
}
impl Drop for MultiFitFSolver {
fn drop(&mut self) {
unsafe { ffi::gsl_multifit_fsolver_free(self.s) };
self.s = ::std::ptr::null_mut();
}
}
impl ffi::FFI<ffi::gsl_multifit_fsolver> for MultiFitFSolver {
fn wrap(s: *mut ffi::gsl_multifit_fsolver) -> MultiFitFSolver {
MultiFitFSolver {
s: s
}
}
fn soft_wrap(s: *mut ffi::gsl_multifit_fsolver) -> MultiFitFSolver {
Self::wrap(s)
}
fn unwrap_shared(s: &MultiFitFSolver) -> *const ffi::gsl_multifit_fsolver {
s.s as *const _
}
fn unwrap_unique(s: &mut MultiFitFSolver) -> *mut ffi::gsl_multifit_fsolver {
s.s
}
}
#[repr(C)]
pub struct MultiFitFunction {
pub f: Option<extern "C" fn(x: *const ffi::gsl_vector, params: *mut c_void,
f: *mut ffi::gsl_vector) -> ::Value>,
pub n: usize,
pub p: usize,
pub params: *mut c_void,
}
pub struct MultiFitFdfSolver {
intern: *mut ffi::gsl_multifit_fdfsolver,
}
impl MultiFitFdfSolver {
pub fn new(_type: &MultiFitFdfSolverType, n: usize, p: usize) -> Option<MultiFitFdfSolver> {
let s = unsafe {
ffi::gsl_multifit_fdfsolver_alloc(
_type.intern as *const ffi::gsl_multifit_fdfsolver_type, n, p)
};
if s.is_null() {
None
} else {
Some(MultiFitFdfSolver {
intern: s,
})
}
}
pub fn set(&mut self, f: &mut MultiFitFunctionFdf, x: &::VectorF64) -> ::Value {
::Value::from(unsafe {
ffi::gsl_multifit_fdfsolver_set(self.intern, f.to_raw(), ffi::FFI::unwrap_shared(x))
})
}
pub fn x(&self) -> ::VectorF64 {
unsafe { ffi::FFI::soft_wrap((*self.intern).x) }
}
pub fn f(&self) -> ::VectorF64 {
unsafe { ffi::FFI::soft_wrap((*self.intern).f) }
}
pub fn J(&self) -> ::MatrixF64 {
unsafe { ffi::FFI::soft_wrap((*self.intern).J) }
}
pub fn dx(&self) -> ::VectorF64 {
unsafe { ffi::FFI::soft_wrap((*self.intern).dx) }
}
pub fn name(&self) -> String {
unsafe {
let tmp = ffi::gsl_multifit_fdfsolver_name(self.intern);
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(tmp).to_bytes()).to_string()
}
}
pub fn iterate(&mut self) -> ::Value {
::Value::from(unsafe { ffi::gsl_multifit_fdfsolver_iterate(self.intern) })
}
pub fn position(&self) -> ::VectorF64 {
unsafe { ffi::FFI::wrap(ffi::gsl_multifit_fdfsolver_position(self.intern)) }
}
#[allow(unused_assignments)]
pub fn driver(&mut self, max_iter: usize, epsabs: f64, epsrel: f64) -> ::Value {
let mut status = ::Value::Failure;
if !self.intern.is_null() {
let mut iter = 0usize;
loop {
status = self.iterate();
if status != ::Value::Success {
break
}
status = ::Value::from(unsafe { ffi::gsl_multifit_test_delta((*self.intern).dx,
(*self.intern).x,
epsabs,
epsrel) });
iter += 1;
if status != ::Value::Continue || iter >= max_iter {
break
}
}
}
status
}
}
impl Drop for MultiFitFdfSolver {
fn drop(&mut self) {
if !self.intern.is_null() {
unsafe { ffi::gsl_multifit_fdfsolver_free(self.intern); }
self.intern = ::std::ptr::null_mut();
}
}
}
#[allow(dead_code)]
pub struct MultiFitFdfSolverType {
intern: *mut ffi::gsl_multifit_fdfsolver_type,
}
impl MultiFitFdfSolverType {
pub fn lmder() -> MultiFitFdfSolverType {
MultiFitFdfSolverType {
intern: unsafe { ffi::gsl_multifit_fdfsolver_lmder },
}
}
pub fn lmsder() -> MultiFitFdfSolverType {
MultiFitFdfSolverType {
intern: unsafe { ffi::gsl_multifit_fdfsolver_lmsder },
}
}
}
pub struct MultiFitFunctionFdf {
pub f: Option<Box<Fn(::VectorF64, ::VectorF64) -> ::Value>>,
pub df: Option<Box<Fn(::VectorF64, ::MatrixF64) -> ::Value>>,
pub fdf: Option<Box<Fn(::VectorF64, ::VectorF64, ::MatrixF64) -> ::Value>>,
pub n: usize,
pub p: usize,
intern: ffi::gsl_multifit_function_fdf,
}
impl MultiFitFunctionFdf {
pub fn new(n: usize, p: usize) -> MultiFitFunctionFdf {
MultiFitFunctionFdf {
f: None,
df: None,
fdf: None,
n: n,
p: p,
intern: ffi::gsl_multifit_function_fdf {
f: Some(f),
df: Some(df),
fdf: Some(fdf),
n: n,
p: p,
params: ::std::ptr::null_mut(),
},
}
}
fn to_raw(&mut self) -> *mut ffi::gsl_multifit_function_fdf {
self.intern.n = self.n;
self.intern.p = self.p;
self.intern.params = self as *mut MultiFitFunctionFdf as *mut c_void;
&mut self.intern
}
}
extern "C" fn f(x: *mut ffi::gsl_vector, params: *mut c_void,
pf: *mut ffi::gsl_vector) -> libc::c_int {
unsafe {
let t = params as *mut MultiFitFunctionFdf;
if let Some(ref i_f) = (*t).f {
i_f(ffi::FFI::soft_wrap(x), ffi::FFI::soft_wrap(pf)).into()
} else {
::Value::Success.into()
}
}
}
extern "C" fn df(x: *mut ffi::gsl_vector, params: *mut c_void,
pdf: *mut ffi::gsl_matrix) -> libc::c_int {
unsafe {
let t = params as *mut MultiFitFunctionFdf;
if let Some(ref i_df) = (*t).df {
i_df(ffi::FFI::soft_wrap(x), ffi::FFI::soft_wrap(pdf)).into()
} else {
::Value::Success.into()
}
}
}
extern "C" fn fdf(x: *mut ffi::gsl_vector, params: *mut c_void, pf: *mut ffi::gsl_vector,
pdf: *mut ffi::gsl_matrix) -> libc::c_int {
unsafe {
let t = params as *mut MultiFitFunctionFdf;
if let Some(ref i_fdf) = (*t).fdf {
i_fdf(ffi::FFI::soft_wrap(x), ffi::FFI::soft_wrap(pf), ffi::FFI::soft_wrap(pdf)).into()
} else {
::Value::Success.into()
}
}
}