uncomplicate.neanderthal.core

Contains core type-agnostic linear algebraic functions roughly corresponding to functionality defined in BLAS 123, and functions to create and work with various kinds of vectors and matrices. Typically, you would want to require this namespace regardless of the actual type (real, complex, CPU, GPU, pure Java etc.) of the vectors and matrices that you use.

In cases when you need to repeatedly call a function from this namespace that accesses individual entries, and the entries are primitive, it is better to use a primitive version of the function from uncomplicate.neanderthal.real namespace. Constructor functions for different specialized types (native, GPU, pure java) are in respective specialized namespaces (uncomplicate.neanderthal.native, uncomplicate.neanderthal.opencl, etc).

Please take care to only use vectors and matrices of the same type in one call of a linear algebra operation. Compute operations typically (and on purpose!) do not support arguments of mixed types. For example, you can not call the dot function with one double vector (dv) and one float vector (fv), or for one vector in the CPU memory and one in the GPU memory. If you try to do that, an ex-info is thrown. You can use those different types side-by-side and transfer data between them though.

How to use

(ns test
  (:require [uncomplicate.neanderthal core native]))

(ns test
  (:require [uncomplicate.neanderthal core native opencl]))

Examples

The best and most accurate examples can be found in the comprehensive test suite: see here, here, and here. Also, there are tutorial test examples here, the tutorials at the Neanderthal web site, and my blog dragan.rocks.

Cheat Sheet

Naming conventions for BLAS routines.

alter!

(alter! x f)(alter! x i f)(alter! a i j f)

Alters the i-th entry of vector x, or (i, j)-th entry of matrix a by evaluating function f on one or all of its elements.

If no index is passed, the function f will alter all elements and feeds the indices to f. If the structure holds primitive elements, the function f must accept appropriate primitive unboxed arguments, and it will work faster if it also returns unboxed result.

If i or j is not within the dimensions of the object, throws ExceptionInfo.

(alter! (dv 1 2 3) 2 (fn ^double [^double x] (inc x)))
(alter! (dge 2 2) (fn ^double [^long i ^long j ^double x] (double (+ i j))))

amax

(amax x)

Absolute value of the first entry of vector x that has the largest absolute value.

See related info about cblas_i?amax.

(amax (dv 1 -3 2)) => 3

asum

(asum x)

Sums absolute values of entries of vector or matrix x’’.

See related info about cblas_?asum.

(asum (dv -1 2 -3)) => 6.0

ax

(ax alpha x)

Multiplies vector or matrix x by a scalar alpha. Similar to scal!, but does not change x. The result is a new instance. See axpy! and axpy.

axpby!

(axpby! alpha x beta y)(axpby! x beta y)(axpby! x y)(axpby! alpha x beta y & zs)

Multiplies elements of a vector or matrix x by scalar alpha and adds it to vector or matrix y, that was previously scaled by scalar beta.

The contents of y will be changed.

If called with 2 arguments, x and y, adds vector or matrix x to a vector or matrix y. If called with more than 4 arguments, at least every other have to be a vector or matrix. A scalar multiplier may be included before each object.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?axpby.

(axpy! 3 x 0.9 y)
(axpy! x y)
(axpy! 3 x 0.2 y 4 z 0.4 v)

axpy

(axpy x y)(axpy x y z)(axpy x y z w & ws)

A pure variant of axpy! that does not change any of the arguments. The result is a new instance.

axpy!

(axpy! alpha x y)(axpy! x y)(axpy! alpha x y & zs)

Multiplies elements of a vector or matrix x by scalar alpha and adds it to a vector or matrix y.

The contents of y will be changed.

If called with 2 arguments, x and y, adds vector or matrix x to a vector or matrix y. If called with more than 3 arguments, at least every other have to be a vector or matrix. A scalar multiplier may be included before each object.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?axpy.

(axpy! 3 x y)
(axpy! x y)
(axpy! 3 x y 4 z 0.4 v)

col

(col a j)

Returns the j-th column of the matrix a as a vector.

The vector has access to and can change the same data as the original matrix.

If the requested column is not within the dimensions of a, throws ExceptionInfo.

cols

(cols a)

Returns a lazy sequence of column vectors of the matrix a.

The vectors has access to and can change the same data as the original matrix.

