Fork me on GitHub

Science in Go,
all the way down.

go-scikit is the umbrella over 20 organisations that together cover what a Python notebook reaches for in NumPy, SciPy, pandas and matplotlib: arrays, FFTs, numerical methods, statistics, labelled tables, figures and notebooks, and, on the way to parity with MATLAB and Mathematica, sparse matrices, interpolation, signal processing and arbitrary precision. Pure Go, CGO=0, and each library measured against its reference, with the documents that say where it is slower or less accurate. A notebook's cells can be Go or Ruby, one cell reading what the other computed.

20 organisationsGo and Ruby cellsCGO=0 everywhereBSD-3-Clause
first.md
# A first notebook

```go
import (
	"github.com/go-ndarray/ndarray/random"
	"github.com/go-statistics/stats"
)
```

A thousand draws from seed 42: the
numbers NumPy's `default_rng(42)` gives.

```go
rng := random.DefaultRNG(42)
x, _ := stats.Normal{Loc: 10, Scale: 2}.Rvs(rng, 1000)
```

```go
stats.Percentiles(x, []float64{25, 50, 75}, nil)
```

The same draws in Ruby, through
the go-scikit bindings.

```ruby
fit = Stats::Normal.fit(x)
format("loc %.4f, scale %.4f", fit.loc, fit.scale)
```

$ notebook run first.md
── cell 0 (line 4)
── cell 1 (line 14)
── cell 2 (line 19)
   [8.607374170843807 10.012355742798341 11.179773490450081]
── cell 3 (line 26)
   "loc 9.9422, scale 1.9774"
20 organisations β€” one stack, each with its own site and documentation
How the pieces fit

Arrays at the bottom, notebooks on top.

go-ndarray's arrays are what the libraries above take and return, and its generator is where their random numbers come from; its fft package runs on go-fft. go-statistics takes its special functions and optimisers from go-numerics, go-dataframe's numeric columns are go-ndarray arrays and its dfplot draws with go-plot, and a go-notebook cell can use all of them.

go-notebook logo go-notebook
compiled, reactive notebooks
go-numerics logo go-numerics
optimize, integrate, special
go-statistics logo go-statistics
distributions, statistics, tests
go-dataframe logo go-dataframe
labelled tables
go-plot logo go-plot
figures, SVG and PNG
go-bignum logo go-bignum
arbitrary precision, oracle harness
go-sparse logo go-sparse
scipy.sparse, iterative solvers
go-approx logo go-approx
interpolation, splines, polynomials
go-dsp logo go-dsp
scipy.signal
go-symbolic logo go-symbolic
computer algebra
go-mlkit logo go-mlkit
machine learning
go-autodiff logo go-autodiff
automatic differentiation
go-geometry logo go-geometry
computational geometry
go-fem logo go-fem
finite elements, PDEs
go-graphalgo logo go-graphalgo
graph algorithms
go-control logo go-control
control systems, DAEs
go-units logo go-units
units, physical constants
go-ndarray logo go-ndarray
arrays, numpy.linalg, numpy.random
go-fft logo go-fft
numpy.fft, scipy.fft
go-sciio logo go-sciio
scientific file formats
The organisations

20 organisations, one stack.

Each organisation has its own landing, documentation and release cycle; each card gives its release status. The libraries are in the organisations; this page only points at them. The organisations still planned already have their site and documentation: what they will cover, the references they will be measured against and their place in the plan.

go-ndarray logo

go-ndarray

ndarray v0.18.0

N-dimensional arrays in 13 dtypes with NumPy 2 promotion, broadcasting, strided views and reductions, multicore and SIMD. Package linalg is numpy.linalg, fft is numpy.fft, and random is numpy.random with NumPy's numbers for the same seed.

Site β†’   Docs β†’   Source β†’   Playground β†’

go-fft logo

go-fft

fft v0.27.3

The numpy.fft / scipy.fft equivalent: complex and real transforms of any length, N-D, the DCT and DST, single precision, windows, with no dependency on FFTW. AVX2 and AVX-512 kernels on amd64, NEON on arm64, bit-identical to the Go code.

