- blas
- Documentation
- Naming conventions for routines
- Vector copy routines
- BLAS level 1 routines
- Conventions
- Apply plane rotation
- Scale vector
- Swap the elements of two vectors
- Real vector dot product
- Complex vector dot product
- Hermitian vector dot product
- Vector multiply-add
- Vector multiply-add with optional offset
- Euclidean norm of a vector
- Sum of absolute values of the elements in a vector
- Sum of absolute values of the elements in a vector

- BLAS level 2 routines
- Conventions
- General matrix-vector multiply-add
- Banded matrix-vector multiply-add
- Hermitian matrix-vector multiply-add
- Hermitian banded matrix-vector multiply-add
- Symmetric matrix-vector multiply-add
- Banded symmetric matrix-vector multiply-add
- Triangular matrix-vector multiply-add
- Banded triangular matrix-vector multiply-add
- Triangular matrix equation solve
- Banded triangular matrix equation solve
- Rank 1 operation
- Rank 1 operation with optional offset
- Rank 1 operation on complex matrices and vectors
- Rank 1 operation on complex matrices and vectors
- Hermitian rank 1 operation
- Hermitian rank 2 operation
- Symmetric rank 1 operation
- Symmetric rank 2 operation

- BLAS level 3 routines

- Examples
- About this egg

## blas

An interface to level 1, 2 and 3 BLAS linear algebra routines.

## Documentation

### Naming conventions for routines

Every routine in the BLAS library comes in four flavors, each prefixed by the letters S, D, C, and Z, respectively. Each letter indicates the format of input data:

- S stands for single-precision (32-bit IEEE floating point numbers),
- D stands for double-precision (64-bit IEEE floating point numbers),
- C stands for complex numbers (represented by pairs of 32-bit IEEE floating point numbers),
- Z stands for double complex numbers (represented by pairs of 64-bit IEEE floating point numbers)

In addition, each BLAS routine in this egg comes in three flavors:

- Safe, pure

*Safe* routines check the sizes of their input arguments. For example, if a routine is supplied arguments that indicate that an input matrix is of dimensions *M*-by-*N*, then the argument corresponding to that matrix is checked that it is of size *M * N*.

*Pure* routines do not alter their arguments in any way. A new matrix or vector is allocated for the return value of the routine.

- Safe, destructive (suffix: !)

*Safe* routines check the sizes of their input arguments. For example, if a routine is supplied arguments that indicate that an input matrix is of dimensions *M*-by-*N*, then the argument corresponding to that matrix is checked that it is of size *M * N*.

*Destructive* routines can modify some or all of their arguments. They are given names ending in exclamation mark. Please consult the BLAS documentation to determine which functions modify their input arguments.

- Unsafe, destructive (prefix:
**unsafe-**, suffix: !)

*Unsafe* routines do not check the sizes of their input arguments. They invoke the corresponding BLAS routines directly. Unsafe routines do not have pure variants.

For example, function *xGEMM* (matrix-matrix multiplication) comes in the following variants:

BLAS name |
Safe, pure |
Safe, destructive |
Unsafe, destructive |
---|---|---|---|

SGEMM |
sgemm |
sgemm! |
unsafe-sgemm! |

DGEMM |
dgemm |
dgemm! |
unsafe-dgemm! |

CGEMM |
cgemm |
cgemm! |
unsafe-cgemm! |

ZGEMM |
zgemm |
zgemm! |
unsafe-zgemm! |

### Vector copy routines

*[procedure]*

`scopy:: F32VECTOR -> F32VECTOR`

*[procedure]*

`dcopy:: F64VECTOR -> F64VECTOR`

*[procedure]*

`ccopy:: F32VECTOR -> F32VECTOR`

*[procedure]*

`zcopy:: F64VECTOR -> F64VECTOR`

These procedures return a copy of given input SRFI-4 vector. The returned vector is allocated with the corresponding SRFI-4 constructor, and the input vector is copied to it by the corresponding BLAS copy procedure.

### BLAS level 1 routines

#### Conventions

The BLAS level 1 procedures in this egg differ from the actual routines they invoke by the position of the vector increment arguments (`INCX` and `INCY`). In this egg, these arguments are optional; the default value of `INCX` and `INCY` is 1.