copy

(copy x)(copy x offset length)

Copies all entries of a vector or a matrix x to the newly created structure (see copy!).

copy!

(copy! x y)(copy! x y offset-x length offset-y)

Copies all entries of a vector or a matrix x to the compatible structure y.

Only y will be changed.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?copy.

dia

(dia a)

Returns the diagonal elements of the matrix a in a vector.

The vector has access to and can change the same data as the original matrix.

dim

(dim x)

Returns the dimension of the vector x.

dot

(dot x y)

Computes the dot product of vectors or matrices x and y.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?dot.

(dot (dv 1 2 3) (dv 1 2 3)) => 14.0

entry

(entry x i)(entry a i j)

Returns the boxed i-th entry of vector x, or (i, j)-th entry of matrix a.

For optimally accessing the elements of native objects use the equivalent entry function from uncomplicate.neanderthal.real namespace.

If i or j is not within the dimensions of the object, throws ExceptionInfo.

entry!

(entry! x val)(entry! x i val)(entry! a i j val)

Sets the i-th entry of vector x, or (i, j)-th entry of matrix a using a boxed method.

For optimally accessing the elements of native objects use the equivalent entry! function from uncomplicate.neanderthal.real namespace.

If i or j is not within the dimensions of the object, throws ExceptionInfo.

ge

(ge factory m n source options)(ge factory m n arg)(ge factory m n)(ge factory a)

Creates a dense matrix (GE) in the context of factory, with m rows and n columns.

If source is provided, transfers the data to the result. source is typically a sequence, a matrix, or another structure that can be transferred to the context of factory. If source is a matrix, dimensions m and n are not required.

The internal structure can be specified with a map of options: :order (:column or :row).

If the provided indices or source do not make sense, throws ExceptionInfo.

(ge float-factory 2 3)
(ge opencl-factory 2 3 (range 6))
(ge opencl-factory (ge double-factory 2 3 (range 6)))

ge?

(ge? x)

Tests if x is a dense matrix (GE).

iamax

(iamax x)

The index of the first entry of vector x that has the largest absolute value.

See related info about cblas_i?amax.

(iamax (dv 1 -3 2)) => 1

iamin

(iamin x)

The index of the first entry of vector x that has the smallest absolute value.

See related info about cblas_i?amin.

(iamin (dv 1 -3 2)) => 0

imax

(imax x)

The index of the first entry of vector x that has the largest value.

See related info about cblas_i?amax.

(imax (dv 1 -3 2)) => 2

imin

(imin x)

The index of the first entry of vector x that has the smallest value.

See related info about cblas_i?amin.

(imin (dv 1 -3 2)) => 2

matrix?

(matrix? x)

Tests if x is a matrix of any kind.

mm

(mm a b c & ds)(mm a b)

Pure matrix multiplication that returns the resulting matrix in a new instance. Computes alpha a * b, if alpha is scalar, or alpha * a * b * c * ... * ds if alpha is a vector. Does matrix composition by optimally multiplying the chain of matrices.

If any consecutive pair’s dimensions do not fit for matrix multiplication, throws ExceptionInfo.

mm!

(mm! alpha a b beta c)(mm! alpha a b c)(mm! alpha a b)(mm! a b)

Matrix-matrix multiplication. Multiplies matrix a, scaled by scalar alpha, by matrix b, and ads it to matrix c previously scaled by scalar beta.

If called with only 2 matrices, a and b, multiplies matrix a by a matrix b, and puts the result in the one that is a GE matrix. In this case, exactly one of a or b has to be, and one not be a GE matrix, but TR, or SY, or a matrix type that supports in-place multiplication. Scaling factors alpha and/or beta may be left out.

The contents of the destination matrix will be changed.

If the context or dimensions of a, b and c are not compatible, throws ExceptionInfo.

See related info about cblas_?gemm, and cblas_?trmm.

(def a (dge 2 3 (range 6)))
(def b (dge 3 2 (range 2 8)))
(def c (dge 2 2 [1 1 1 1]))
(def e (dtr 3 (range 6)))

(mm! 1.5 a b 2.5 c)
(mm! 2.3 a e)
(mm! e a)

mrows

(mrows a)

Returns the number of rows of the matrix a.

mv

