func Qags(ff gsl.F, ab gsl.Interval, eps gsl.Eps, w *WorkSpace) (gsl.Result, error) { // Make a gsl_function var gf C.gsl_function data := gsl.GSLFuncWrapper{ff} gf = C.mkintegCB(unsafe.Pointer(&data)) // Check to see if we have a positive/-negative infinity pinf := math.IsInf(ab.Hi, 1) ninf := math.IsInf(ab.Lo, -1) var ret C.int var y, err C.double // Switch on options switch { case pinf && ninf: ret = C.gsl_integration_qagi(&gf, C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) case pinf: ret = C.gsl_integration_qagiu(&gf, C.double(ab.Lo), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) case ninf: ret = C.gsl_integration_qagil(&gf, C.double(ab.Hi), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) default: ret = C.gsl_integration_qags(&gf, C.double(ab.Lo), C.double(ab.Hi), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) } if ret != 0 { return gsl.Result{float64(y), float64(err)}, gsl.Errno(ret) } return gsl.Result{float64(y), float64(err)}, nil }
// NewSpline creates a new Spline struct func New(s SplineType, xa, ya []float64) (*Spline, error) { // Check inputs nx := len(xa) ny := len(ya) if nx != ny { return nil, fmt.Errorf("Incompatible dimensions in NewSpline: x(%d) != y(%d)", nx, ny) } // Convert type of spline sptype, err := convertSplineType(s) if err != nil { return nil, err } // Create a new object sp := new(Spline) sp.sp = C.gsl_spline_alloc(sptype, C.size_t(nx)) sp.acc = C.gsl_interp_accel_alloc() // Initialize the spline object ret := C.gsl_spline_init(sp.sp, (*C.double)(&xa[0]), (*C.double)(&ya[0]), C.size_t(nx)) if ret != 0 { return nil, gsl.Errno(ret) } return sp, nil }
// SphBesselArr returns an array of Jl(x) where l runs from 0 to nmax inclusive // // Note that GSL has two implementations; we use the default one, not the one based // on Steed's algorithm. func SphBesselArr(lmax int, x float64) []float64 { arr := make([]float64, lmax+1) ret := C.gsl_sf_bessel_jl_array(C.int(lmax), C.double(x), (*C.double)(&arr[0])) if ret != 0 { panic(gsl.Errno(ret)) } return arr }
// BesselJArr returns an array of Jn(x) where n runs from nmin to nmax inclusive func BesselJArr(nmin, nmax int, x float64) []float64 { arr := make([]float64, nmax-nmin+1) ret := C.gsl_sf_bessel_Jn_array(C.int(nmin), C.int(nmax), C.double(x), (*C.double)(&arr[0])) if ret != 0 { panic(gsl.Errno(ret)) } return arr }
// Eval evaluates the spline at x. // If x is out of bounds, the code will panic. func (s *Spline) Eval(x float64) (float64, error) { var y C.double ret := C.gsl_spline_eval_e(s.sp, C.double(x), s.acc, &y) if ret != 0 { return float64(y), gsl.Errno(ret) } return float64(y), nil }
// Integrate evaluates the integral of the spline from lo to hi. // If this put it out of bounds, x // If x is out of bounds, the code will panic. func (s *Spline) Integrate(lo, hi float64) (float64, error) { var y C.double ret := C.gsl_spline_eval_integ_e(s.sp, C.double(lo), C.double(hi), s.acc, &y) if ret != 0 { return float64(y), gsl.Errno(ret) } return float64(y), nil }
// Diff computes the derivative of ff, returns derivative and an error func Diff(dir DerivType, ff gsl.F, x, h float64) (gsl.Result, error) { var y, err C.double var ret C.int var gf C.gsl_function data := gsl.GSLFuncWrapper{ff} gf = C.mkderivCB(unsafe.Pointer(&data)) switch dir { case Central: ret = C.gsl_deriv_central(&gf, C.double(x), C.double(h), &y, &err) case Forward: ret = C.gsl_deriv_forward(&gf, C.double(x), C.double(h), &y, &err) case Backward: ret = C.gsl_deriv_backward(&gf, C.double(x), C.double(h), &y, &err) default: panic(errors.New("Unknown direction")) } if ret != 0 { return gsl.Result{float64(y), float64(err)}, gsl.Errno(ret) } return gsl.Result{float64(y), float64(err)}, nil }