In the procedure signatures below, these optional arguments are indicated by [ and ] (square brackets).

#### Apply plane rotation

*[procedure]*

`srot:: N * X * Y * C * S [INCX * INCY] -> F32VECTOR * F32VECTOR`

*[procedure]*

`drot:: N * X * Y * C * S [INCX * INCY] -> F64VECTOR * F64VECTOR`

`xROT` applies a plane rotation matrix to a sequence of ordered pairs: `(x_i , y_i)`, for `i = 1, 2, ..., n`.

`X` and `Y` are vector of dimensions `(N-1) * abs(incx) + 1` and `(N-1) * abs(incy) + 1`, respectively.

`C` and `S` are respectively the cosine and sine of the plane of rotation.

#### Scale vector

*[procedure]*

`sscal:: N * ALPHA * X [INCX] -> F32VECTOR`

*[procedure]*

`dscal:: N * ALPHA * X [INCX] -> F64VECTOR`

*[procedure]*

`cscal:: N * ALPHA * X [INCX] -> F32VECTOR`

*[procedure]*

`zscal:: N * ALPHA * X [INCX] -> F64VECTOR`

`xSCAL` scales a vector with a scalar: `x := alpha * x`.

#### Swap the elements of two vectors

*[procedure]*

`sswap:: N * X * Y [INCX * INCY] -> F32VECTOR`

*[procedure]*

`dswap:: N * X * Y [INCX * INCY] -> F64VECTOR`

*[procedure]*

`cswap:: N * X * Y [INCX * INCY] -> F32VECTOR`

*[procedure]*

`zswap:: N * X * Y [INCX * INCY] -> F64VECTOR`

`xSWAP` interchanges the elements of two vectors: `x <-> y`.

#### Real vector dot product

*[procedure]*

`sdot:: N * X * Y [INCX * INCY] -> NUMBER`

*[procedure]*

`ddot:: N * X * Y [INCX * INCY] -> NUMBER`

`xDOT` computes the dot product of two vectors of real values: `dot := x'*y = \Sum_{i=1}^{n} (x_i * y_i)`.

#### Complex vector dot product

*[procedure]*

`cdotu:: N * X * Y [INCX * INCY] -> NUMBER`

*[procedure]*

`zdotu:: N * X * Y [INCX * INCY] -> NUMBER`

`xDOTU` computes the dot product of two vectors of complex values: `dotu := x'*y = \Sum_{i=1}^{n} (x_i * y_i)`.

#### Hermitian vector dot product

*[procedure]*

`cdotc:: N * X * Y [INCX * INCY] -> NUMBER`

*[procedure]*

`zdotc:: N * X * Y [INCX * INCY] -> NUMBER`

`xDOTC` computes the dot product of the conjugates of two complex vectors: `dotu := conjg(x')*y = \Sum_{i=1}^{n} (conjg(x_i) * y_i)`, for `i = 1, 2, ..., n`.

#### Vector multiply-add

*[procedure]*

`saxpy:: N * ALPHA * X * Y [INCX * INCY] -> F32VECTOR`

*[procedure]*

`daxpy:: N * ALPHA * X * Y [INCX * INCY] -> F64VECTOR`

*[procedure]*

`caxpy:: N * ALPHA * X * Y [INCX * INCY] -> F32VECTOR`

*[procedure]*

`zaxpy:: N * ALPHA * X * Y [INCX * INCY] -> F64VECTOR`

`xAXPY` adds a scalar multiple of a vector to another vector: `y := alpha * x + y`.

#### Vector multiply-add with optional offset

*[procedure]*

`siaxpy:: N * ALPHA * X * Y [INCX * INCY * XOFS * YOFS] -> F32VECTOR`

*[procedure]*

`diaxpy:: N * ALPHA * X * Y [INCX * INCY * XOFS * YOFS] -> F64VECTOR`

*[procedure]*

`ciaxpy:: N * ALPHA * X * Y [INCX * INCY * XOFS * YOFS] -> F32VECTOR`

*[procedure]*

`ziaxpy:: N * ALPHA * X * Y [INCX * INCY * XOFS * YOFS] -> F64VECTOR`

`xIAXPY` adds a scalar multiple of a vector to another vector, where the beginning of each vector argument can be offset: `y[yofs:n] := alpha * x[xofs:n] + y[yofs:n]`.