Site β†’   Docs β†’   Source β†’   Playground β†’

go-numerics logo

go-numerics

optimize, integrate, special v0.2.0

Numerical methods ported statement by statement from their reference algorithms: minimisation, roots, least squares and linear programming (optimize); QUADPACK quadrature and ODE solvers (integrate); gamma, beta, error, Bessel and zeta functions measured against mpmath (special).

Site β†’   Docs β†’   Source β†’   Playground β†’

go-statistics logo

go-statistics

stats v0.1.0

32 univariate and 3 multivariate distributions with every method of SciPy's frozen distributions, descriptive statistics with NumPy's 13 quantile methods, and the statistical tests, from t-tests to Shapiro–Wilk and Anderson–Darling.

Site β†’   Docs β†’   Source β†’   Playground β†’

go-dataframe logo

go-dataframe

dataframe v0.2.0

Series, DataFrame and Index whose numeric columns are go-ndarray arrays: CSV, Arrow and Parquet, group-by, joins, reshaping and time series, giving pandas' answers.

Site β†’   Docs β†’   Source β†’

go-plot logo

go-plot

plot v0.1.1

matplotlib's object model and defaults, figures to SVG and PNG, real TeX in the labels; ticks, colormaps and layout tested equal to matplotlib where they can be equal.

Site β†’   Docs β†’   Source β†’

go-notebook logo

go-notebook

notebook v0.3.0

A notebook is a Markdown file whose go and ruby blocks are cells. The kernel compiles it into a real Go program, orders the cells of both languages by what they use, and runs only what changed, keeping values across runs. Ruby cells run on go-embedded-ruby, with the go-scikit bindings.

Site β†’   Docs β†’   Source β†’

go-bignum logo

go-bignum

bigfloat v0.1.0

Correctly rounded functions on math/big's big.Float (exponentials, logarithms, roots, trigonometric, hyperbolic and power functions, constants), checked against mpmath, and the Go oracle harness the other organisations validate with. Ball arithmetic and number theory are planned.

Site β†’   Docs β†’   Source β†’

go-sparse logo

go-sparse

sparse v0.1.0

CSR, CSC and COO matrices with int32 indices as in scipy.sparse, fill-reducing orderings (AMD, COLAMD, RCM) and preconditioned CG, GMRES, MINRES and LSQR with SciPy's iteration counts; every measured case at or below SciPy's time. Direct solvers and sparse eigensolvers are planned.

Site β†’   Docs β†’   Source β†’

go-approx logo

go-approx

interp v0.2.1, poly v0.1.0

interp is numpy.interp, interp1d, PCHIP, Akima, cubic, B- and smoothing splines and gridded interpolation; poly is numpy.polyfit, roots and the five numpy.polynomial bases, at or below NumPy's time. Chebyshev and AAA approximation and scattered data are planned.

Site β†’   Docs β†’   Source β†’

go-dsp logo

go-dsp

signal v0.1.0

scipy.signal in Go: IIR and FIR design (Butterworth to elliptic, Remez, least squares), filtering, convolution, Welch, spectrograms, resampling and peak finding, all 28 measured cases at or below SciPy's time. Wavelets and audio I/O are planned.

Site β†’   Docs β†’   Source β†’

go-symbolic logo

go-symbolic

planned (wave 4)

Computer algebra: expressions, simplification, differentiation, integration and equation solving, the core of what Mathematica does symbolically.

Site β†’   Docs β†’

go-mlkit logo

go-mlkit

planned (wave 3)

Machine learning on go-ndarray arrays: clustering, classification and regression models, and model selection.

Site β†’   Docs β†’

go-autodiff logo

go-autodiff

planned (wave 2)

Automatic differentiation, forward and reverse mode, for the optimisers, solvers and models of the other organisations.

Site β†’   Docs β†’

go-geometry logo

go-geometry

planned (wave 2)

Robust predicates, convex hulls, Delaunay triangulations, Voronoi diagrams, k-d trees and mesh generation.

Site β†’   Docs β†’

