func Qags(ff gslgo.F, ab gslgo.Interval, eps gslgo.Eps, w *WorkSpace) (gslgo.Result, error) { // Make a gsl_function var gf C.gsl_function data := gslgo.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 gslgo.Result{float64(y), float64(err)}, gslgo.Errno(ret) } return gslgo.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, gslgo.Errno(ret) } return sp, nil }
// 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), gslgo.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), gslgo.Errno(ret) } return float64(y), nil }
// Diff computes the derivative of ff, returns derivative and an error func Diff(dir DerivType, ff gslgo.F, x, h float64) (gslgo.Result, error) { var y, err C.double var ret C.int var gf C.gsl_function data := gslgo.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 gslgo.Result{float64(y), float64(err)}, gslgo.Errno(ret) } return gslgo.Result{float64(y), float64(err)}, nil }