func ScaleVector(v *Vector, s float64) *Vector {
	return NewVector(v.x*s, v.y*s)
}
ScaleVector multiplies a vector with a float and returns
the new vector.
package numerics
import (
	"fmt"
	"math"
	"sort"
)
type Point struct {
	x float64
	y float64
}
func NewPoint(x, y float64) *Point {
	return &Point{x, y}
}
func (p Point) IsInf() bool {
	return math.IsInf(p.x, 0) || math.IsInf(p.y, 0)
}
func (p Point) IsNaN() bool {
	return math.IsNaN(p.x) || math.IsNaN(p.y)
}
func (p Point) X() float64 {
	return p.x
}
func (p Point) Y() float64 {
	return p.y
}
func (p Point) DistanceTo(op *Point) float64 {
	dx := p.x - op.x
	dy := p.y - op.y
	return math.Sqrt(dx*dx + dy*dy)
}
func (p Point) VectorTo(op *Point) *Vector {
	return NewVector(op.X()-p.x, op.Y()-p.y)
}
func (p Point) String() string {
	return fmt.Sprintf("(%f, %f)", p.x, p.y)
}
func MiddlePoint(a, b *Point) *Point {
	return NewPoint((a.x+b.x)/2, (a.y+b.y)/2)
}
func PointVector(a, b *Point) *Vector {
	return a.VectorTo(b)
}
type Points []*Point
func NewPoints(p ...*Point) Points {
	if len(p) > 0 {
		return p
	}
	return []*Point{}
}
func (ps Points) XAt(idx int) float64 {
	return ps[idx].X()
}
func (ps Points) YAt(idx int) float64 {
	return ps[idx].Y()
}
func (ps Points) XDifference(idxA, idxB int) float64 {
	return ps[idxA].X() - ps[idxB].X()
}
func (ps Points) YDifference(idxA, idxB int) float64 {
	return ps[idxA].Y() - ps[idxB].Y()
}
func (ps Points) XInRange(x float64) bool {
	minX := ps[0].X()
	maxX := ps[0].X()
	for _, p := range ps[1:] {
		if p.X() < minX {
			minX = p.X()
		}
		if p.X() > maxX {
			maxX = p.X()
		}
	}
	return minX <= x && x <= maxX
}
func (ps Points) SearchNextIndex(x float64) int {
	sf := func(i int) bool {
		return x < ps[i].X()
	}
	return sort.Search(len(ps), sf)
}
func (ps Points) Len() int {
	return len(ps)
}
func (ps Points) Less(i, j int) bool {
	switch {
	case ps[i].x < ps[j].x:
		return true
	case ps[i].x > ps[j].x:
		return false
	}
	switch {
	case ps[i].y < ps[j].y:
		return true
	case ps[i].y > ps[j].y:
		return false
	}
	return false
}
func (ps Points) Swap(i, j int) {
	ps[i], ps[j] = ps[j], ps[i]
}
func (ps Points) CubicSplineFunction() *CubicSplineFunction {
	return NewCubicSplineFunction(ps)
}
func (ps Points) LeastSquaresFunction() *LeastSquaresFunction {
	return NewLeastSquaresFunction(ps)
}
func (ps Points) String() string {
	pss := "{"
	for _, p := range ps {
		pss += p.String()
	}
	pss += "}"
	return pss
}
type Vector struct {
	x float64
	y float64
}
func NewVector(x, y float64) *Vector {
	return &Vector{x, y}
}
func (v Vector) X() float64 {
	return v.x
}
func (v Vector) Y() float64 {
	return v.y
}
func (v Vector) Len() float64 {
	return math.Sqrt(v.x*v.x + v.y*v.y)
}
func (v Vector) String() string {
	return fmt.Sprintf("<%f, %f>", v.x, v.y)
}
func AddVectors(a, b *Vector) *Vector {
	return NewVector(a.x+b.x, a.y+b.y)
}
func SubVectors(a, b *Vector) *Vector {
	return NewVector(a.x-b.x, a.y-b.y)
}