#### Euclidean norm of a vector

*[procedure]*

`snrm2:: N * X [INCX] -> NUMBER`

*[procedure]*

`dnrm2:: N * X [INCX] -> NUMBER`

*[procedure]*

`cnrm2:: N * X [INCX] -> NUMBER`

*[procedure]*

`znrm2:: N * X [INCX] -> NUMBER`

`xNRM2` computes the Euclidean (L2) norm of a vector.

#### Sum of absolute values of the elements in a vector

*[procedure]*

`sasum:: N * X [INCX] -> NUMBER`

*[procedure]*

`dasum:: N * X [INCX] -> NUMBER`

*[procedure]*

`casum:: N * X [INCX] -> NUMBER`

*[procedure]*

`zasum:: N * X [INCX] -> NUMBER`

`xASUM` sums the absolute values of the elements in a vector.

#### Sum of absolute values of the elements in a vector

*[procedure]*

`samax:: N * X [INCX] -> INDEX`

*[procedure]*

`damax:: N * X [INCX] -> INDEX`

*[procedure]*

`camax:: N * X [INCX] -> INDEX`

*[procedure]*

`zamax:: N * X [INCX] -> INDEX`

`xAMAX` searches a vector for the first occurrence of its maximum absolute value, and returns the index of that element.

### BLAS level 2 routines

#### Conventions

The BLAS level 2 procedures in this egg differ from the actual routines they invoke by the position of the leading dimension argument (`LDA`) and the vector increment arguments (`INCX` and `INCY`). In this egg, these arguments are optional; the default value of `LDA`is the largest matrix dimension, depending on the semantics of the respective operation, and the default value of `INCX` and `INCY` is 1.

In the procedure signatures below, these optional arguments are indicated by [ and ] (square brackets).

Argument `ORDER` is one of `RowMajor` or `ColMajor` to indicate that the input and output matrices are in row-major or column-major form, respectively.

Where present, argument `TRANS` can be one of `NoTrans` or `Trans` to indicate whether the input matrix is to be transposed or not.

Where present, argument `UPLO` can be one of `Upper` or `Lower` to indicate whether the upper or lower triangular part of an input symmetric matrix is to referenced,or to specify the type of an input triangular matrix.

Where present, argument `DIAG` can be one of `NonUnit` or `Unit` to indicate whether an input triangular matrix is unit triangular or not.

#### General matrix-vector multiply-add

*[procedure]*

`sgemv:: ORDER * TRANS * M * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dgemv:: ORDER * TRANS * M * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

*[procedure]*

`cgemv:: ORDER * TRANS * M * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zgemv:: ORDER * TRANS * M * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xGEMV` performs the matrix-vector multiply-add operation of the form `y := alpha*op( A )*x + beta*y`, where `op( X )` is one of `op( A ) = A` or `op( A ) = A'`.

`ALPHA` and `BETA` are scalars, and `A` is an `M x N` matrix.

`X` is a vector of size `(1 + ( N - 1 ) * abs(INCX))` when argument `TRANS` is `NoTrans`, and `(1 + ( M - 1 ) * abs(INCX))` otherwise. `Y` is a vector of size `(1 + ( M - 1 ) * abs(INCY))` when argument `TRANS` is `NoTrans`, and `(1 + ( N - 1 ) * abs(INCY))` otherwise.

#### Banded matrix-vector multiply-add

*[procedure]*

`sgbmv:: ORDER * TRANS * M * N * KL * KU * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dgbmv:: ORDER * TRANS * M * N * KL * KU * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

*[procedure]*

`cgbmv:: ORDER * TRANS * M * N * KL * KU * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zgbmv:: ORDER * TRANS * M * N * KL * KU * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xGBMV` performs the matrix-vector multiply-add operation of the form `y := alpha*op( A )*x + beta*y`, where `op( X )` is one of `op( A ) = A` or `op( A ) = A'`.

`ALPHA` and `BETA` are scalars, and `A` is an `M x N` banded matrix, with `KL` sub-diagonals and `KU` super-diagonals.

`X` is a vector of size `(1 + ( N - 1 ) * abs(INCX))` when argument `TRANS` is `NoTrans`, and `(1 + ( M - 1 ) * abs(INCX))` otherwise. `Y` is a vector of size `(1 + ( M - 1 ) * abs(INCY))` when argument `TRANS` is `NoTrans`, and `(1 + ( N - 1 ) * abs(INCY))` otherwise.