go-fem logo

go-fem

planned (wave 3)

Finite elements and PDE solvers on the meshes of go-geometry and the sparse solvers of go-sparse.

Site β†’   Docs β†’

go-graphalgo logo

go-graphalgo

planned (wave 3)

Graph algorithms: traversals, shortest paths, flows, matchings, connectivity and centrality.

Site β†’   Docs β†’

go-control logo

go-control

planned (wave 3)

Control systems (transfer functions, state space, analysis and design) and DAE solvers.

Site β†’   Docs β†’

go-units logo

go-units

planned (wave 2)

Units of measure with dimensional checking, and the physical constants.

Site β†’   Docs β†’

go-sciio logo

go-sciio

planned (wave 2)

Scientific file formats read into and written from go-ndarray arrays: HDF5, MAT, NetCDF, FITS, npy, Matrix Market, WAV and FLAC.

Site β†’   Docs β†’

What is measured

9 claims, each with its evidence.

Every figure below is from the library's own documentation, which says how it was measured and against which version of the reference. The references are mpmath, NumPy, SciPy, pandas, matplotlib and FFTW; where a library loses to them, the same documents say so.

Accuracy against mpmath

go-statistics measures every distribution function in ULPs against mpmath, with SciPy on the same points: at or below SciPy's error in 1473 of 1479 regions, the six exceptions under 4.5 ulp.

go-statistics accuracy β†’

Special functions in ULPs

go-numerics' special functions, about 250 000 points in 419 regions over 62 functions: at or below SciPy's error in 418 regions.

go-numerics accuracy β†’

NumPy's numbers, same seed

go-ndarray's random is numpy.random: PCG64, MT19937, Philox, SFC64 and 40 samplers, bit-exact against NumPy 2.5.3 on x86-64, the few ULP-level exceptions listed.

go-ndarray random β†’

SciPy's draws, to the bit

On that generator, go-statistics' draws of 17 distributions, Dirichlet and multinomial are bit-identical to SciPy's; the others are listed with how much they differ.

go-statistics draws β†’

The reference's path

116 of 124 fixture integrals take SciPy's exact QUADPACK subdivision path, and 110 of 120 solve_ivp runs its exact steps.

go-numerics integrate β†’

Faster than FFTW, and slower where it is

At v0.27.0 go-fft is faster than FFTW on all 24 rows on Neoverse-N1 and at or above numpy.fft and scipy.fft on all 24 rows on every host measured; the tables include the rows FFTW wins.

go-fft benchmarks β†’

Against NumPy and OpenBLAS

go-ndarray is faster on whole-array reductions and the *Into forms of elementwise operations, and slower on MatMul against 16-thread OpenBLAS from 512Β².

go-ndarray performance β†’

pandas' answers, polars' speed

go-dataframe replays 173 cases recorded from pandas 3.0; polars is faster on most of the operations measured, and the numbers say by how much.

go-dataframe performance β†’

matplotlib's ticks

go-plot's tick locations, labels and offset text on 408 axes of real figures: every location bit for bit, every label character for character.

go-plot design β†’

Roadmap

Parity with MATLAB and Mathematica, in four waves.

The goal is feature parity with MATLAB (base and toolboxes) and Mathematica, in pure Go (CGO=0), each piece validated against the reference tools of its domain. The plan, the home of each domain and the order of the work are in the roadmap repository: PLAN.md, STATUS.md and the bibliography. Five packages of the new organisations have been released: go-approx/interp v0.2.1 (speed comparison in its docs/perf.md), go-approx/poly, go-dsp/signal and go-sparse/sparse v0.1.0, each at or below its reference's time on every case measured, and go-bignum/bigfloat v0.1.0, at or below mpmath's time on every function (docs/perf.md). The vector-update kernels Axpy, Xpby, AxpyDot and Scale shipped in go-simd/floats v0.4.0.

Wave 1: the everyday MATLAB core

Correctly rounded big.Float functions and a Go oracle harness; sparse matrices and iterative solvers; interpolation and splines; filter design and spectral estimation.

