Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,25 @@ jobs:
- name: The stated conformance total matches the gate
run: go run ./tools/conformancefigure

# The Ruby examples on this site state their own answers, and until now
# nothing ran them: a binding renamed or a return shape changed in the
# ruby repository left every example here claiming its old output, which
# reads as a promise and is the first thing a reader tries.
#
# rbgo is built from the ruby repository's main, so the examples are
# judged against the interpreter this site documents rather than against
# a release that may be behind it. A build that fails, or an interpreter
# that cannot be produced, exits 2 -- a REFUSAL, not a pass, for the same
# reason the baseline check above refuses.
- name: The Ruby examples print what the pages say they print
run: |
go run ./tools/docexample -selftest
# GOBIN names the destination: `go install` otherwise writes to
# $(go env GOPATH)/bin, and an install that lands somewhere else looks
# exactly like one that worked.
GOBIN=/tmp go install github.com/go-embedded-ruby/ruby/cmd/rbgo@main
go run ./tools/docexample -rbgo /tmp/rbgo -root docs

deploy:
# Only main publishes. A pull request stops after build above: it has no
# business pushing to gh-pages, and `permissions: contents: write` is not
Expand Down
13 changes: 8 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,12 @@ Every feature below is **differential-tested against MRI Ruby 4.0.5**:
reference object), `instance_variable_get`/`set`.
- **Numeric & scientific stack:** `Complex`, `Rational`, the `Math` module, and a
**cgo-free scientific stack** — `NDArray` (NumPy-style arrays), an `FFT` module
(numpy.fft-style transforms), `Image` (scikit-image-style processing) — plus
container/value types `Set`, `Bag` (multiset), `Time`, `Date` and
`BigDecimal`, each binding a pure-Go sibling library (go-ndarray / go-fft /
go-images / go-composites). See
(numpy.fft-style transforms), `Special` and `Stats` (scipy.special's 67 functions
and scipy.stats's 32 univariate distributions), `Integrate` and `Optimize`
(scipy.integrate's quadrature and scipy.optimize's root finders and minimisers),
`Image` (scikit-image-style processing) — plus container/value types `Set`, `Bag`
(multiset), `Time`, `Date` and `BigDecimal`, each binding a pure-Go sibling library
(go-ndarray / go-fft / go-numerics / go-statistics / go-images / go-composites). See
[Scientific stack](scientific-stack.md).
- **Native capability modules:** a set of `require`-able modules, each backed by a
canonical pure-Go `go-ruby-*` library so the build stays **CGO=0**. They wrap
Expand Down Expand Up @@ -285,7 +287,8 @@ The full bound family (alphabetical, all native modules in `go.mod`):
[`aasm`](https://github.com/go-ruby-aasm/aasm), [`abbrev`](https://github.com/go-ruby-abbrev/abbrev), [`acme`](https://github.com/go-ruby-acme/acme), [`actioncable`](https://github.com/go-ruby-actioncable/actioncable), [`actionmailer`](https://github.com/go-ruby-actionmailer/actionmailer), [`actionpack`](https://github.com/go-ruby-actionpack/actionpack), [`actionview`](https://github.com/go-ruby-actionview/actionview), [`activejob`](https://github.com/go-ruby-activejob/activejob), [`activemodel`](https://github.com/go-ruby-activemodel/activemodel), [`activerecord`](https://github.com/go-ruby-activerecord/activerecord), [`activestorage`](https://github.com/go-ruby-activestorage/activestorage), [`activesupport`](https://github.com/go-ruby-activesupport/activesupport), [`addressable`](https://github.com/go-ruby-addressable/addressable), [`age`](https://github.com/go-ruby-age/age), [`arrow`](https://github.com/go-ruby-arrow/arrow), [`async`](https://github.com/go-ruby-async/async), [`augeas`](https://github.com/go-ruby-augeas/augeas), [`base64`](https://github.com/go-ruby-base64/base64), [`bbolt`](https://github.com/go-ruby-bbolt/bbolt), [`bcrypt`](https://github.com/go-ruby-bcrypt/bcrypt), [`benchmark`](https://github.com/go-ruby-benchmark/benchmark), [`bigdecimal`](https://github.com/go-ruby-bigdecimal/bigdecimal), [`bleve`](https://github.com/go-ruby-bleve/bleve), [`builder`](https://github.com/go-ruby-builder/builder), [`bundler`](https://github.com/go-ruby-bundler/bundler), [`cancancan`](https://github.com/go-ruby-cancancan/cancancan), [`capistrano`](https://github.com/go-ruby-capistrano/capistrano), [`capybara`](https://github.com/go-ruby-capybara/capybara), [`cgi`](https://github.com/go-ruby-cgi/cgi), [`chronic`](https://github.com/go-ruby-chronic/chronic), [`cmath`](https://github.com/go-ruby-cmath/cmath), [`commonmark`](https://github.com/go-commonmark/commonmark), [`concurrent-ruby`](https://github.com/go-ruby-concurrent-ruby/concurrent-ruby), [`confd`](https://github.com/go-ruby-confd/confd), [`connection-pool`](https://github.com/go-ruby-connection-pool/connection-pool), [`csv`](https://github.com/go-ruby-csv/csv), [`date`](https://github.com/go-ruby-date/date), [`deep-merge`](https://github.com/go-ruby-deep-merge/deep-merge), [`devise`](https://github.com/go-ruby-devise/devise), [`did-you-mean`](https://github.com/go-ruby-did-you-mean/did-you-mean), [`digest`](https://github.com/go-ruby-digest/digest), [`dotenv`](https://github.com/go-ruby-dotenv/dotenv), [`dry-struct`](https://github.com/go-ruby-dry-struct/dry-struct), [`dry-types`](https://github.com/go-ruby-dry-types/dry-types), [`dry-validation`](https://github.com/go-ruby-dry-validation/dry-validation), [`erb`](https://github.com/go-ruby-erb/erb), [`erubi`](https://github.com/go-ruby-erubi/erubi), [`etcd`](https://github.com/go-ruby-etcd/etcd), [`excon`](https://github.com/go-ruby-excon/excon), [`facter`](https://github.com/go-ruby-facter/facter), [`factory-bot`](https://github.com/go-ruby-factory-bot/factory-bot), [`faker`](https://github.com/go-ruby-faker/faker), [`faraday`](https://github.com/go-ruby-faraday/faraday), [`fast-gettext`](https://github.com/go-ruby-fast-gettext/fast-gettext), [`find`](https://github.com/go-ruby-find/find), [`format`](https://github.com/go-ruby-format/format), [`friendly-id`](https://github.com/go-ruby-friendly-id/friendly-id), [`getoptlong`](https://github.com/go-ruby-getoptlong/getoptlong), [`grape`](https://github.com/go-ruby-grape/grape), [`graphql`](https://github.com/go-ruby-graphql/graphql), [`grpc`](https://github.com/go-ruby-grpc/grpc), [`haml`](https://github.com/go-ruby-haml/haml), [`hanami`](https://github.com/go-ruby-hanami/hanami), [`hcl2`](https://github.com/go-ruby-hcl2/hcl2), [`hiera`](https://github.com/go-ruby-hiera/hiera), [`hocon`](https://github.com/go-ruby-hocon/hocon), [`http`](https://github.com/go-ruby-http/http), [`httparty`](https://github.com/go-ruby-httparty/httparty), [`i18n`](https://github.com/go-ruby-i18n/i18n), [`images`](https://github.com/go-ruby-images/images), [`ipaddr`](https://github.com/go-ruby-ipaddr/ipaddr), [`irb`](https://github.com/go-ruby-irb/irb), [`jbuilder`](https://github.com/go-ruby-jbuilder/jbuilder), [`jekyll`](https://github.com/go-ruby-jekyll/jekyll), [`json`](https://github.com/go-ruby-json/json), [`jwt`](https://github.com/go-ruby-jwt/jwt), [`kafka`](https://github.com/go-ruby-kafka/kafka), [`kaminari`](https://github.com/go-ruby-kaminari/kaminari), [`kramdown`](https://github.com/go-kramdown/kramdown), [`liquid`](https://github.com/go-liquid/liquid), [`logger`](https://github.com/go-ruby-logger/logger), [`mail`](https://github.com/go-ruby-mail/mail), [`marshal`](https://github.com/go-ruby-marshal/marshal), [`matrix`](https://github.com/go-ruby-matrix/matrix), [`mime-types`](https://github.com/go-ruby-mime-types/mime-types), [`minitest`](https://github.com/go-ruby-minitest/minitest), [`money`](https://github.com/go-ruby-money/money), [`mongodb`](https://github.com/go-ruby-mongodb/mongodb), [`msgpack`](https://github.com/go-ruby-msgpack/msgpack), [`multi-json`](https://github.com/go-ruby-multi-json/multi-json), [`mustache`](https://github.com/go-mustache/mustache), [`mysql`](https://github.com/go-ruby-mysql/mysql), [`nats`](https://github.com/go-ruby-nats/nats), [`net-ftp`](https://github.com/go-ruby-net-ftp/net-ftp), [`net-http`](https://github.com/go-ruby-net-http/net-http), [`net-imap`](https://github.com/go-ruby-net-imap/net-imap), [`net-pop`](https://github.com/go-ruby-net-pop/net-pop), [`net-sftp`](https://github.com/go-ruby-net-sftp/net-sftp), [`net-smtp`](https://github.com/go-ruby-net-smtp/net-smtp), [`nokogiri`](https://github.com/go-nokogiri/nokogiri), [`oauth2`](https://github.com/go-ruby-oauth2/oauth2), [`observer`](https://github.com/go-ruby-observer/observer), [`oidc`](https://github.com/go-ruby-oidc/oidc), [`omniauth`](https://github.com/go-ruby-omniauth/omniauth), [`openbao`](https://github.com/go-ruby-openbao/openbao), [`openstack`](https://github.com/go-ruby-openstack/openstack), [`opentelemetry`](https://github.com/go-ruby-opentelemetry/opentelemetry), [`opentype`](https://github.com/go-ruby-opentype/opentype), [`optparse`](https://github.com/go-ruby-optparse/optparse), [`ostruct`](https://github.com/go-ruby-ostruct/ostruct), [`pagy`](https://github.com/go-ruby-pagy/pagy), [`paper-trail`](https://github.com/go-ruby-paper-trail/paper-trail), [`parquet`](https://github.com/go-ruby-parquet/parquet), [`parser`](https://github.com/go-ruby-parser/parser), [`pathname`](https://github.com/go-ruby-pathname/pathname), [`pg`](https://github.com/go-ruby-pg/pg), [`prawn`](https://github.com/go-ruby-prawn/prawn), [`prettyprint`](https://github.com/go-ruby-prettyprint/prettyprint), [`prime`](https://github.com/go-ruby-prime/prime), [`protobuf`](https://github.com/go-ruby-protobuf/protobuf), [`pstore`](https://github.com/go-ruby-pstore/pstore), [`public-suffix`](https://github.com/go-ruby-public-suffix/public-suffix), [`puma`](https://github.com/go-ruby-puma/puma), [`pundit`](https://github.com/go-ruby-pundit/pundit), [`puppet`](https://github.com/go-ruby-puppet/puppet), [`puppet-resource-api`](https://github.com/go-ruby-puppet-resource-api/puppet-resource-api), [`racc`](https://github.com/go-ruby-racc/racc), [`rack`](https://github.com/go-ruby-rack/rack), [`rails`](https://github.com/go-ruby-rails/rails), [`railties`](https://github.com/go-ruby-railties/railties), [`rake`](https://github.com/go-ruby-rake/rake), [`ransack`](https://github.com/go-ruby-ransack/ransack), [`rdoc`](https://github.com/go-ruby-rdoc/rdoc), [`redis`](https://github.com/go-ruby-redis/redis), [`regexp`](https://github.com/go-ruby-regexp/regexp), [`reline`](https://github.com/go-ruby-reline/reline), [`resolv`](https://github.com/go-ruby-resolv/resolv), [`resque`](https://github.com/go-ruby-resque/resque), [`rexml`](https://github.com/go-ruby-rexml/rexml), [`roda`](https://github.com/go-ruby-roda/roda), [`rolify`](https://github.com/go-ruby-rolify/rolify), [`rouge`](https://github.com/go-rouge/rouge), [`rqrcode`](https://github.com/go-ruby-rqrcode/rqrcode), [`rspec`](https://github.com/go-ruby-rspec/rspec), [`rss`](https://github.com/go-ruby-rss/rss), [`rubocop`](https://github.com/go-ruby-rubocop/rubocop), [`rubygems`](https://github.com/go-ruby-rubygems/rubygems), [`saml`](https://github.com/go-ruby-saml/saml), [`sass`](https://github.com/go-ruby-sass/sass), [`scanf`](https://github.com/go-ruby-scanf/scanf), [`securerandom`](https://github.com/go-ruby-securerandom/securerandom), [`semantic-puppet`](https://github.com/go-ruby-semantic-puppet/semantic-puppet), [`sequel`](https://github.com/go-ruby-sequel/sequel), [`shellwords`](https://github.com/go-ruby-shellwords/shellwords), [`shrine`](https://github.com/go-ruby-shrine/shrine), [`sidekiq`](https://github.com/go-ruby-sidekiq/sidekiq), [`simplecov`](https://github.com/go-ruby-simplecov/simplecov), [`sinatra`](https://github.com/go-ruby-sinatra/sinatra), [`slim`](https://github.com/go-ruby-slim/slim), [`sodium`](https://github.com/go-ruby-sodium/sodium), [`sqlite3`](https://github.com/go-ruby-sqlite3/sqlite3), [`strscan`](https://github.com/go-ruby-strscan/strscan), [`thor`](https://github.com/go-ruby-thor/thor), [`timecop`](https://github.com/go-ruby-timecop/timecop), [`toml`](https://github.com/go-ruby-toml/toml), [`tsort`](https://github.com/go-ruby-tsort/tsort), [`typhoeus`](https://github.com/go-ruby-typhoeus/typhoeus), [`tzinfo`](https://github.com/go-ruby-tzinfo/tzinfo), [`unicode-normalize`](https://github.com/go-ruby-unicode-normalize/unicode-normalize), [`uri`](https://github.com/go-ruby-uri/uri), [`vcr`](https://github.com/go-ruby-vcr/vcr), [`warden`](https://github.com/go-ruby-warden/warden), [`webauthn`](https://github.com/go-ruby-webauthn/webauthn), [`webmock`](https://github.com/go-ruby-webmock/webmock), [`webrick`](https://github.com/go-ruby-webrick/webrick), [`widgets`](https://github.com/go-ruby-widgets/widgets), [`xslt`](https://github.com/go-xslt/xslt), [`yaml`](https://github.com/go-ruby-yaml/yaml), [`zeitwerk`](https://github.com/go-ruby-zeitwerk/zeitwerk), [`zlib`](https://github.com/go-ruby-zlib/zlib), [`activeldap`](https://github.com/go-ruby-activeldap/activeldap), [`ldap`](https://github.com/go-ruby-ldap/ldap), [`fast-gettext-locale`](https://github.com/go-ruby-fast-gettext-locale/fast-gettext-locale) — each at `github.com/go-ruby-<name>/<name>`, except `commonmark`, `kramdown`, `liquid`, `mustache`, `nokogiri`, `rouge` and `xslt`, which are bound from `github.com/go-<name>/<name>`. (`set` is **not** bound: `Set` is implemented in-tree, over rbgo's own `object.Hash`.)

The scientific / container stack ([go-ndarray](https://github.com/go-ndarray/ndarray),
[go-fft](https://github.com/go-fft/fft), [go-images](https://github.com/go-images/images),
[go-fft](https://github.com/go-fft/fft), [go-numerics](https://github.com/go-numerics),
[go-statistics](https://github.com/go-statistics), [go-images](https://github.com/go-images/images),
[go-composites](https://github.com/go-composites)) binds in the same way.

## How it differs from goruby
Expand Down
100 changes: 100 additions & 0 deletions docs/scientific-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,106 @@ bin-frequency helpers (`fftfreq`/`rfftfreq`), windows
p FFT.fft([1, 2, 3, 4]).map { |c| c.real.round(3) } # => [10.0, -2.0, -2.0, -2.0]
```

## Special — scipy.special-style functions

Binds [go-numerics/special](https://github.com/go-numerics/special) — no SciPy:
**all 67** of its functions under 66 Ruby names, which are **scipy's own**. The
names come from the correspondence that module measures itself against in ULPs
(`bench/scipy_server.py` and `testdata/gen/fam_*.py`), so `Log1pExp` is
`softplus` and `LogGamma` is `gammaln` rather than a transliteration of the Go
name. Gamma (`gamma`/`gammaln`/`gammasgn`/`digamma`/`polygamma`/`factorial`),
beta (`beta`/`betaln`/`binom`/`comb`/`perm`), error and normal
(`erf`/`erfc`/`erfcx`/`erfinv`/`erfcinv`/`ndtr`/`ndtri`/`log_ndtr`), logistic
(`expit`/`logit`/`softplus`/`xlogy`), reductions
(`logsumexp`/`softmax`/`log_softmax`), `zeta` (Riemann, or Hurwitz with a second
argument), the incomplete gamma and beta functions with their inverses, Bessel
(`j0`…`k1e`, `jv`/`yv`/`iv`/`kv`, `jn_zeros`) and the complete elliptic
integrals.

Each is a **ufunc**, as scipy's is: a Float answers a Float, an `NDArray`
answers an `NDArray` of the same shape, and a Float mixed with an array
broadcasts.

```ruby
p Special.gamma(5.0) # => 24.0
p Special.erf(1.0) # => 0.8427007929497149
p Special.zeta(2.0) # => 1.6449340668482264
p Special.gamma(NDArray.from([1.0, 2.0, 3.0, 4.0], [2, 2])).to_a # => [1.0, 1.0, 2.0, 6.0]
```

## Stats — scipy.stats-style distributions

Binds [go-statistics/stats](https://github.com/go-statistics/stats) — no SciPy:
the **32 univariate distributions**, again under scipy's names, which is why
`StudentT` is `t`, `ChiSquared` is `chi2`, `DiscreteUniform` is `randint` and
`Weibull` is `weibull_min`. Continuous
`norm`/`cauchy`/`expon`/`gumbel_r`/`halfnorm`/`laplace`/`logistic`/`rayleigh`/
`uniform`/`chi`/`chi2`/`gamma`/`invgamma`/`lognorm`/`lomax`/`pareto`/`t`/
`triang`/`vonmises`/`weibull_min`/`beta`/`f`/`ncx2`/`reciprocal`; discrete
`bernoulli`/`geom`/`poisson`/`zipf`/`binom`/`nbinom`/`randint`/`hypergeom`.

Arguments follow scipy's order — the shape parameters, then `loc`, then `scale`
— and every distribution answers the same method set, `Stats::Continuous` and
`Stats::Discrete` differing only in the density: `pdf`/`logpdf` against
`pmf`/`logpmf`, plus `cdf`/`logcdf`/`sf`/`logsf`/`ppf`/`isf`, the moments
`mean`/`var`/`std`/`skew`/`kurtosis`/`median`/`entropy`/`moment`,
`interval`/`support`, and `rvs(size…, seed:)`. The per-point methods are ufuncs
too. A parameter outside its domain is refused at construction.

```ruby
p Stats.norm.pdf(0.0) # => 0.3989422804014327
p Stats.norm.ppf(0.975) # => 1.9599639845400538
p Stats.poisson(3.0).pmf(2) # => 0.22404180765538775
p Stats.binom(10, 0.5).mean # => 5.0
```

## Integrate — scipy.integrate-style quadrature

Binds [go-numerics/integrate](https://github.com/go-numerics/integrate) — no
SciPy: adaptive `quad` (finite **or infinite** limits, `points:` for a known
kink), the fixed rules `fixed_quad` and `romberg`, the sampled rules
`trapezoid`/`simpson`/`romb`/`cumulative_trapezoid` (`x:` or `dx:`), the
multiple integrals `dblquad` and `nquad`, and `gauss_legendre` for a rule's
nodes and weights.

The integrand is a **block**, which is how Ruby passes a callable — and which
takes `&f` for a Proc or lambda without any further surface. `quad` answers
scipy's `(value, abserr)` pair, so it destructures the same way.

The two quadrature results in the example below are rounded, and the others on
this page are not. Quadrature sums products, which Go fuses into an FMA on
arm64 and not on amd64, so the last bit of `quad`'s answer differs between
architectures: `0.3333333333333333` on one and `0.33333333333333337` on the
other. The special functions do not drift that way — their kernels are kept
FMA-free on purpose — which is why only these two carry a `round`.

```ruby
v, err = Integrate.quad(0.0, 1.0) { |x| x * x }
p v.round(12) # => 0.333333333333
p Integrate.quad(0.0, Float::INFINITY) { |x| Math.exp(-x) }[0].round(12) # => 1.0
p Integrate.trapezoid([0.0, 1.0, 4.0], dx: 1.0) # => 3.0
```

## Optimize — scipy.optimize-style root finding and minimisation

Binds [go-numerics/optimize](https://github.com/go-numerics/optimize) — no
SciPy: the bracketing root finders `brentq`/`brenth`/`bisect`/`ridder` and
`newton` (secant, Newton–Raphson with `fprime:`, Halley with `fprime2:`),
`minimize_scalar` and `fminbound`, `minimize` over several variables
(`BFGS`/`CG`/`Nelder-Mead`/`Powell`/`L-BFGS-B`, with `bounds:`), plus
`curve_fit`, `approx_fprime` and `bracket`.

Return shapes are scipy's: one number is a Float, a tuple an Array (`curve_fit`
is `(popt, pcov)`), and an `OptimizeResult` or `RootResults` a Hash with symbol
keys — which `full_output: true` asks a root finder for.

```ruby
p Optimize.brentq(0.0, 2.0) { |x| x * x - 2 } # => 1.4142135623731364
p Optimize.minimize_scalar { |x| (x - 3.0) ** 2 }[:x] # => 3.0
r = Optimize.minimize([0.0, 0.0]) { |v| (v[0] - 1.0) ** 2 + (v[1] - 2.0) ** 2 }
p r[:x].map { |z| z.round(6) } # => [1.0, 2.0]
```

## Image — scikit-image-style processing

Binds [go-images](https://github.com/go-images/images): `Image.new`/`load`/`save`
Expand Down
Loading
Loading