#### Hermitian matrix-vector multiply-add

*[procedure]*

`chemv:: ORDER * UPLO * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zhemv:: ORDER * UPLO * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xHEMV` performs the matrix-vector multiply-add operation of the form `y := alpha*op( A )*x + beta*y`, where `op( X )` is one of `op( A ) = A` or `op( A ) = A'`.

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` Hermitian matrix.

`X` and `Y` are `N` element vectors.

#### Hermitian banded matrix-vector multiply-add

*[procedure]*

`chbmv:: ORDER * UPLO * N * K * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zhbmv:: ORDER * UPLO * N * K * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xHBMV` performs the matrix-vector multiply-add operation of the form `y := alpha*op( A )*x + beta*y`, where `op( X )` is one of `op( A ) = A` or `op( A ) = A'`.

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` Hermitian banded matrix, with `K` super-diagonals.

`X` and `Y` are `N` element vectors.

#### Symmetric matrix-vector multiply-add

*[procedure]*

`ssymv:: ORDER * UPLO * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dsymv:: ORDER * UPLO * N * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xSYMV` performs matrix-vector multiply-add operation of the form `y := alpha*A*x + beta*y`.

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` symmetric matrix.

`X` and `Y` are `N` element vectors.

#### Banded symmetric matrix-vector multiply-add

*[procedure]*

`ssbmv:: ORDER * UPLO * N * K * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dsbmv:: ORDER * UPLO * N * K * ALPHA * A * X * BETA * Y [LDA * INCX * INCY] -> F64VECTOR`

`xSBMV` performs matrix-vector multiply-add operation of the form `y := alpha*A*B + beta*y`.

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` symmetric banded matrix, with `K` super-diagonals.

`X` and `Y` are `N` element vectors.

#### Triangular matrix-vector multiply-add

*[procedure]*

`strmv:: ORDER * UPLO * TRANS * DIAG * N * A * X [LDA * INCX] -> F32VECTOR`

*[procedure]*

`dtrmv:: ORDER * UPLO * TRANS * DIAG * N * A * X [LDA * INCX] -> F64VECTOR`

*[procedure]*

`ctrmv:: ORDER * UPLO * TRANS * DIAG * N * A * X [LDA * INCX] -> F32VECTOR`

*[procedure]*

`ztrmv:: ORDER * UPLO * TRANS * DIAG * N * A * X [LDA * INCX] -> F64VECTOR`

`xTRMV` performs matrix-vector multiply-add operation of the form `y := alpha*op( A )*x`, where `op ( A ) = A` or `op ( A ) = A'`

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` upper or lower triangular matrix.

`X` is a vector of length `(1 + (n - 1) * abs(INCX))`.

#### Banded triangular matrix-vector multiply-add

*[procedure]*

`stbmv:: ORDER * UPLO * TRANS * DIAG * N * K * A * X [LDA * INCX] -> F32VECTOR`

*[procedure]*

`dtbmv:: ORDER * UPLO * TRANS * DIAG * N * K * A * X [LDA * INCX] -> F64VECTOR`

*[procedure]*

`ctbmv:: ORDER * UPLO * TRANS * DIAG * N * K * A * X [LDA * INCX] -> F32VECTOR`

*[procedure]*

`ztbmv:: ORDER * UPLO * TRANS * DIAG * N * K * A * X [LDA * INCX] -> F64VECTOR`

`xTBMV` performs matrix-vector multiply-add operation of the form `y := alpha*A*B + beta*y`, where `op ( A ) = A` or `op ( A ) = A'`

`ALPHA` and `BETA` are scalars, and `A` is an `N x N` upper or lower triangular banded matrix, with `K+1` diagonals.

`X` is a vector of length `(1 + (n - 1) * abs(INCX))`.

#### Triangular matrix equation solve

*[procedure]*

`strsv:: ORDER * UPLO * TRANS * DIAG * N * ALPHA * A * B * [LDA * INCB] -> F32VECTOR`

*[procedure]*

`dtrsv:: ORDER * UPLO * TRANS * DIAG * N * A * B * [LDA * INCB] -> F64VECTOR`