(mv alpha a x beta y)(mv alpha a x y)(mv alpha a x)(mv a x)

Matrix-vector multiplication. A pure version of mv! that returns the result in a new vector instance. Computes alpha * a * x.

mv!

(mv! alpha a x beta y)(mv! alpha a x y)(mv! a x y)(mv! a x)

Matrix-vector multiplication. Multiplies matrix a, scaled by scalar alpha, by vector x, and ads it to vector y previously scaled by scalar beta.

If called with 2 arguments, a and x, multiplies matrix a by a vector x, and puts the result in the vector x. Scaling factors alpha and/or beta may be left out.

The contents of the destination vector will be changed.

If the context or dimensions of a, x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?gemv, and cblas_?trmv.

(mv! 3 a x y)
(mv! a x y)
(mv! a x)

native

(native x)

Ensures that x is in the native main memory, and if not, transfers it there.

(let [v (fv [1 2 3])] (identical? (native v) v)) => true

ncols

(ncols a)

Returns the number of columns of the matrix a.

nrm1

(nrm1 x)

Computes the 1-norm of vector or matrix x.

nrm2

(nrm2 x)

Computes the Euclidan norm of vector x, or Frobenius norm of matrix x.

See related info about cblas_?nrm2.

(nrm2 (dv 1 2 3)) => 3.7416573867739413

nrmi

(nrmi x)

Computes the infinity-norm of vector or matrix x.

raw

(raw x)(raw factory x)

Returns an uninitialized instance of the same type and dimension(s) as x.

rk

(rk alpha x y a)(rk alpha x y)(rk x y)

Pure rank-1 update. A pure version of rk! that returns the result in a new matrix instance.

rk!

(rk! alpha x y a)(rk! x y a)

Rank-1 update. Multiplies vector x with transposed vector y, scales the resulting matrix by scalar alpha, and adds it to the matrix a.

The contents of a will be changed.

If the context or dimensions of a, x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?ger.

(rk! 1.5 (dv 1 2 3) (dv 4 5) a)

rot!

(rot! x y c s)(rot! x y c)

Rotates points of vectors x and y in the plane by cos c and sin s.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?rot.

rotg!

(rotg! abcs)

Computes the parameters for a givens rotation and puts them as entries of a 4-element vector abcs, that can be used as parameters in rot!.

If abcs does not have at least 4 entries, throws ExceptionInfo.

See related info about cblas_?rotg.

rotm!

(rotm! x y param)

Rotates points of vectors x and y in the plane using Givens rotation.

param must be a vector of at least 4 entries.

See related info about cblas_?rotm.

rotmg!

(rotmg! d1d2xy param)

BLAS 1: Generate modified plane rotation.

If the context or dimensions of d1d2xy and param are not compatible, or d1d2xy does not have at least at least 4 entries, or param does not have at least 5 entries, throws ExceptionInfo.

See related info about cblas_?rotmg.

row

(row a i)

Returns the i-th row of the matrix a as a vector.

The vector has access to and can change the same data as the original matrix.

If the requested column is not within the dimensions of a, throws ExceptionInfo.

rows

(rows a)

Returns a lazy sequence of row vectors of the matrix a.

The vectors has access to and can change the same data as the original matrix.

scal

(scal alpha x)

Multiplies all entries of a copy a vector or matrix x by scalar alpha.

See related info about cblas_?scal.

scal!

(scal! alpha x)

Multiplies all entries of a vector or matrix x by scalar alpha.

After scal!, x will be changed.

See related info about cblas_?scal.

submatrix

(submatrix a i j k l)(submatrix a k l)

Returns a submatrix of the matrix a starting from row i, column j, that has k kolumns and l rows.

The resulting submatrix has a live connection to a’s data. Any change to the subvector data will affect the vector data. If you wish to disconnect the submatrix from the parent matrix, make a copy prior to any destructive operation.

If the requested region is not within the dimensions of a, throws ExceptionInfo.

(submatrix (ge double-factroy 4 3 (range 12)) 1 1 2 1)

subvector

(subvector x k l)

Returns a subvector starting witk k, l entries long, which is a part of the neanderthal vector x.

The resulting subvector has a live connection to x’s data. Any change to the subvector data will affect the vector data. If you wish to disconnect the subvector from the parent vector, make a copy prior to any destructive operation.

