nox.im · All Posts · All in Go

Matrix and Vector Arithmetic With Gonum

Every once in a while we come across engineering problems that require matrix and vector calculations. While we can utilize R for experiments and it is awesome at that, for my taste, it’s simply not suitable for anything that runs under performance and memory constraints in production. If you’re familiar with R or Numpy, you dealt with a variety of data types. Since Go is statically typed, Gonum/mat provides implementations of float64 for its linear algebra operations. Go bridges the benefits of two worlds, the fast edit-compile-run cycles from interpreted languages and compile time checks as well as runtime efficiency of compiled languages.

Create a vector with mat.NewVecDense():

e := mat.NewVecDense(2, []float64{
        1, 1,
})

Note that GoNum treats vectors as a column. To use a vector as a row, you can transpose it with e.T().

e = 
    ⎡1⎤
    ⎣1⎦

We can print vectors and matrices as above with a small helper function:

func Print(m mat.Matrix, name string) {
	spacer := "    "
	r := mat.Formatted(m, mat.Prefix(spacer), mat.Squeeze())
	fmt.Printf("%s = \n%s%v\n\n", name, spacer, r)
}

Create a matrix with math.NewDense():

a := mat.NewDense(3, 2, []float64{
        1, 0,
        0, 1,
        0, 1,
})
a = 
    ⎡1  0⎤
    ⎢0  1⎥
    ⎣0  1⎦

Gonum operations usually don’t return values and operates on a receiver instead, which can be in-place to allow large matrices to execute without overhead in memory. For example:

// matrix A x vector e with the result being written into matrix A
a.MulVec(a, e)

But we can also allocate a new vector for the result we’re expecting. Note that we have to match the dimensions.

r := mat.NewVecDense(3, make([]float64, 3))
r.MulVec(a, e)

If dimensions mismatch, you will see the mat.ErrShape error.

ErrShape               = Error{"mat: dimension mismatch"}

When dimensions work, you can print the result:

r = 
    ⎡1⎤
    ⎢1⎥
    ⎣1⎦

The Hadamard product, or element wise multiplication of two equal sized Matrices can be achieved with:

r.MulElem(a, b)

more to follow soon, I’ll extend this with time…


Published on Monday, Mar 28, 2022. Last modified on Tuesday, Apr 5, 2022.
Go back

If you’d like to support me, follow me on Twitter or buy me a coffee. Use Bitcoin
BTC address: bc1q6zjzekdjhp44aws36hdavzc5hhf9p9xnx9j7cv