*[procedure]*

`ctrsv:: ORDER * UPLO * TRANS * DIAG * N * A * B * [LDA * INCB] -> F32VECTOR`

*[procedure]*

`ztrsv:: ORDER * UPLO * TRANS * DIAG * N * A * B * [LDA * INCB] -> F64VECTOR`

`xTRSV` solves one of the systems of equations `A*x = b` or `A'*x = b`.

`ALPHA` and `BETA` are scalars, `A` is a upper or lower triangular matrix, and `B` is a `N` element vector.

#### Banded triangular matrix equation solve

*[procedure]*

`stbsv:: ORDER * UPLO * TRANS * DIAG * N * K * A * B * [LDA * INCB] -> F32VECTOR`

*[procedure]*

`dtbsv:: ORDER * UPLO * TRANS * DIAG * N * K * A * B * [LDA * INCB] -> F64VECTOR`

*[procedure]*

`ctbsv:: ORDER * UPLO * TRANS * DIAG * N * K * A * B * [LDA * INCB] -> F32VECTOR`

*[procedure]*

`ztbsv:: ORDER * UPLO * TRANS * DIAG * N * K * A * B * [LDA * INCB] -> F64VECTOR`

`xTBSV` solves one of the systems of equations `A*x = b` or `A'*x = b`.

`ALPHA` and `BETA` are scalars, `A` is a upper or lower banded triangular matrix with `K+1` diagonals, and `B` is a `N` element vector.

#### Rank 1 operation

*[procedure]*

`sger:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dger:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F64VECTOR`

`xGER` performs the rank 1 operation `A := alpha*x*y' + A`.

`ALPHA` is a scalar, `X` is an `M` element vector, `Y` is an `N` element vector, and `A` is an `M x N` matrix.

#### Rank 1 operation with optional offset

*[procedure]*

`siger:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY * XOFS * YOFS] -> F32VECTOR`

*[procedure]*

`diger:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY * XOFS * YOFS] -> F64VECTOR`

`xIGER` performs the rank 1 operation `A := alpha*x[xofs:M]*y'[yofs:N] + A`.

`ALPHA` is a scalar, `X` is an `M` element vector, `Y` is an `N` element vector, and `A` is an `M x N` matrix.

#### Rank 1 operation on complex matrices and vectors

*[procedure]*

`cgeru:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zgeru:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F64VECTOR`

`xGERU` performs the rank 1 operation `A := alpha*x*y' + A`.

`ALPHA` is a scalar, `X` is an `M` element vector, `Y` is an `N` element vector, and `A` is an `M x N` matrix.

#### Rank 1 operation on complex matrices and vectors

*[procedure]*

`cgerc:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zgerc:: ORDER * M * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F64VECTOR`

`xGERC` performs the rank 1 operation `A := alpha*x*conjg(y') + A`.

`ALPHA` is a scalar, `X` is an `M` element vector, `Y` is an `N` element vector, and `A` is an `M x N` matrix.

#### Hermitian rank 1 operation

*[procedure]*

`cher:: ORDER * UPLO * N * ALPHA * X * A [LDA * INCX] -> F32VECTOR`

*[procedure]*

`zher:: ORDER * UPLO * N * ALPHA * X * A [LDA * INCX] -> F64VECTOR`

`xHER` performs the Hermitian rank 1 operation `A := alpha*x*conjg(x') + A`.

`ALPHA` is a scalar, `X` is an `N` element vector, and `A` is an `N x N` Hermitian matrix.

#### Hermitian rank 2 operation

*[procedure]*

`cher2:: ORDER * UPLO * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`zher2:: ORDER * UPLO * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F64VECTOR`

`xHER2` performs the Hermitian rank 2 operation `A := alpha*x*conjg(y') + conjg(alpha)*y*conjg(x') + A`.

`ALPHA` is a scalar, `X` and `Y` are `N` element vectors, and `A` is an `N x N` Hermitian matrix.

#### Symmetric rank 1 operation

*[procedure]*

`ssyr:: ORDER * UPLO * N * ALPHA * X * A [LDA * INCX] -> F32VECTOR`

*[procedure]*

`dsyr:: ORDER * UPLO * N * ALPHA * X * A [LDA * INCX] -> F64VECTOR`

`xSYR` performs the symmetric rank 1 operation `A := alpha*x*x' + A`.

