NuMojo, Linamo, and SciJo, updated for Mojo v1.2.0

Hi Mojicians,

I am glad to let you know that NuMojo, Linamo, and SciJo are now updated for Mojo v1.2.0. All three are maintained under the Mojo-Numerics-and-Algorithms-group and mojomath organisations, and are on the modular-community channel:

pixi add numojo
pixi add linamo
pixi add scijo

In case you haven’t met them yet: NuMojo is our NumPy for Mojo, with N-dimensional arrays and lots of numerical routines. Linamo focuses on linear algebra with 2-D matrices, which can hold floats, arbitrary-precision numbers, or complex numbers. SciJo builds on NuMojo to do what SciPy does, from optimization and FFT to special functions.

NuMojo v0.12.0 is mostly the migration to Mojo v1.2.0. It also adds stack, dstack, hsplit, vsplit and dsplit, and fixes several things about complex arrays: arithmetic mixing real and complex values, complex powers, and the complex versions of creation routines such as ones, eye and logspace. The release before, v0.11.0 for Mojo v1.1.0, was a big one that we did not post about: SVD, pseudoinverse, Cholesky and QR, random distributions, quantiles and histograms, .npy and .pt file I/O, and a long list of NumPy routines.

Linamo v0.3.0 is a pure migration to Mojo v1.2.0, with no API changes. In case you missed v0.2.0: a matrix can now hold complex numbers, and lu, det, solve, inv, cholesky, qr and lstsq work on them:

import linamo as la
from linamo import CFloat64

def main() raises:
    var a = la.matrix[CFloat64](
        [[CFloat64(2, 1), CFloat64(0, 1)], [CFloat64(1, 0), CFloat64(3, -1)]]
    )
    print(la.det(a))  
    # This prints
    # 7.0+0.0i

SciJo v0.4.0 is more than a migration to Mojo v1.2.0. It adds scijo.special (gamma, erf, beta, digamma, incomplete gamma and beta, Bessel and Airy functions, etc) and scijo.types, which has a Dual number for forward-mode automatic differentiation. Each special function is written once, generically, so calling it on a Dual instead of a float gives you the exact derivative for free (hooray):

from scijo.types import Numeric, variable

def f[T: Numeric](x: T) -> T:
    return x * x + 2.0 * x

def main() raises:
    print(f(variable(3.0)).deriv.v)  # f'(3) = 2*3 + 2 = 8.0

Release notes: NuMojo v0.12.0, Linamo v0.3.0, SciJo v0.4.0

Relevant posts:
NuMojo: v0.10.0, v0.9.0, v0.8.0, v0.6, v0.5
Linamo: v0.1.0
SciJo: first release

6 Likes

@Photon