Improvement over the last one I posted (now deleted, had no answers and was only cubics). Uses Horner's algorithm this time...
package main
import (
"fmt"
"math"
)
const ε float64 = 0.01
type polynomial struct {
coeffs []float64
x float64
}
// Both of these functions use Horner's algorithm
func evalPoly(p polynomial, n int) float64 {
var result float64 = 0
for i := 0; i < n; i++ {
result = result*p.x + p.coeffs[i]
}
return result
}
func evalPolyDeriv(p polynomial, n int) float64 {
var result float64 = 0
for i := 0; i < n-1; i++ {
result = result*p.x + float64(n-i-1)*p.coeffs[i]
}
return result
}
func f(p polynomial) float64 {
return evalPoly(p, len(p.coeffs)) / evalPolyDeriv(p, len(p.coeffs))
}
func solveNewton(p polynomial) float64 {
h := f(p)
for math.Abs(h) >= ε {
p.x -= h
h = f(p)
}
return p.x - h
}
func main() {
guess := float64(2)
coeffs := []float64{1, -2, 1, -4} // Can be of arbitary length
fmt.Println(solveNewton(polynomial{coeffs: coeffs, x: guess})) // 2.3146...
}