`ALPHA` is a scalar, `X` is an `N` element vector, and `A` is an `N x N` symmetric matrix.

#### Symmetric rank 2 operation

*[procedure]*

`ssyr2:: ORDER * UPLO * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F32VECTOR`

*[procedure]*

`dsyr2:: ORDER * UPLO * N * ALPHA * X * Y * A [LDA * INCX * INCY] -> F64VECTOR`

`xSYR2` performs the symmetric rank 2 operation `A := alpha*x*y' + alpha*y*x' + A`.

`ALPHA` is a scalar, `X` and `Y` are `N` element vectors, and `A` is an `N x N` symmetric matrix.

### BLAS level 3 routines

#### Conventions

The BLAS level 3 procedures in this egg differ from the actual routines they invoke by the position of the leading dimension arguments (`LDA`, `LDB`, and `LDC`). In this egg, these arguments are optional, and their default values are set to the largest matrix dimension, depending on the semantics of the respective operation.

In the procedure signatures below, these optional arguments are indicated by [ and ] (square brackets).

Argument `ORDER` is one of `RowMajor` or `ColMajor` to indicate that the input and output matrices are in row-major or column-major form, respectively.

Where present, arguments `TRANS`, `TRANSA`, `TRANSB` can be one of `NoTrans` or `Trans` to indicate whether the respective input matrices are to be transposed or not.

Where present, argument `SIDE` can be one of `Left` or `Right` to indicate whether an input symmetric matrix appears on the left or right in the respective operation.

Where present, argument `UPLO` can be one of `Upper` or `Lower` to indicate whether the upper or lower triangular part of an input symmetric matrix is to referenced,or to specify the type of an input triangular matrix.

Where present, argument `DIAG` can be one of `NonUnit` or `Unit` to indicate whether an input triangular matrix is unit triangular or not.

#### General matrix multiply-add

*[procedure]*

`sgemm:: ORDER * TRANSA * TRANSB * M * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`dgemm:: ORDER * TRANSA * TRANSB * M * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`cgemm:: ORDER * TRANSA * TRANSB * M * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`zgemm:: ORDER * TRANSA * TRANSB * M * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xGEMM` performs matrix-matrix multiply-add operation of the form `C := alpha*op( A )*op( B ) + beta*C`, where `op( X )` is one of `op( X ) = X` or `op( X ) = X'`.

`ALPHA` and `BETA` are scalars, and `A`, `B` and `C` are matrices, with `op( A )` an `M x K` matrix, `op( B )` a `K x N` matrix and `C` an `M x N` matrix.

#### Symmetric matrix multiply-add

*[procedure]*

`ssymm:: ORDER * SIDE * UPLO * M * N * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`dsymm:: ORDER * SIDE * UPLO * M * N * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`csymm:: ORDER * SIDE * UPLO * M * N * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`zsymm:: ORDER * SIDE * UPLO * M * N * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xSYMM` performs matrix-matrix multiply-add operation of the form `C := alpha*A*B + beta*C` or `C := alpha*B*A + beta*C`.

`ALPHA` and `BETA` are scalars, `A` is a symmetric matrix, and `B` and `C` are `M x N` matrices.

#### Symmetric rank k operation

*[procedure]*

`ssyrk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`dsyrk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`csyrk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`zsyrk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xSYRK` performs one of the symmetric rank k operations

{{C := alpha*A*A' + beta*C}} or {{C := alpha*A'*A + beta*C}}.

`ALPHA` and `BETA` are scalars, `A` is an `N x K` or `K x N` matrix, and `C` is an `N x N` symmetric matrix.

#### Hermitian rank k operation

*[procedure]*

`cherk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`zherk:: ORDER * UPLO * TRANS * N * K * ALPHA * A * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xHERK` performs one of the hermitian rank k operations `C := alpha*A*conjg(A') + beta*C` or `C := alpha*conjg(A')*A + beta*C`.

`ALPHA` and `BETA` are scalars, `A` is an `N x K` or `K x N` matrix, and `C` is an `N x N` hermitian matrix.

#### Symmetric rank 2k operation

*[procedure]*

`ssyr2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`dsyr2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`csyr2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`zsyr2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xSYR2K` performs one of the symmetric rank 2k operations `C := alpha*A*B' + beta*C` or `C := alpha*B'*A + beta*C`.

