READMEorg[edit on web]

Numcl https://travis-ci.org/numcl/numcl.svg?branch=master

This is a Numpy clone in Common Lisp. At the moment the library is written in pure Common Lisp, focusing more on correctness and usefulness, not speed.

NEWS

  • 2020/2/26 version 0.2.0 is released!
  • 2020/2/29 matmul* : multi-argument version of matmul is added. It optimizes the multiplication order in order to reduce the runtime / memory.
  • 2020/3/30 Refactored the type inference framework using float infiny / NaNs.
  • 2020/6/29 Minor incompatibility: LOG, LOG2 always return real arrays. Use LOGC instead for the original behavior.

Quick tutorial

In order to guarantee the speed and to simplify the implementation, the arrays given to numcl functions must satisfy the following two conditions:

  • It is a specialized array. Things of type (array single-float), (array (unsigned-byte 16)) etc.
  • It is an array displaced to a simple 1D specialized array. "Simple array" means a non-displaced, non-adjustable array without fill pointer.

This means you cannot directly feed the arrays such as #2A((0.0 1.0) (2.0 3.0)), which is an array of type (simple-array T).

There are two ways to create an array similar to what you have and is compatible to numcl:

  • (reshape (arange 4.0) '(2 2))
  • (asarray #2A((0.0 1.0) (2.0 3.0)))
    • or (asarray '((0.0 1.0) (2.0 3.0)))
    • or (asarray '(#(0.0 1.0) #(2.0 3.0))).
  • (let ((a (zeros '(2 2) :type 'single-float))) (dotimes (i 2) (dotimes (j 2) (setf (aref a i j) ...)))).

The names and the parameters of numcl functions mostly (rather strictly) follows the numpy counterpart. There are even numpy names, such as dtype, which are just aliases for array-element-type.

Goals

  • Closely follow the numpy API, but still make it lispy.
    • Delegate the documentation effort to Numpy community.
  • Replace the Common Lisp array interface.
    • We do not deviate from the traditional symbols/idioms in Common Lisp unless necessary. Therefore we provide symbols that conflicts the Common Lisp symbol. Math functions become aliases to the original CL functions when the inputs are not arrays.
    • See doc/DETAILS.org#packages .

Features/Contracts

  • APIs are provided as functions, not macros.
    • It is a design flaw otherwise.
    • This does not mean the API is functional — we use procedural code.
  • Still, zero overhead.
    • The APIs are simply the wrappers over simple functions and designed to be fully inlined.
    • Optimization will be done on the compiler side, not by macros.
  • Operations are type-correct.
    • They always return arrays of the most specific array-element-type. For example,
    • (zeros 5) returns a bit vector.
    • (asarray '(1 2 3)) returns an (unsigned-byte 2) vector.
    • See doc/DETAILS.org#types .
  • NUMCL Arrays are CL arrays.
    • As this library aims to extend Common Lisp (not to replace part of it) in a compatible way, we do not introduce custom structures/classes for representing an array.
    • See doc/DETAILS.org#representation .

Dependencies

This library is at least tested on implementation listed below:

  • SBCL 1.4.12 on X86-64 Linux 4.4.0-141-generic (author's environment)
  • SBCL 1.5.1 on X86-64 Linux 4.4.0-141-generic (author's environment)
  • SBCL 2.0.1 on X86-64 Ubuntu 16.04.6 LTS Linux 4.15.0-1028-gcp
  • ccl-1.11.5 on X86-64 Ubuntu 16.04.6 LTS Linux 4.15.0-1028-gcp
  • SBCL 2.0.1 on X86-64 Mac OS X 10.13.6
  • ccl-1.11.5 on X86-64 Mac OS X 10.13.6
  • SBCL 2.0.0 on X86-64 Windows Server, version 1809
  • SBCL 2.0.0 on Arm64 Ubuntu 16.04.6 LTS Linux 5.3.0-19-generic
  • SBCL 1.5.8 on ppc64le Ubuntu 16.04.6 LTS Linux 5.0.0-37-generic

Dependency graph:

Masataro Asai (guicho2.71828@gmail.com)

Licensed under LGPL v3.

Copyright (c) 2019 IBM Corporation

doc

DETAILSorg[edit on web]

In this document, we detail the inner working of NUMCL.

Packages

NUMCL defines several symbols which have the same name as the corresponding CL symbols. We call them conflicting symbols. To avoid the confusion in the code base, we use 3 packages:

  • NUMCL.IMPL (internal package) for implementing numcl.
  • NUMCL.EXPORTED (external package), for storing the numcl exported symbols,
  • NUMCL package, that replaces COMMON-LISP package by shadowing-import symbols from NUMCL.EXPORTED on top of COMMON-LISP package.

Types

Common Lisp has the following types for numbers.

number = (or complex real)
real   = (or float rational)
rational = (or ratio integer)
integer  = (or fixnum bignum)
float    = (or short-float ... long-float) (== irrational).

Common Lisp defines several rules for the type of the values returned by the numerical operations. The detail of the rules are explained in CLHS 12.1 Number Concepts.

Rational functions behave as rational* -> rational, float* -> float, {rational,float}* -> float. This rule is called float contagion rule.

Rational functions do not guarantee integer -> integer, primarily due to / , which returns integer* -> (or ratio integer).

Irrational functions behaves as rational -> (or rational float), float -> float: For a certain irrational functions, implementations are allowed to return the exact rational number or its float approximation. Examples are (sin pi) -> 1/2. The behavior depends on the implementation and is called float substitution rule.

In NUMCL, ratio does not exist due to three reasons: First, CL prohibits ratio to have a denominator 1 (e.g. 3/1), and thus the operations on ratios are not closed. Second, no implementations provide a specialized array for rational. Finally, ratio computation requires an additional simplification phase (e.g. 2/4 -> 1/2) which does not finish in a constant number of operations and is incompatible to SIMD operations.

As a result, ratios are always converted to *numcl-default-float-format*, which is single-float by default. This means that / always returns a float array (except atomic numbers are given).

We also force irrational functions to always return floats, by coercion. (Implementations are allowed to return rationals for certain constants, e.g. (sin pi).)

(array bignum) does not exist either. However, when the result of numerical computation causes a fixnum overflow, it signals an error instead of overflowing silently.

For complex arrays, only (complex *-float) exists (for each float type). Both complex integers and complex ratios are converted into floats. This is because CL does not allow rational complex with imagpart 0 (cf. http://clhs.lisp.se/Body/t_comple.htm), thus the numerical operation always coerces the result into reals. This prevents us from having (ARRAY (COMPLEX FIXNUM)).

Representation

NUMCL arrays are not based on custom classes or structures. They are merely the displaced multidimentional arrays.

In order to guarantee the speed and to simplify the implementation, the arrays given to numcl functions must satisfy the following two conditions:

  • It is a specialized array. Things of type (array single-float), (array (unsigned-byte 16)) etc.
  • It is an array displaced to a simple 1D specialized array. "Simple array" means a non-displaced, non-adjustable array without fill pointer.

The base function for creating a new array is %make-array, but this is not exported in NUMCL. You should use the wrapper functions like ones, zeros, ones-like, arange, linspace, asarray etc. They are always inline-expanded to %make-array, therefore there is no worry about the performance. These functions analyze the input and return the most specialized array for the input, but you can also specify the element type.

%make-array instantiates a new flattened array and returns another array displaced to it with the specified shape. The flattened array is returned as the secondary value (as does most other numcl functions).

The justification for this scheme is that some implementations (esp. SBCL) require an indirection for accessing the array element (e.g. through array-header in SBCL) even for a simple multi-dimentional array and thus using a displacing array has essentially no performance penalty over using a simple multi-dimentional array.

We also ensure that the length of the base arrays are the multiples of 8. This ensures that the program can safely iterate over the extended region with a future support for SIMD operations in mind.

src

0packagelisp[edit on web]

defpackage
numcl.exported

External package for storing the exported symbols.

define-package
numcl.impl

Internal package for implementing numcl.

define-package
numcl

NUMCL defines several symbols which have the same name as the corresponding CL symbols. We call them conflicting symbols. To avoid the confusion in the code base, we use 3 packages: NUMCL.EXPORTED, NUMCL.IMPL, NUMCL.

This package replaces COMMON-LISP package by shadowing-import symbols from NUMCL.EXPORTED on top of COMMON-LISP package.

1versionlisp[edit on web]

defun
numcl-version

Returns a string that represents the version of NUMCL currently installed.

1constantfoldedlisp[edit on web]

define-foldable-version
make-arrayvectorbit-andbit-andc1bit-andc2bit-eqvbit-iorbit-nandbit-norbit-notbit-orc1bit-orc2bit-xormapcarconsadjoinappendaconspairlissublislistlist*make-listmaplistsubstsubst-ifsubst-if-notintersectionset-differenceset-exclusive-orunionldiffmake-sequencesubseqconcatenatemapreducereverseremoveremove-duplicatesremove-ifremove-if-notsubstitutesubstitute-ifsubstitute-if-notmake-stringstringstring-capitalizestring-downcasestring-left-trimstring-right-trimstring-trimstring-upcase
common-lisp

(documentation missing)

1typelisp[edit on web]

defun
numcl-array-p
array

Returns true when ARRAY satisfies the NUMCL assumption, that is, an array displaced to a non-displaced 1D array.

deftype
numcl-array
&optional element-type dimensions

Type specifier for the arrays satifying the NUMCL assumption, that is, an array displaced to a non-displaced 1D array.

deftype
*

(documentation missing)

2aliaslisp[edit on web]

defun
shapesizerankdtypelength
numcl.exportedarray

(documentation missing)

defun
to-simple-array
array

Returns a simple array of the equivalent contents.

defun
reshape
a shape

Reshape the array while sharing the backing 1D array. -1 implies that the axis size is deduced from the other axes. At most one axis is allowed to be -1. T implies that the axis size is preserved. It can be used as many times, but only at the right/leftmost axes.

Example of reshaping (3 8 5):

valid:

(6 -1 10)     = (6 2 10)
(t 2 2 2 t)   = (3 2 2 2 5)
(3 t t)       = (3 8 5)
(2 -1 2 2 t)  = (2 3 2 2 5)

invalid:

(2 t 2 2 t)

defun
flattensqueeze
numcl.exporteda

(documentation missing)

defun
expand-dims
a axes

axes: an int or a list of ints

2areflisp[edit on web]

define-condition
invalid-array-index-error

(documentation missing)

defun
aref
array &rest subscripts

An extended aref that accepts ranges as lists, similar to numpy's array access. For a 3D array x,

  • range
x[1:5,2,3]   = (aref x '(1 5) 2 3)
x[2,1:5,3]   = (aref x 2 '(1 5) 3)
x[2,1:2:5,3] = (aref x 2 '(1 2 5) 3)
x[2,1:,3]    = (aref x 2 '(1 t) 3)
x[2,:1,3]    = (aref x 2 '(t 1) 3)
x[2,:,3]     = (aref x 2 '(t t) 3)
x[2,:,3]     = (aref x 2    t   3)
  • insufficient axis
(aref x '(1 5)) == (aref x '(1 5) t t)
(aref x 2 '(1 5)) == (aref x 2 '(1 5) t)
  • newaxis
(aref x '(1 2 5) nil 2 3)
  • ellipsis
(aref x '- 2) = (aref x t t 2) = x[...,2]
(aref x 2 '-) = (aref x 2 t t) = x[2,...]
(aref x 2 '- 3) = (aref x 2 t 3) = x[2,...,3]
(aref x 2 3 '-) = (aref x 2 3 t) = x[2,3,...]

2typeinferlisp[edit on web]

defmethod
documentation
(x symbol) (type (eql 'inferer))

(documentation missing)

3arangelisp[edit on web]

defun
arange
&rest args

Arange's argument signature is irregular, following the API of numpy. The interpretation of its arguments depends on the number of arguments.

(arange stop &key type) (arange start stop &key type) (arange start stop step &key type)

Don't worry, we provide a compiler-macro to avoid the runtime dispatch.

define-compiler-macro
arange
&rest args

defun
linspace
start stop length &key type endpoint

(all documentation missing)

3arraylisp[edit on web]

defun
asarray
contents &key type

Note: ASARRAY is SLOW as it recurses into the substructures.

Copy CONTENTS to a new array. When CONTENTS is a multidimentional array, its elements are copied to a new array that guarantees the NUMCL assumption. When CONTENTS is a nested sequence, it is traversed up to the depth that guarantees the sane shape for an array. When elements are copied, it is coerced to TYPE. When TYPE is not given, it is replaced with the float-contagion type deduced from the elements of CONTENTS. It may return a 0-dimensional array with CONTENTS being the only element.

For example:

;; a vector of two lists.
(asarray '((1) (1 2)))               -> #((1) (1 2))
;; a 2D array of 4 lists.
(asarray '(((1) (1 2)) ((3) (3 4)))) -> #2A(((1) (1 2)) ((3) (3 4)))

(asarray '((1 2) (3 4)))    -> #2A((1 2) (3 4))
(asarray #(#(1 2) #(3 4)))  -> #2A((1 2) (3 4))
(asarray #((1 2) (3 4)))    -> #2A((1 2) (3 4))

However, this behavior may not be ideal because the resulting shape could be affected by the lengths of the strings.

(asarray #(#(1 2) #(3 4)))   -> #2A((1 2) (3 4))
(asarray #(#(1 2) #(3 4 5))) -> #(#(1 2) #(3 4 5))

(asarray #("aa" "aa"))   -> #2A((#a #a) (#a #a))
(asarray #("aa" "aaa"))  -> #("aa" "aaa")

As a remedy to this problem, we allow TYPE to be a specifier for vector subtypes. Providing such a type specifier will keep the leaf objects (e.g. strings) from split into individual elements. We don't allow it to be a multidimentional array [at the moment.]

(asarray #(#(1 2) #(3 4))   :type '(array fixnum (*))) -> #(#(1 2) #(3 4))
(asarray #(#(1 2) #(3 4 5)) :type '(array fixnum (*))) -> #(#(1 2) #(3 4 5))

(asarray #("aa" "aa")  :type 'string)    -> #("aa" "aa")
(asarray #("aa" "aaa") :type 'string)    -> #("aa" "aaa")

(asarray '((1 2) (3 4))   :type '(array fixnum (* *)))  -> error

3copylisp[edit on web]

defun
copy
array

defun
astype
array type

(all documentation missing)

3einsumlisp[edit on web]

defun
einsum
subscripts &rest args

Note: Broadcasting with EINSUM is experimental.

Performs Einstein's summation. The SUBSCRIPT specification is significantly extended from that of Numpy and can be seens as a full-brown DSL for array operations.

SUBSCRIPTS is a sequence of the form (<ISPEC>+ [-> <TRANSFORM>*] [-> <OSPEC>*] [-> <IOPTION>*] [-> <OOPTION>*]). The remaining arguments ARGS contain the input arrays and optionally the output arrays.

Inputs are interpreted in the following rule, depending on the number of arrows.

 (<ISPEC>+)
 (<ISPEC>+ -> <OSPEC>*)
 (<ISPEC>+ -> <TRANSFORM>* -> <OSPEC>*)
 (<ISPEC>+ -> <TRANSFORM>* -> <OSPEC>* -> <IOPTION>*)
 (<ISPEC>+ -> <TRANSFORM>* -> <OSPEC>* -> <IOPTION>* -> <OOPTION>*)

SPEC

The first set of SPECs specifies the input subscripts, and the second set of SPECs specifies the output subscripts. Unlike Numpy, there can be multiple output subscripts: It can performs multiple operations in the same loop, then return multiple values. The symbol -> can be a string and can belong to any package because it is compared by STRING=.

Each SPEC is an string designator, such as a symbol IJK or a string "IJK", where each character is considered as an index. Broadcasting can be specified by a hyphen. It signals a type-error when it contains any non-alpha char except hyphens (-). Note that a symbol NIL is interpreted as an empty list rather than N, I and L. Once broadcasting is used in one input, it must be used in all inputs/outputs.

Alternatively, each SPEC can be a list that contains a list of symbols. For example, ((i j) (j k) -> (i k)) and (ij jk -> ik) are equivalent.

When -> and the output SPECs are omitted, a single output is assumed and its spec is a union of the input specs. For example, (ij jk) is equivalent to (ij jk -> ijk). Note that (ij jk) and (ij jk ->) have the different meanings: The latter sums up all elements.

TRANSFORM

TRANSFORM is a list of element-wise operations. The number of TRANSFORM should correspond to the number of outputs. In each TRANSFORM, the elements in the input arrays can be referenced by $N, where N is a 1-indexed number. Similarly the output array can be referred to by @N.

  • Example: (ij ik -> (+ @1 (* $1 $2)) -> ik) is equivalent to (ij ik -> ik) (a GEMM).
  • Example: (i -> (sin $1) -> i) is equivalent to mapping a sin function to an array.

By default, TRANSFORM is (+ @1 (* $1 ... $N)) for N inputs, which is equivalent to Einstein's summation.

OPTION

Each OPTION is a list of iteration specifiers. Iteration specifier is a form (index &key (start 0) (end -1) (step 1)). START and END are the forms specifying the interval designator of the loop range, which supersedes the default full-width loop. STEP is a form specifying the increment of the index. INDEX is a symbol which should match one of the subscripts used in one of the SPEC.

For example, you can specify

 (einsum '(ij jk -> (+ @1 (* $1 $2)) -> ik -> ((j :step 2)) ((j :step 3)))
         (ones '(5 10))
         (ones '(15 5)))

to suggest that the index j for the first array should have a stride of 2, and the index j for the second array should have a stride of 3.

This is fairly complex, but we hope to provide the maximum flexibility.

ARGS

The shape of each input array should unify against the corresponding input spec. For example, with a spec IJI, the input array should be of rank 3 as well as the 1st and the 3rd dimension of the input array should be the same. Note that this is affected by OPTIONS --- when specified, it uses the number of iteration instead of the size of the dimension.

The shape of each output array is determined by the corresponding output spec. For example, if SUBSCRIPTS is (ij jk -> ik) and the input arrays are NxM and MxL matrices, the output has a shape NxL.

If the output arrays are provided, their shapes and types are also checked against the corresponding output spec. The types should match the result of the numerical operations on the elements of the input arrays.

The outputs are calculated in the following rule.

  • The output array types are calculated based on the TRANSFORM, and the shapes are calcurated based on the SPEC and the input arrays.

  • The output arrays are allocated and initialized by zeros.

  • Einsum nests one loop for each index in the input specs. For example, (ij jk -> ik) results in a triple loop.

  • In the innermost loop, each array element is bound to $1..$N / @1..@N.

  • For each @i, i-th transform is evaluated and assigned to @i.

  • If the same index appears multiple times in a single spec, they share the same value in each iteration. For example, (ii -> i) returns the diagonal elements of the matrix.

When TRANSFORMs are missing, it follows naturally from the default TRANSFORM values that

  • When an index used in the input spec is missing in the output spec, the axis is aggregated over the iteration by summation.
  • If the same index appears across the different input specs, the element values from the multiple input arrays are aggregated by multiplication. For example, (ij jk -> ik) will perform (setf (aref a2 i k) (* (aref a0 i j) (aref a1 j k))) when a0, a1 are the input arrays and a2 is the output array.

For example, (einsum '(ij jk) a b) is equivalent to:

 (dotimes (i <max> <output>)
   (dotimes (j <max>)
     (dotimes (k <max>)
       (setf (aref <output> i j k) (* (aref a i j) (aref b j k))))))

Performance

If SUBSCRIPTS is a constant, the compiler macro builds an iterator function and make them inlined. Otherwise, a new function is made in each call to einsum, resulting in a large bottleneck. (It could be memoized in the future.)

The nesting order of the loops are automatically decided based on the specs. The order affects the memory access pattern and therefore the performance due to the access locality. For example, when writing a GEMM which accesses three matrices by (setf (aref output i j) (* (aref a i k) (aref b k j))), it is well known that ikj-loop is the fastest among other loops, e.g. ijk-loop. EINSUM reorders the indices so that it maximizes the cache locality.

define-compiler-macro
einsum
subscripts &rest args

(documentation missing)

3zeroslisp[edit on web]

defun
empty
shape &key (type 'bit)

defun
full
shape value &key (type (type-of value))

defun
zerosones
numcl.exportedshape &key (type 'bit)

defun
empty-like
array &key (type (array-element-type array))

defun
full-like
array value &key (type (array-element-type array))

defun
zeros-likeones-like
numcl.exportedarray &key (type (array-element-type array))

Equivalent of the same function in numpy. Note the default type difference.

  • empty : does not explicitly fill the array. In an unsafe compiler setting, junk value may appear.
  • full : fill the array with a certain value.
  • zeros, ones : fill the array with zeros / ones. type affects the actual value being filled.
  • X-like : similar to above functions, but takes another array and returns the array of the same shape.

4concatenatelisp[edit on web]

defun
concatenatestack
numcl.exportedarrays &key (axis 0) out

defun
unstack
array &key (axis 0)

(all documentation missing)

4linear-algebra2lisp[edit on web]

defundefine-compiler-macro
transpose
numcl.exportedmatrix &optional result

Reverses the axes of an array.

defundefine-compiler-macro
matmul
numcl.exporteda b &optional result

Matrix product of two arrays.

defundefine-compiler-macro
vdot
numcl.exporteda b &optional result

Dot product of two vectors. For complex values, the first value is conjugated.

defundefine-compiler-macro
inner
numcl.exporteda b &optional result

Inner product of two vectors.

defundefine-compiler-macro
outer
numcl.exporteda b &optional result

Compute the outer product of two vectors.

defundefine-compiler-macro
kron
numcl.exporteda b &optional result

Compute the kronecker product of two vectors.

defundefine-compiler-macro
diag
numcl.exporteda &optional result

Return the diagonal element of a matrix as a vector

defundefine-compiler-macro
tri
numcl.exportedn &key (m n) (k 0) (type 'bit)

Returns a triangle matrix whose lower diagnonal (including the diagonal) filled with 1. N,M specifies the shape of the return array. K will adjust the sub-diagonal -- positive K fills more 1s.

defundefine-compiler-macro
tril
numcl.exportedmatrix &optional (k 0)

Returns the copy of matrix with elements above the k-th diagonal zeroed. Positive K fills less 0s.

defundefine-compiler-macro
triu
numcl.exportedmatrix &optional (k 0)

Returns the copy of matrix with elements below the k-th diagonal zeroed. Positive K fills more 0s.

defundefine-compiler-macro
eye
numcl.exportedn &key (m n) (k 0) (type 'bit)

Returns a matrix whose k-th diagnonal filled with 1. N,M specifies the shape of the return array. K will adjust the sub-diagonal -- positive K moves it upward.

defundefine-compiler-macro
vander
numcl.exportedv &key (n (length v)) increasing

Returns a matrix where M[i,j] == V[i]^(N-j) when increasing is false (default), and M[i,j] == V[i]^j when increasing is true.

4linear-algebra3lisp[edit on web]

define-compiler-macro
matmul*
&rest args

(documentation missing)

defun
matmul*
&rest args

Takes an arbitrary number of matrices and performs multiplication, optimizing the order using the shape information and the associativity to minimize the size of the intermediate matrix.

5numericlisp[edit on web]

defundefine-compiler-macro
map-array-into
numcl.exportedresult-sequence function &rest sequences

defun
map-into
result-sequence function &rest sequences

defun
map
result-type function &rest sequences

defun
map-array
function &rest sequences

(all documentation missing)

defundefine-compiler-macro
broadcast
numcl.exportedfunction x y &key type (atomic function)

For binary functions

define-simple-mapper
sqrt

defun
sqrt
x

define-simple-mapper
isqrt

defun
isqrt
x

define-simple-mapper
sin

defun
sin
x

define-simple-mapper
cos

defun
cos
x

define-simple-mapper
tan

defun
tan
x

define-simple-mapper
asin

defun
asin
x

define-simple-mapper
acos

defun
acos
x

define-simple-mapper
atan

defun
atan
x

define-simple-mapper
sinh

defun
sinh
x

define-simple-mapper
cosh

defun
cosh
x

define-simple-mapper
tanh

defun
tanh
x

define-simple-mapper
asinh

defun
asinh
x

define-simple-mapper
acosh

defun
acosh
x

define-simple-mapper
atanh

defun
atanh
x

define-simple-mapper
exp

defun
exp
x

define-simple-mapper
abs

defun
abs
x

define-simple-mapper
signum

defun
signum
x

define-simple-mapper
cis

defun
cis
x

define-simple-mapper
conjugate

defun
conjugate
x

define-simple-mapper
phase

defun
phase
x

define-simple-mapper
realpart

defun
realpart
x

define-simple-mapper
imagpart

defun
imagpart
x

define-simple-mapper
numerator

defun
numerator
x

define-simple-mapper
denominator

defun
denominator
x

define-simple-mapper
logcount

defun
logcount
x

define-simple-mapper
integer-length

defun
integer-length
x

(all documentation missing)

define-simple-mapper
square

defun
square
x

Square function f(x)= x * x.

define-simple-mapper
log

defun
log
x

Logarithmic function. Unlike Common Lisp LOG, it assumes that the input is a positive real, in favor of efficiency. Another reason is that most Common Lisp implementations do not have specialized arrays for positive-only / negative-only floats, thus the runtime type inference cannot deduce whether the resulting array element type have to be a complex or a real.

define-simple-mapper
logc

defun
logc
x

Logarithmic function. This function behaves exactly like Common Lisp LOG. Unless it can be proven from the input array element type, such as the input being a specialized array of unsigned-int, it takes a conservative approach, i.e., it returns arrays specialized to the complex numbers.

define-simple-mapper
log2

defun
log2
x

Logarithm of base 2.

defun
1+1-
numcl.exportedarray

defun
+*maxmin
numcl.exported&rest args

defun
expt
base power

defun
-/
numcl.exportedfirst &rest args

defun
clip
array min max

define-symbol-macro
++++++******//////
numcl.exported

defun
modremroundfloorceilingtruncatefroundffloorfceilingftruncate
numcl.exportednumber &optional (divisor 1)

defun
=/=<=>=<>
numcl.exportedx y &rest more

defpattern
=/=<=>=<>
numcl.exportedx

defun
logandlogandc1logandc2logeqvlogiorlognandlognorlogorc1logorc2logxor
numcl.exported&rest args

define-simple-mapper
lognot

defun
lognot
x

(all documentation missing)

5randomlisp[edit on web]

defun
shuffle
array-or-sequence &key (start 0) end

This code extends alexandria:shuffle. It additionally accepts arrays and shuffles the elements according to the first axis, viewing the remaining axes as one "element".

Original documentation:

Returns a random permutation of SEQUENCE bounded by START and END. Original sequence may be destructively modified, and (if it contains CONS or lists themselv) share storage with the original one. Signals an error if SEQUENCE is not a proper sequence.

defun
bernoulli
p &optional shape

Returns a bit array whose elements are 1 with probability P

defun
bernoulli-like
a

defun
beta
a b &optional shape (type (union-to-float-type (type-of a) (type-of b)))

defun
binomial
n p &optional shape

defun
exponential
scale &optional shape (type (union-to-float-type (type-of scale)))

defun
f
dfnum dfden &optional shape (type (union-to-float-type (type-of dfnum) (type-of dfden)))

defun
gamma
k &optional (theta 1.0) shape (type (union-to-float-type (type-of k) (type-of theta)))

(all documentation missing)

defun
multinomial
n pvals &optional shape

pvals is a sequence of probabilities summing up to 1.

defun
negative-binomial
n p &optional shape

defun
normal
&optional (mean 0.0) (var 1.0) shape (type (union-to-float-type (type-of mean) (type-of var)))

defun
poisson
&optional (lambda 1.0) shape (type (union-to-float-type (type-of lambda)))

defun
uniform
&optional (low 0.0) (high 1.0) shape type

(all documentation missing)

5reducelisp[edit on web]

defun
reduce-array
fn array &key axes (type (%reduce-array-result-type array fn)) (initial-element (zero-value type))

defun
sumprodamaxamin
numcl.exportedarray &rest args &key axes type

defun
meanvariancestandard-deviationavgvarstdev
numcl.exportedarray &key axes

(all documentation missing)

defun
histogram
array &key (low (amin array)) (high (amax array)) (split 1)

Returns a fixnum vector representing a histogram of values. The interval between LOW and HIGH are split by STEP value. All values less than LOW are put in the 0-th bucket; All values greater than equal to HIGH are put in the last bucket.

5wherelisp[edit on web]

defun
array-index-from-row-major-index
array row-major-index

Takes a multidimentional array and a row-major-index. Returns a list containing the normal index.

defun
argwhere
array fn

Returns a list of the multidimentional indices of the elements which satisfies the predicate FN. Note that the list elements are the multidimentional indices, even for a single-dimensional array.

defun
where
array fn

Returns a list of list of indices of the elements which satisfies the predicate FN. The first list contains the indices for the 1st dimension, the second list contains the indices for the 2nd dimension, and so on.

defun
nonzero
array

collect multidimentional indices where the element is nonzero

defun
take
array indices

Collect the elements using a list of multidimentional indices (in a format returned by WHERE).