Homes: go-bignum, go-sparse, go-approx, go-dsp

Wave 2: models and geometry

Constrained and global optimisation; linear models and GLM; exact predicates, Delaunay, Voronoi; automatic differentiation; units; scientific file formats; dense linear algebra additions.

Homes: go-numerics/optimize, go-statistics/models, go-geometry, go-autodiff, go-units, go-sciio, go-ndarray/linalg

Wave 3: systems, PDEs, 3D, interactivity

3D plots and Manipulate; control systems; meshing and finite elements; sparse direct solvers, wavelets, Chebyshev and AAA; machine learning and time series; graph algorithms and layouts.

Homes: go-plot, go-notebook, go-control, go-geometry, go-fem, go-sparse, go-dsp, go-approx, go-mlkit, go-statistics/timeseries, go-graphalgo, go-graphdrawing

Wave 4: Mathematica's core

Ball arithmetic, N-digit special functions and number theory; computer algebra.

Homes: go-bignum, go-symbolic

The organisations of the plan are in the organisations with the others, each card with its status and links to its landing and documentation.

Get started

A first notebook, in four commands.

A notebook is a Markdown file; its go and ruby blocks are the cells. Put the notebook from the top of this page in first.md, in a module that requires the libraries its Go cells import, and run it. It prints the quartiles of a thousand normal draws from seed 42 (the draws SciPy's norm.rvs(10, 2, size=1000, random_state=np.random.default_rng(42)) makes), then fits a normal distribution to the same draws in Ruby.

shell
$ go install github.com/go-notebook/notebook/cmd/notebook@latest
$ go mod init example.com/first
$ go get github.com/go-statistics/stats github.com/go-ndarray/ndarray
$ notebook run first.md
── cell 0 (line 4)
── cell 1 (line 14)
── cell 2 (line 19)
   [8.607374170843807 10.012355742798341 11.179773490450081]
── cell 3 (line 26)
   "loc 9.9422, scale 1.9774"

# notebook html first.md    writes first.html
# notebook serve first.md   the same, live in the browser, editable

Run it again and every cell is kept: a cell whose code and inputs did not change is not run again, across runs. The go-notebook documentation gives the cell rules; to try the arrays and the transforms without installing anything, the go-ndarray and go-fft playgrounds run them compiled to WebAssembly in the browser, and the go-statistics and go-numerics playgrounds run whole notebooks there: edit the cells, run them, see the figures.

A ruby cell runs on go-embedded-ruby, a Ruby written in Go, so the notebook stays one Go program with no Ruby to install. It sees the values the Go cells above it defined (here x, a Go []float64), and the Go cells below it see what it defines; the kernel orders and re-runs cells of both languages by what they use. From Ruby, the stack is reached through go-scikit/ruby, which the kernel adds by itself: Stats, Special, Optimize, Integrate, DataFrame and Plot call the same Go functions, with the same answers. The Ruby cells page gives the rules, and the -timeout and -memory limits that stop a runaway cell.

Repositories

What is here.

This page (Hugo, on the go-fleettools landing kit). The notebook in the hero is run again by CI, which fails if its output changes.

brand

assets

Logos and icons in SVG / PNG / JPG / ICO / ICNS; the mark is the stack, written by a Go program from the list of member organisations.

docs

docs

The documentation site (Hugo and Hextra), served at go-scikit.github.io/docs: the member organisations with their landing and docs links, and the status of the parity-plan packages.

ruby

bindings

Ruby bindings to the stack, for go-embedded-ruby (v0.1.0): Stats, Special, Optimize, Integrate, DataFrame and Plot, each compared with the Go call it wraps, and the runner of a notebook's ruby cells.

The parity plan with MATLAB and Mathematica: the home of each domain, the four waves, the status of each item and the bibliography.

.github

profile

The organisation profile and the shared Renovate preset.

One stack, 20 organisations.

Each library is a go get away and none needs cgo. Start from the organisation that matches the question: the arrays, a transform, a solver, a distribution, a table or a figure, then reach the others from a notebook.

go-scikit on GitHub β†’