예제 #1
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
}
예제 #2
0
// Return the value for vector c which best fits the linear model y = Xc.
// X is a matrix given by its row vectors: each row corresponds to a y value;
// columns within the row correspond to coefficients for parameters in c.
func Linear(y vec.Vector, X []vec.Vector) vec.Vector {
	n := C.size_t(len(y))    // number of observations
	p := C.size_t(len(X[0])) // number of parameters
	c, gslY := C.gsl_vector_alloc(p), C.gsl_vector_alloc(n)
	cov, gslX := C.gsl_matrix_alloc(p, p), C.gsl_matrix_alloc(n, p)
	vecToGSL(y, gslY)
	matrixToGSL(X, gslX)
	chisq := C.double(0)
	work := C.gsl_multifit_linear_alloc(n, p)
	C.gsl_multifit_linear(gslX, gslY, c, cov, &chisq, work)
	C.gsl_multifit_linear_free(work)
	result := vecFromGSL(c)
	C.gsl_matrix_free(gslX)
	C.gsl_matrix_free(cov)
	C.gsl_vector_free(gslY)
	C.gsl_vector_free(c)
	return result
}
예제 #3
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
}
예제 #4
0
//export fit_go_df
func fit_go_df(x C.const_gsl_vector, fn unsafe.Pointer, J *C.gsl_matrix) C.int {
	gofn := (*FitData)(fn)
	gx := vecFromGSL(x)
	for i := 0; i < gofn.N; i++ {
		val, err := gofn.Df(gx, i)
		if err != nil {
			// same assumption as fit_go_f
			return C.GSL_EDOM
		}
		gslval := C.gsl_vector_alloc(x.size)
		vecToGSL(val, gslval)
		C.gsl_matrix_set_row(J, C.size_t(i), gslval)
		C.gsl_vector_free(gslval)
	}
	return C.GSL_SUCCESS
}
예제 #5
0
// Return an ordered slice of the eigenvalues of sym, and a slice of the
// eigenvectors in the same order.
func (sym *SymmetricMatrix) Eigensystem() ([]float64, [][]float64) {
	originalSize := sym.length
	reduced, convert := sym.RemoveEmptyRows()
	size := C.size_t(reduced.length)
	eigenvalues := C.gsl_vector_alloc(size)
	eigenvectors := C.gsl_matrix_alloc(size, size)
	matrix := reduced.toMatrix()
	work := C.gsl_eigen_symmv_alloc(size)
	err := C.gsl_eigen_symmv(matrix, eigenvalues, eigenvectors, work)
	if err != 0 {
		// handle it
	}
	goEigenvalues := vectorToSlice(eigenvalues)
	goEigenvectors := matrixColumnsToSlices(eigenvectors)
	C.gsl_vector_free(eigenvalues)
	C.gsl_matrix_free(eigenvectors)
	C.gsl_matrix_free(matrix)
	C.gsl_eigen_symmv_free(work)
	retEigenvectors := InsertEmptyRows(goEigenvectors, convert, originalSize)
	return goEigenvalues, retEigenvectors
}