`ALPHA` and `BETA` are scalars, `A` and `B` are `N x K` or `K x N` matrices, and `C` is an `N x N` symmetric matrix.

#### Hermitian rank 2k operation

*[procedure]*

`cher2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`zher2k:: ORDER * UPLO * TRANS * N * K * ALPHA * A * B * BETA * C [LDA * LDB * LDC] -> F64VECTOR`

`xHER2K` performs one of the hermitian rank 2k operations `C := alpha*A*conjg(B') + beta*C` or `C := alpha*conjg(B')*A + beta*C`.

`ALPHA` and `BETA` are scalars, `A` and `B` are `N x K` or `K x N` matrices, and `C` is an `N x N` hermitian matrix.

#### Triangular matrix multiply

*[procedure]*

`strmm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B [LDA * LDB] -> F32VECTOR`

*[procedure]*

`dtrmm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B [LDA * LDB] -> F64VECTOR`

*[procedure]*

`ctrmm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B [LDA * LDB] -> F32VECTOR`

*[procedure]*

`ztrmm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B [LDA * LDB] -> F64VECTOR`

`xTRMM` performs matrix-matrix multiply operation of the form `B := alpha*op( A )*B` or `B := alpha*B*op( A )`.

`ALPHA` is a scalar, `A` is an upper or lower triangular matrix, and `B` is an `M x N` matrix.

#### Triangular matrix equation solve

*[procedure]*

`strsm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B * [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`dtrsm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B * [LDA * LDB * LDC] -> F64VECTOR`

*[procedure]*

`ctrsm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B * [LDA * LDB * LDC] -> F32VECTOR`

*[procedure]*

`ztrsm:: ORDER * SIDE * UPLO * TRANSA * DIAG * M * N * ALPHA * A * B * [LDA * LDB * LDC] -> F64VECTOR`

`xTRSM` solves one of the matrix equations

{{op( A )*X = alpha*B}} or {{X*op( A ) = alpha*B}}.

`op( A )` is one of `op( A ) = A` or `op( A ) = A'`.

`ALPHA` and `BETA` are scalars, `A` is a upper or lower triangular matrix, and `B` is a `M x N` matrix.

## Examples

(import srfi-4 blas) (define order ColMajor) (define transa NoTrans) (define m 4) (define n 4) (define alpha 1) (define beta 0) (define a ; column-major order! (f64vector 1 2 3 4 1 1 1 1 3 4 5 6 5 6 7 8) ) (define x (f64vector 1 2 1 1)) (define y (f64vector 0 0 0 0)) (dgemv! order transa m n alpha a x beta y) (print y)

## About this egg

### Author

Felix Winkelmann and Ivan Raikov

### Version history

- 4.1
- Fixed use of memq [thanks to Moritz Heidkamp]
- 4.0
- Using bind instead of easyffi
- 3.1
- Updated test script to return proper exit code
- 3.0
- Eliminated reduntant blas: prefix from names of exported symbols
- 2.8
- Eliminated use of noop
- 2.7
- Switched to wiki documentation
- 2.6
- Ported to Chicken 4
- 2.5
- Build script updated for better cross-platform compatibility
- 2.4
- Added iger procedures; fixed a bug in the default arguments of level 2 routines
- 2.3
- Added iaxpy procedures; fixed a bug in the default arguments of level 1 routines
- 2.2
- Fixed a bug in the renaming of C routines
- 2.1
- Added eggdoc property to meta file
- 2.0
- An overhaul of the library to introduce safe, unsafe, and pure variants of each routine
- 1.8
- Added icopy procedures [by Ivan Raikov]
- 1.7
- Support for Mac OS X added [by Will Farr]
- 1.6
- Fixed bug in blas library test code
- 1.5
- Added support for CLAPACK [by Ivan Raikov]
- 1.4
- Added support for atlas CBLAS library [by Stu Glaser]
- 1.3
- Tries to find a proper CBLAS library (currently only GSL)
- 1.2
- Adapted to new FFI macro-names
- 1.1
- Adapted to new setup scheme

### License

Copyright (c) 2003-2006, Felix L. Winkelmann Copyright (c) 2007-2018 Ivan Raikov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.