本文主要介绍 Gonum 科学计算包中 floats 模块。

sliceVectorDenseDenseCDenseBandDenseVectorDenseDense

slice 切片

slice
// src/runtime/slice.go
type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

创建

slice
a := []float64{0, 1, 2} // 方法 1

b := make([]float64, 3} // 方法 2
[0, 1, 2][0, 0, 0]
appendslice
a := make([]float64, 3)
a = append(a, 3)

上述代码首先初始化了一个长度为 3 的切片,然后在其末尾添加了浮点数 3.

slice在结构体中的应用

slice
// Vertex holds vertex data
type Vert struct {
    ID   int       // identifier
    Nset int       // vert set identifier
    X    []float64 // coordinates
}
VertXXVertX
v := new(Vert)

v.X = make([]float64, 3) // or 
v.X = []float64{0, 1, 2}

fmt.Println(v.X[0]) // 需要事先定义 X

floats 模块

slice[]float64

常用功能函数

Add 函数和 AddTo 函数

AddAddTo
//Add adds, element-wise, the elements of s and dst, and stores the result in dst.
// It panics if the argument lengths do not match.
func Add(dst, s []float64)

// AddTo adds, element-wise, the elements of s and t and
// stores the result in dst.
// It panics if the argument lengths do not match.
func AddTo(dst, s, t []float64) []float64

两者的主要区别为:

AddslicesliceAddTosliceslice
AddTo
package main

import (
    "fmt"
    "gonum.org/v1/gonum/floats"
)

func main() {
    // If one wants to store the result in a
    // new container, just make a new slice
    s1 := []float64{1, 2, 3, 4}
    s2 := []float64{5, 6, 7, 8}
    s3 := []float64{1, 1, 1, 1}
    dst := make([]float64, len(s1))

    floats.AddTo(dst, s1, s2)
    floats.Add(dst, s3)

    fmt.Println("dst =", dst)
    fmt.Println("s1 =", s1)
    fmt.Println("s2 =", s2)
    fmt.Println("s3 =", s3)

}

/* 计算结果
dst = [7 9 11 13]
s1 = [1 2 3 4]
s2 = [5 6 7 8]
s3 = [1 1 1 1]
*/

Dot 函数

Dot
// Dot computes the dot product of s1 and s2, i.e. sum_{i = 1}^N s1[i]*s2[i]. It panics if the argument lengths do not match.
func Dot(s1, s2 []float64) float64
Dot
package main

import (
    "fmt"
    "gonum.org/v1/gonum/floats"
)

func main() {
    s1 := []float64{0, 1, 2, 4}
    s2 := []float64{0, 2, 3, 6}

    s := floats.Dot(s1, s2)
    fmt.Println("s=", s)
}

// s = 32
VectorDense
package main

import (
    "fmt"
    "gonum.org/v1/gonum/floats"
    "gonum.org/v1/gonum/mat"
)

func main() {
    s1 := []float64{0, 1, 2, 4}
    s2 := []float64{0, 2, 3, 6}
    s := floats.Dot(s1, s2)

    vs1 := mat.NewVecDense(4, s1)
    vs2 := mat.NewVecDense(4, s2)
    vs := mat.Dot(vs1, vs2)

    fmt.Println("s=", s)
    fmt.Println("vs=", vs)
}

Max函数和Min 函数

MaxMinslice
// Max returns the maximum value in the input slice. If the slice is empty, Max will panic.
func Max(s []float64) float64

// Min returns the minimum value in the input slice. It panics if s is zero length.
func Min(s []float64) float64

结尾彩蛋:numpy 中 linspace 函数的等效替代

gonum 科学计算包中的 floats 模块针对 Go 语言内置的切片提供了大量的科学运算功能,在深入学习 gonum 科学计算的过程中,有必要熟练的掌握 floats 模块。

spanlinspace
package main

import (
    "fmt"
    "gonum.org/v1/gonum/floats"
)

func Linspace(n int, l, r float64) []float64{
    s := make([]float64, n)
    dst := floats.Span(s, l, r)

    return dst
}

func main() {
    dst := Linspace(10, 0, 1)
    fmt.Println("dst = ", dst)
}

/* 计算结果
dst =  [0 0.1111111111111111 0.2222222222222222 0.3333333333333333 0.4444444444444444 0.5555555555555556 0.6666666666666666 0.7777777777777777 0.8888888888888888 1]
*/
span
func Span(dst []float64, l, u float64) []float64

Span returns a set of N equally spaced points between l and u, where N is equal to the length of the destination. The first element of the destination is l, the final element of the destination is u. It panics if the length of dst is less than 2.