Esempio n. 1
0
func Brent(fn Diffable, x_lo, x_hi, epsAbs, epsRel float64) (float64, error) {
	cfn := unsafe.Pointer(&fn)
	result := C.double(0.0)
	err := C.brentSolve(cfn, C.double(x_lo), C.double(x_hi), C.double(epsAbs), C.double(epsRel), &result)
	if err != C.GSL_SUCCESS {
		err_str := C.GoString(C.gsl_strerror(err))
		return 0.0, fmt.Errorf("error in solve.Brent: %v\n", err_str)
	}
	return float64(result), nil
}
Esempio n. 2
0
// Perform a fit for p = len(`start`) parameters on `n` functions `F` (with
// derivatives `Df`). F(x, i) and Df(x, i) must be defined for 0 <= i < n. If
// x (a vector of dimension p) is outside the domain of F or Df, they should
// return an error.
func MultiDim(F FitErrF, Df FitErrDf, n int, start vec.Vector, epsAbs, epsRel float64) (vec.Vector, error) {
	fns := FitData{F, Df, n}
	cfns := unsafe.Pointer(&fns)
	p := C.size_t(len(start))
	csolution, cstart := C.gsl_vector_alloc(p), C.gsl_vector_alloc(p)
	vecToGSL(start, cstart)
	err := C.multiFit(cfns, cstart, C.double(epsAbs), C.double(epsRel), C.size_t(n), csolution)
	if err != C.GSL_SUCCESS {
		err_str := C.GoString(C.gsl_strerror(err))
		return nil, fmt.Errorf("error in fit.MultiDim: %v\n", err_str)
	}
	solution := vecFromGSL(csolution)
	C.gsl_vector_free(csolution)
	C.gsl_vector_free(cstart)
	return solution, nil
}
Esempio n. 3
0
// Numerical central derivative of fn(v) with respect to v_i within tolerance
// epsabs. h is the initial step size.
func Derivative(fn vec.FnDim0, v vec.Vector, i int, h, epsabs float64) (float64, error) {
	v_i_initial := v[i]
	iters, maxIters := 0, 100
	// results are bad for h too small or too large; we iterate in both directions
	hMin := h / 1e6
	hMax := h * 1e6
	hRising := true
	hInitial := h
	hOk := func(h float64) bool {
		if !hRising && h > hMin {
			return true
		} else if hRising && h < hMax {
			return true
		}
		return false
	}
	hAdvance := func(h float64) float64 {
		if hRising {
			if h*2.0 > hMax {
				hRising = false
				return hInitial / 2.0
			}
			return h * 2.0
		}
		return h / 2.0
	}
	fwi := unsafe.Pointer(&fnWithIndex{fn, v, i})
	x := C.double(v[i])
	result, abserr := C.double(0.0), C.double(math.MaxFloat64)
	for iters < maxIters && hOk(h) {
		err := C.centralDeriv(fwi, x, C.double(h), &result, &abserr)
		if err != C.GSL_SUCCESS {
			err_str := C.GoString(C.gsl_strerror(err))
			v[i] = v_i_initial
			return float64(result), fmt.Errorf("error in Derivative (GSL): %v\n", err_str)
		}
		if float64(abserr) < epsabs {
			v[i] = v_i_initial
			return float64(result), nil
		}
		iters++
		h = hAdvance(h)
	}
	// if we get here, !hOk(h) || iters == maxIters
	v[i] = v_i_initial
	return float64(result), fmt.Errorf("Derivative exceeded maximum iterations\n")
}
Esempio n. 4
0
// Multidimensional root-finder. Implemented by providing an interface to GSL
// implementation of Powell's Hybrid method (gsl_multiroot_fdfsolver_hybridsj).
// Callback passing through cgo follows the model at:
// http://stackoverflow.com/questions/6125683/call-go-functions-from-c/6147097#6147097
func MultiDim(fn DiffSystem, start vec.Vector, epsAbs, epsRel float64) (vec.Vector, error) {
	cfn := unsafe.Pointer(&fn)
	dim := C.size_t(fn.Dimension)
	csolution, cstart := C.gsl_vector_alloc(dim), C.gsl_vector_alloc(dim)
	VecToGSL(start, cstart)
	err := C.powellSolve(cfn, cstart, C.double(epsAbs), C.double(epsRel), csolution)
	if err != C.GSL_SUCCESS {
		err_str := C.GoString(C.gsl_strerror(err))
		return nil, fmt.Errorf("error in solve.MultiDim: %v\n", err_str)
	}
	solution := VecFromGSL(csolution)
	val, solveErr := fn.F(solution)
	if solveErr != nil || val.AbsMax() > epsAbs {
		return nil, fmt.Errorf("solution is inaccurate; absolute error = %v", val)
	}
	C.gsl_vector_free(csolution)
	C.gsl_vector_free(cstart)
	return solution, nil
}
Esempio n. 5
0
// Interface to gsl_integration_qags: "adaptive integration with [integrable]
// singularities". Integrate f from a to b and return the value of the
// integral and the absolute error.
func Qags(fn func(float64) float64, a, b, epsabs, epsrel float64) (result, absErr float64, err error) {
	cfn := unsafe.Pointer(&fn)
	C_result, C_absErr := C.double(0.0), C.double(0.0)
	// guard against panics during integration
	defer func() {
		if x := recover(); x != nil {
			result = 0.0
			absErr = 0.0
			err = x.(error)
		}
	}()
	// perform integration
	C_err := C.gslQags(cfn, C.double(a), C.double(b), C.double(epsabs), C.double(epsrel), &C_result, &C_absErr)
	if C_err != C.GSL_SUCCESS {
		err_str := C.GoString(C.gsl_strerror(C_err))
		return 0.0, 0.0, fmt.Errorf("error in Qags (GSL): %v\n", err_str)
	}
	result = float64(C_result)
	absErr = float64(C_absErr)
	return
}
Esempio n. 6
0
func (e *GSLError) Error() (what string) {
	str := C.gsl_strerror(e.code)
	what = C.GoString(str)
	return
}
Esempio n. 7
0
// const char * gsl_strerror (const GslError gsl_errno)
func (ge GslError) String() string {
	return C.GoString(C.gsl_strerror(C.int(ge)))
}
Esempio n. 8
0
File: error.go Progetto: h12w/go-gsl
func (e Error) Error() string {
	return C.GoString(C.gsl_strerror(C.int(e)))
}