If the requested region is not within the dimensions of x, throws ExceptionInfo.

sum

(sum x)

Sums values of entries of a vector or matrix x.

(sum (dv -1 2 -3)) => -2.0

swp!

(swp! x y)

Swaps all entries of vectors or matrices x and y.

Both x and y will be changed.

If the context or dimensions of x and y are not compatible, throws ExceptionInfo.

See related info about cblas_?swap.

tr

(tr factory n source options)(tr factory n arg)(tr factory source)

Creates a dense triangular matrix (TR) in the context of factory, with n rows and n columns.

If source is provided, transfers the data to the result. source is typically a sequence, a matrix, or another structure that can be transferred to the context of factory. If source is a matrix, dimension n is not required.

The internal structure can be specified with a map of options: :order (:column or :row), :uplo (upper or :lower), and :diag (:unit or :non-unit).

If the provided indices or source do not make sense, throws ExceptionInfo.

(tr float-factory 2)
(tr opencl-factory 3 (range 6))
(tr opencl-factory (ge double-factory 2 3 (range 6)))

tr?

(tr? x)

Tests if x is a triangular matrix (TR).

trans

(trans a)

Transposes matrix a, i.e returns a matrix that has m’s columns as rows.

The transpose does not affect the internal structure of a. The resulting matrix has a live connection to a’s data.

trans!

(trans! a)

Transposes matrix a’s data in-place. For the ‘real’ transpose, use the trans function.

The transpose affects the internal structure of a.

(trans! (dge 2 3 [1 2, 3 4, 5 6])) => (dge 2 3 [1 3, 5 2, 4 ,6])

transfer

(transfer factory x)(transfer x)

Transfers the data to the memory context defined by factory (native, OpenCL, CUDA, etc.).

If factory is not provided, moves the data to the main host memory. If x is already in the main memory, makes a fresh copy.

(transfer (fv [1 2 3]) opencl-factory)
(transfer (sge 2 3 (range 6)) opencl-factory)

(transfer (fv [1 2 3]))

transfer!

multimethod

Transfers the data from source to destination regardless of the structure type or memory context.

Typically you would use it when you want to move data between the host memory and the OpenCL device memory. If you want to simply move data from one object to another in the same memory context, you should prefer copy!. If both arguments are already in the same memory context, the data will simply be copied, but with multimethod call overhead.

(transfer! (fv 1 2 3) device-vctr)
(transfer! device-vctr (fv 3))

vctr

(vctr factory source)(vctr factory x & xs)

Creates a dense vector in the context of factory, from the provided source.

If source is an integer, creates a vector of zeroes. If source is a number, puts it in the resulting vector. Otherwise, transfers the data from source (a sequence, vector, etc.) to the resulting vector.

If the provided source do not make sense, throws ExceptionInfo.

(vctr double-factory 3)
(vctr float-factory 1 2 3)
(vctr opencl-factory [1 2 3])
(vctr opencl-factory (vctr float-factory [1 2 3]))

vctr?

(vctr? x)

Tests if x is a (neanderthal) vector.

view-ge

(view-ge a)(view-ge a stride-mult)

Attach a GE matrix to the raw data of a, with optional stride multiplicator.

Changes to the resulting object affect the source a, even the parts of data that might not be accessible by a. Use with caution!

(view-ge (tr float-factory 3 (range 6)))

view-tr

(view-tr a)(view-tr a options)

Attach a TR matrix to the raw data of a.

Changes to the resulting object affect the source a, even the parts of data that might not be accessible by a. Use with caution!

Options: :uplo (upper or :lower), and :diag (:unit or :non-unit).

(view-ge (tr float-factory 3 (range 6)))

view-vctr

(view-vctr a)(view-vctr a stride-mult)

Attach a dense vector to the raw data of x, with optional stride multiplicator stride-mult.

Changes to the resulting object affect the source x, even the parts of data that might not be accessible by x. Use with caution!

(view-vctr (ge float-factory 2 3 (range 6)))

xpy

(xpy x y)(xpy x y & zs)

Sums vectors or matrices x, y, and zs. The result is a new instance. See axpy! and axpy.

zero

(zero x)(zero factory x)

Returns an instance of the same type and dimension(s) as the x, initialized with 0.