x<-seq(1,20,1)
noise<-rnorm(20,0,5)
y<-2.38*x+8.29 + noise
plot(x,y)
Here's what the plot looks like:


func(x[]float64)float64 {
sumOfResiduals:=0.0
m :=x[0]//slope
b := x[1]//intercept
for _, p:= range points {
actualY:= p[1]
testY:= m*p[0] + b
sumOfResiduals += math.Abs(testY-actualY)
}
return sumOfResiduals
}
And here’s the full program, including the test dataset with random noise:
package main
import (
"log"
"math"
"gonum.org/v1/gonum/optimize"
)
func main() {
points:= [][2]float64{
{1, 9.801428},
{2, 17.762811},
{3, 20.222147},
{4, 18.435252},
{5, 12.570380},
{6, 20.979064},
{7, 24.313054},
{8, 21.307317},
{9, 26.555673},
{10, 27.772882},
{11, 41.202046},
{12, 44.854088},
{13, 40.916411},
{14, 49.013679},
{15, 37.969996},
{16, 49.735623},
{17, 48.259766},
{18, 50.009173},
{19, 61.297761},
{20, 58.333159},
}
problem := optimize.Problem{
Func:func(x []float64) float64 {
sumOfResiduals:= 0.0
m := x[0]//slope
b := x[1]//intercept
for _, p := range points {
actualY := p[1]
testY := m*p[0] + b
sumOfResiduals += math.Abs(testY-actualY)
}
return sumOfResiduals
},
}
result, err := optimize.Local(problem, []float64{1, 1}, nil, &optimize.NelderMead{})
if err!= nil {
log.Fatal(err)
}
log.Println("result:", result.X)
}
When you run that, you’ll get the following:
result: [2.5546852775670477 7.241390060062128]
Those two values represent the optimized slope and intercept parameters. If you plot the points and a line with the optimized parameters, you get this:

Pretty good fit! Let’s see how that compares to ordinary least squares regression, as computed by R.
>lm (y~x)
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept) x
8.402 2.491

The least squares result is in red. Pretty close too! Finally, let me add the true line in blue with the slope and intercept values I used to generate the test dataset, 2.38 and 8.29.

Note that in my example there’s only one place where Nelder-Mead is mentioned. That’s because the optimize package is abstracted enough that I can easily swap out the actual algorithm. Overall, I think the optimize package is very well organized and easy to work with, and I look forward to trying out more of the gonum collection!