heat.linalg
Import all linear algebra functions into the ht.linalg namespace
Submodules
Package Contents
- condest(A: heat.core.dndarray.DNDarray, p: int | str = None, algorithm: str = 'randomized', params: list = None) heat.core.dndarray.DNDarray[source]
Computes a (possibly randomized) upper estimate of the l2-condition number of the input 2D DNDarray.
- Parameters:
A (DNDarray) – The matrix, i.e., a 2D DNDarray, for which the condition number shall be estimated.
p (int or str (optional)) – The norm to use for the condition number computation. If None, the l2-norm (default, p=2) is used. So far, only p=2 is implemented.
algorithm (str) – The algorithm to use for the estimation. Currently, only “randomized” (default) is implemented.
params (dict (optional)) – A list of parameters required for the chosen algorithm; if not provided, default values for the respective algorithm are chosen. If algorithm=”randomized” the number of random samples to use can be specified under the key “nsamples”; default is 10.
Notes
The “randomized” algorithm follows the approach described in [1]; note that in the paper actually the condition number w.r.t. the Frobenius norm is estimated. However, this yields an upper bound for the condition number w.r.t. the l2-norm as well.
References
[1] T. Gudmundsson, C. S. Kenney, and A. J. Laub. Small-Sample Statistical Estimates for Matrix Norms. SIAM Journal on Matrix Analysis and Applications 1995 16:3, 776-792.
- cross(a: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, axisa: int = -1, axisb: int = -1, axisc: int = -1, axis: int = -1) heat.core.dndarray.DNDarray[source]
Returns the cross product. 2D vectors will we converted to 3D.
- Parameters:
a (DNDarray) – First input array.
b (DNDarray) – Second input array. Must have the same shape as ‘a’.
axisa (int) – Axis of a that defines the vector(s). By default, the last axis.
axisb (int) – Axis of b that defines the vector(s). By default, the last axis.
axisc (int) – Axis of the output containing the cross product vector(s). By default, the last axis.
axis (int) – Axis that defines the vectors for which to compute the cross product. Overrides axisa, axisb and axisc. Default: -1
- Raises:
ValueError – If the two input arrays don’t match in shape, split, device, or comm. If the vectors are along the split axis.
TypeError – If ‘axis’ is not an integer.
Examples
>>> a = ht.eye(3) >>> b = ht.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) >>> cross = ht.cross(a, b) DNDarray([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.]], dtype=ht.float32, device=cpu:0, split=None)
- det(a: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Returns the determinant of a square matrix.
- Parameters:
a (DNDarray) – A square matrix or a stack of matrices. Shape = (…,M,M)
- Raises:
RuntimeError – If the dtype of ‘a’ is not floating-point.
RuntimeError – If a.ndim < 2 or if the length of the last two dimensions is not the same.
Examples
>>> a = ht.array([[-2, -1, 2], [2, 1, 4], [-3, 3, -1]]) >>> ht.linalg.det(a) DNDarray(54., dtype=ht.float64, device=cpu:0, split=None)
- dot(a: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, out: heat.core.dndarray.DNDarray | None = None) heat.core.dndarray.DNDarray | float[source]
Returns the dot product of two
DNDarrays. Specifically,If both a and b are 1-D arrays, it is inner product of vectors.
If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or
a@bis preferred.If either a or b is 0-D (scalar), it is equivalent to multiply and using
multiply(a, b)ora*bis preferred.
- Parameters:
See also
vecdotSupports (vector) dot along an axis.
- inv(a: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Computes the multiplicative inverse of a square matrix.
- Parameters:
a (DNDarray) – Square matrix of floating-point data type or a stack of square matrices. Shape = (…,M,M)
- Raises:
RuntimeError – If the inverse does not exist.
RuntimeError – If the dtype is not floating-point
RuntimeError – If a is not at least two-dimensional or if the lengths of the last two dimensions are not the same.
Examples
>>> a = ht.array([[1.0, 2], [2, 3]]) >>> ht.linalg.inv(a) DNDarray([[-3., 2.], [ 2., -1.]], dtype=ht.float32, device=cpu:0, split=None)
- matmul(a: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, allow_resplit: bool = False) heat.core.dndarray.DNDarray[source]
Matrix multiplication of two
DNDarrays:a@b=corA@B=c. Returns a tensor with the result ofa@b. The split dimension of the returned array is typically the split dimension of a. If both areNoneand ifallow_resplit=Falsethenc.splitis alsoNone.Batched inputs (with batch dimensions being leading dimensions) are allowed; see also the Notes below.
- Parameters:
a (DNDarray) – matrix \(L \times P\) or vector \(P\) or batch of matrices: \(B_1 \times ... \times B_k \times L \times P\)
b (DNDarray) – matrix \(P \times Q\) or vector \(P\) or batch of matrices: \(B_1 \times ... \times B_k \times P \times Q\)
allow_resplit (bool, optional) – Whether to distribute
ain the case that botha.split is Noneandb.split is None. Default isFalse. IfTrue, if both are not split thenawill be distributed in-place along axis 0.
Notes
For batched inputs, batch dimensions must coincide and if one matrix is split along a batch axis the other must be split along the same axis.
If
aorbis a vector the result will also be a vector.We recommend to avoid the particular split combinations
1-0,None-0, and1-None(fora.split-b.split) due to their comparably high memory consumption, if possible. ApplyingDNDarray.resplit_orheat.respliton one of the two factors before callingmatmulin these situations might improve performance of your code / might avoid memory bottlenecks.
References
[1] R. Gu, et al., “Improving Execution Concurrency of Large-scale Matrix Multiplication on Distributed Data-parallel Platforms,” IEEE Transactions on Parallel and Distributed Systems, vol 28, no. 9. 2017.
[2] S. Ryu and D. Kim, “Parallel Huge Matrix Multiplication on a Cluster with GPGPU Accelerators,” 2018 IEEE International Parallel and Distributed Processing Symposium Workshops (IPDPSW), Vancouver, BC, 2018, pp. 877-882.
Examples
>>> a = ht.ones((n, m), split=1) >>> a[0] = ht.arange(1, m + 1) >>> a[:, -1] = ht.arange(1, n + 1).larray [0/1] tensor([[1., 2.], [1., 1.], [1., 1.], [1., 1.], [1., 1.]]) [1/1] tensor([[3., 1.], [1., 2.], [1., 3.], [1., 4.], [1., 5.]]) >>> b = ht.ones((j, k), split=0) >>> b[0] = ht.arange(1, k + 1) >>> b[:, 0] = ht.arange(1, j + 1).larray [0/1] tensor([[1., 2., 3., 4., 5., 6., 7.], [2., 1., 1., 1., 1., 1., 1.]]) [1/1] tensor([[3., 1., 1., 1., 1., 1., 1.], [4., 1., 1., 1., 1., 1., 1.]]) >>> linalg.matmul(a, b).larray [0/1] tensor([[18., 8., 9., 10.], [14., 6., 7., 8.], [18., 7., 8., 9.], [22., 8., 9., 10.], [26., 9., 10., 11.]]) [1/1] tensor([[11., 12., 13.], [ 9., 10., 11.], [10., 11., 12.], [11., 12., 13.], [12., 13., 14.]])
- matrix_norm(x: heat.core.dndarray.DNDarray, axis: Tuple[int, int] | None = None, keepdims: bool = False, ord: int | str | None = None) heat.core.dndarray.DNDarray[source]
Computes the matrix norm of an array.
- Parameters:
x (DNDarray) – Input array
axis (tuple, optional) – Both axes of the matrix. If None ‘x’ must be a matrix. Default: None
keepdims (bool, optional) – Retains the reduced dimension when True. Default: False
ord (int, 'fro', 'nuc', optional) – The matrix norm order to compute. If None the Frobenius norm (‘fro’) is used. Default: None
See also
normComputes the vector or matrix norm of an array.
vector_normComputes the vector norm of an array.
Notes
The following norms are supported:
ord
norm for matrices
None
Frobenius norm
‘fro’
Frobenius norm
‘nuc’
nuclear norm
inf
max(sum(abs(x), axis=1))
-inf
min(sum(abs(x), axis=1))
1
max(sum(abs(x), axis=0))
-1
min(sum(abs(x), axis=0))
The following matrix norms are currently not supported:
ord
norm for matrices
2
largest singular value
-2
smallest singular value
- Raises:
TypeError – If axis is not a 2-tuple
ValueError – If an invalid matrix norm is given or ‘x’ is a vector.
Examples
>>> ht.matrix_norm(ht.array([[1, 2], [3, 4]])) DNDarray([[5.4772]], dtype=ht.float64, device=cpu:0, split=None) >>> ht.matrix_norm(ht.array([[1, 2], [3, 4]]), keepdims=True, ord=-1) DNDarray([[4.]], dtype=ht.float64, device=cpu:0, split=None)
- matrix_exp(A: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Computes the matrix exponential of a square matrix.
Letting \(\mathbb{K}\) be \(\mathbb{R}\) or \(\mathbb{C}\), this function computes the matrix exponential of \(A \in \mathbb{K}^{n \times n}\), which is defined as
\[\mathrm{matrix\_exp}(A) = \sum_{k=0}^\infty \frac{1}{k!}A^k \in \mathbb{K}^{n \times n}.\]If the matrix \(A\) has eigenvalues \(\lambda_i \in \mathbb{C}\), the matrix \(\mathrm{matrix\_exp}(A)\) has eigenvalues \(e^{\lambda_i} \in \mathbb{C}\).
Supports input of bfloat16, float, double, cfloat and cdouble dtypes. Also supports batches of matrices, and if
Ais a batch of matrices then the output has the same batch dimensions.Note
A may only be distributed in the batch dimensions.
See also
torch.linalg.matrix_exp()is called under the hood on the local data.- Parameters:
A (DNDarray) – DNDarray of shape (*, n, n) where * is zero or more batch dimensions.
Example:
>>> A = ht.empty((2, 2, 2), split=0) >>> A[0, :, :] = ht.eye((2, 2)) >>> A[1, :, :] = 2 * ht.eye((2, 2)) >>> ht.linalg.matrix_exp(A) DNDarray([[[2.7183, 0.0000], [0.0000, 2.7183]], [[7.3891, 0.0000], [0.0000, 7.3891]]], dtype=ht.float32, device=cpu:0, split=0)
- expm
Alias for
matrix_exp()
- norm(x: heat.core.dndarray.DNDarray, axis: int | Tuple[int, int] | None = None, keepdims: bool = False, ord: int | float | str | None = None) heat.core.dndarray.DNDarray[source]
Return the vector or matrix norm of an array.
- Parameters:
x (DNDarray) – Input vector
axis (int, tuple, optional) – Axes along which to compute the norm. If an integer, vector norm is used. If a 2-tuple, matrix norm is used. If None, it is inferred from the dimension of the array. Default: None
keepdims (bool, optional) – Retains the reduced dimension when True. Default: False
ord (int, float, inf, -inf, 'fro', 'nuc') – The norm order to compute. See Notes
See also
vector_normComputes the vector norm of an array.
matrix_normComputes the matrix norm of an array.
Notes
The following norms are supported:
ord
norm for matrices
norm for vectors
None
Frobenius norm
L2-norm (Euclidean)
‘fro’
Frobenius norm
–
‘nuc’
nuclear norm
–
inf
max(sum(abs(x), axis=1))
max(abs(x))
-inf
min(sum(abs(x), axis=1))
min(abs(x))
0
–
sum(x != 0)
1
max(sum(abs(x), axis=0))
L1-norm (Manhattan)
-1
min(sum(abs(x), axis=0))
1./sum(1./abs(a))
2
–
L2-norm (Euclidean)
-2
–
1./sqrt(sum(1./abs(a)**2))
other
–
sum(abs(x)**ord)**(1./ord)
The following matrix norms are currently not supported:
ord
norm for matrices
2
largest singular value
-2
smallest singular value
- Raises:
ValueError – If ‘axis’ has more than 2 elements
Examples
>>> from heat import linalg as LA >>> a = ht.arange(9, dtype=ht.float) - 4 >>> a DNDarray([-4., -3., -2., -1., 0., 1., 2., 3., 4.], dtype=ht.float32, device=cpu:0, split=None) >>> b = a.reshape((3, 3)) >>> b DNDarray([[-4., -3., -2.], [-1., 0., 1.], [ 2., 3., 4.]], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a) DNDarray(7.7460, dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b) DNDarray(7.7460, dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b, ord="fro") DNDarray(7.7460, dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, float("inf")) DNDarray([4.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b, ht.inf) DNDarray([9.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, -ht.inf)) DNDarray([0.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b, -ht.inf) DNDarray([2.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, 1) DNDarray([20.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b, 1) DNDarray([7.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, -1) DNDarray([0.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(b, -1) DNDarray([6.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, 2) DNDarray(7.7460, dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, -2) DNDarray([0.], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, 3) DNDarray([5.8480], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(a, -3) DNDarray([0.], dtype=ht.float32, device=cpu:0, split=None) c = ht.array([[ 1, 2, 3], [-1, 1, 4]]) >>> LA.norm(c, axis=0) DNDarray([1.4142, 2.2361, 5.0000], dtype=ht.float64, device=cpu:0, split=None) >>> LA.norm(c, axis=1) DNDarray([3.7417, 4.2426], dtype=ht.float64, device=cpu:0, split=None) >>> LA.norm(c, axis=1, ord=1) DNDarray([6., 6.], dtype=ht.float64, device=cpu:0, split=None) >>> m = ht.arange(8).reshape(2, 2, 2) >>> LA.norm(m, axis=(1, 2)) DNDarray([ 3.7417, 11.2250], dtype=ht.float32, device=cpu:0, split=None) >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :]) (DNDarray(3.7417, dtype=ht.float32, device=cpu:0, split=None), DNDarray(11.2250, dtype=ht.float32, device=cpu:0, split=None))
- outer(a: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, out: heat.core.dndarray.DNDarray | None = None, split: int | None = None) heat.core.dndarray.DNDarray[source]
Compute the outer product of two 1-D DNDarrays: \(out(i, j) = a(i) \times b(j)\). Given two vectors, \(a = (a_0, a_1, ..., a_N)\) and \(b = (b_0, b_1, ..., b_M)\), the outer product is:
\begin{pmatrix} a_0 \cdot b_0 & a_0 \cdot b_1 & . & . & a_0 \cdot b_M \\ a_1 \cdot b_0 & a_1 \cdot b_1 & . & . & a_1 \cdot b_M \\ . & . & . & . & . \\ a_N \cdot b_0 & a_N \cdot b_1 & . & . & a_N \cdot b_M \end{pmatrix}- Parameters:
a (DNDarray) – 1-dimensional: \(N\) Will be flattened by default if more than 1-D.
b (DNDarray) – 1-dimensional: \(M\) Will be flattened by default if more than 1-D.
out (DNDarray, optional) – 2-dimensional: \(N \times M\) A location where the result is stored
split (int, optional) – Split dimension of the resulting DNDarray. Can be 0, 1, or None. This is only relevant if the calculations are memory-distributed. Default is
split=0(see Notes).
Notes
Parallel implementation of outer product, assumes arrays are dense. In the classical (dense) case, one of the two arrays needs to be communicated around the processes in a ring.
Sending
baround in a ring results inouterbeing split along the rows (outer.split = 0).Sending
aaround in a ring results inouterbeing split along the columns (outer.split = 1).
So, if specified,
splitdefines whichDNDarraystays put and which one is passed around. IfsplitisNoneor unspecified, the result will be distributed along axis0, i.e. by defaultbis passed around,astays put.Examples
>>> a = ht.arange(4) >>> b = ht.arange(3) >>> ht.outer(a, b).larray (3 processes) [0/2] tensor([[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6]], dtype=torch.int32) [1/2] tensor([[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6]], dtype=torch.int32) [2/2] tensor([[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6]], dtype=torch.int32) >>> a = ht.arange(4, split=0) >>> b = ht.arange(3, split=0) >>> ht.outer(a, b).larray [0/2] tensor([[0, 0, 0], [0, 1, 2]], dtype=torch.int32) [1/2] tensor([[0, 2, 4]], dtype=torch.int32) [2/2] tensor([[0, 3, 6]], dtype=torch.int32) >>> ht.outer(a, b, split=1).larray [0/2] tensor([[0], [0], [0], [0]], dtype=torch.int32) [1/2] tensor([[0], [1], [2], [3]], dtype=torch.int32) [2/2] tensor([[0], [2], [4], [6]], dtype=torch.int32) >>> a = ht.arange(5, dtype=ht.float32, split=0) >>> b = ht.arange(4, dtype=ht.float64, split=0) >>> out = ht.empty((5,4), dtype=ht.float64, split=1) >>> ht.outer(a, b, split=1, out=out) >>> out.larray [0/2] tensor([[0., 0.], [0., 1.], [0., 2.], [0., 3.], [0., 4.]], dtype=torch.float64) [1/2] tensor([[0.], [2.], [4.], [6.], [8.]], dtype=torch.float64) [2/2] tensor([[ 0.], [ 3.], [ 6.], [ 9.], [12.]], dtype=torch.float64)
- projection(a: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Projection of vector
aonto vectorb
- trace(a: heat.core.dndarray.DNDarray, offset: int | None = 0, axis1: int | None = 0, axis2: int | None = 1, dtype: heat.core.types.datatype | None = None, out: heat.core.dndarray.DNDarray | None = None) heat.core.dndarray.DNDarray | float[source]
Return the sum along diagonals of the array
If a is 2D, the sum along its diagonal with the given offset is returned, i.e. the sum of elements a[i, i+offset] for all i.
If a has more than two dimensions, then the axes specified by axis1 and axis2 are used to determine the 2D-sub-DNDarrays whose traces are returned. The shape of the resulting array is the same as that of a with axis1 and axis2 removed.
- Parameters:
a (array_like) – Input array, from which the diagonals are taken
offset (int, optional) – Offsets of the diagonal from the main diagonal. Can be both positive and negative. Defaults to 0.
axis1 (int, optional) – Axis to be used as the first axis of the 2D-sub-arrays from which the diagonals should be taken. Default is the first axis of a
axis2 (int, optional) – Axis to be used as the second axis of the 2D-sub-arrays from which the diagonals should be taken. Default is the second two axis of a
dtype (dtype, optional) – Determines the data-type of the returned array and of the accumulator where the elements are summed. If dtype has value None than the dtype is the same as that of a
out (ht.DNDarray, optional) – Array into which the output is placed. Its type is preserved and it must be of the right shape to hold the output Only applicable if a has more than 2 dimensions, thus the result is not a scalar. If distributed, its split axis might change eventually.
- Returns:
sum_along_diagonals – If a is 2D, the sum along the diagonal is returned as a scalar If a has more than 2 dimensions, then a DNDarray of sums along diagonals is returned
- Return type:
number (of defined dtype) or ht.DNDarray
Examples
2D-case >>> x = ht.arange(24).reshape((4, 6)) >>> x
- DNDarray([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23]], dtype=ht.int32, device=cpu:0, split=None)
>>> ht.trace(x) 42 >>> ht.trace(x, 1) 46 >>> ht.trace(x, -2) 31
> 2D-case >>> x = x.reshape((2, 3, 4)) >>> x
- DNDarray([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7], [ 8, 9, 10, 11]],
- [[12, 13, 14, 15],
[16, 17, 18, 19], [20, 21, 22, 23]]], dtype=ht.int32, device=cpu:0, split=None)
>>> ht.trace(x) DNDarray([16, 18, 20, 22], dtype=ht.int32, device=cpu:0, split=None) >>> ht.trace(x, 1) DNDarray([24, 26, 28, 30], dtype=ht.int32, device=cpu:0, split=None) >>> ht.trace(x, axis1=0, axis2=2) DNDarray([13, 21, 29], dtype=ht.int32, device=cpu:0, split=None)
- transpose(a: heat.core.dndarray.DNDarray, axes: List[int] | None = None) heat.core.dndarray.DNDarray[source]
Permute the dimensions of an array.
- Parameters:
a (DNDarray) – Input array.
axes (None or List[int,...], optional) – By default, reverse the dimensions, otherwise permute the axes according to the values given.
- tril(m: heat.core.dndarray.DNDarray, k: int = 0) heat.core.dndarray.DNDarray[source]
Returns the lower triangular part of the
DNDarray. The lower triangular part of the array is defined as the elements on and below the diagonal, the other elements of the result array are set to 0. The argumentkcontrols which diagonal to consider. Ifk=0, all elements on and below the main diagonal are retained. A positive value includes just as many diagonals above the main diagonal, and similarly a negative value excludes just as many diagonals below the main diagonal.- Parameters:
m (DNDarray) – Input array for which to compute the lower triangle.
k (int, optional) – Diagonal above which to zero elements.
k=0(default) is the main diagonal,k<0is below andk>0is above.
- triu(m: heat.core.dndarray.DNDarray, k: int = 0) heat.core.dndarray.DNDarray[source]
Returns the upper triangular part of the
DNDarray. The upper triangular part of the array is defined as the elements on and below the diagonal, the other elements of the result array are set to 0. The argumentkcontrols which diagonal to consider. Ifk=0, all elements on and below the main diagonal are retained. A positive value includes just as many diagonals above the main diagonal, and similarly a negative value excludes just as many diagonals below the main diagonal.- Parameters:
m (DNDarray) – Input array for which to compute the upper triangle.
k (int, optional) – Diagonal above which to zero elements.
k=0(default) is the main diagonal,k<0is below andk>0is above.
- vdot(x1: heat.core.dndarray.DNDarray, x2: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Computes the dot product of two vectors. Higher-dimensional arrays will be flattened.
- Parameters:
- Raises:
ValueError – If the number of elements is inconsistent.
See also
dotReturn the dot product without using the complex conjugate.
Examples
>>> a = ht.array([1 + 1j, 2 + 2j]) >>> b = ht.array([1 + 2j, 3 + 4j]) >>> ht.vdot(a, b) DNDarray([(17+3j)], dtype=ht.complex64, device=cpu:0, split=None) >>> ht.vdot(b, a) DNDarray([(17-3j)], dtype=ht.complex64, device=cpu:0, split=None)
- vecdot(x1: heat.core.dndarray.DNDarray, x2: heat.core.dndarray.DNDarray, axis: int | None = None, keepdims: bool | None = None) heat.core.dndarray.DNDarray[source]
Computes the (vector) dot product of two DNDarrays.
- Parameters:
x1 (DNDarray) – first input array.
x2 (DNDarray) – second input array. Must be compatible with x1.
axis (int, optional) – axis over which to compute the dot product. The last dimension is used if ‘None’.
keepdims (bool, optional) – If this is set to ‘True’, the axes which are reduced are left in the result as dimensions with size one.
See also
dotNumPy-like dot function.
Examples
>>> ht.vecdot(ht.full((3, 3, 3), 3), ht.ones((3, 3)), axis=0) DNDarray([[9., 9., 9.], [9., 9., 9.], [9., 9., 9.]], dtype=ht.float32, device=cpu:0, split=None)
- vector_norm(x: heat.core.dndarray.DNDarray, axis: int | Tuple[int] | None = None, keepdims=False, ord: int | float | None = None) heat.core.dndarray.DNDarray[source]
Computes the vector norm of an array.
- Parameters:
x (DNDarray) – Input array
axis (int, tuple, optional) – Axis along which to compute the vector norm. If None ‘x’ must be a vector. Default: None
keepdims (bool, optional) – Retains the reduced dimension when True. Default: False
ord (int, float, optional) – The norm order to compute. If None the euclidean norm (2) is used. Default: None
See also
normComputes the vector norm or matrix norm of an array.
matrix_normComputes the matrix norm of an array.
Notes
The following norms are suported:
ord
norm for vectors
None
L2-norm (Euclidean)
inf
max(abs(x))
-inf
min(abs(x))
0
sum(x != 0)
1
L1-norm (Manhattan)
-1
1./sum(1./abs(a))
2
L2-norm (Euclidean)
-2
1./sqrt(sum(1./abs(a)**2))
other
sum(abs(x)**ord)**(1./ord)
- Raises:
TypeError – If axis is not an integer or a 1-tuple
ValueError – If an invalid vector norm is given.
Examples
>>> ht.vector_norm(ht.array([1, 2, 3, 4])) DNDarray([5.4772], dtype=ht.float64, device=cpu:0, split=None) >>> ht.vector_norm(ht.array([[1, 2], [3, 4]]), axis=0, ord=1) DNDarray([[4., 6.]], dtype=ht.float64, device=cpu:0, split=None)
- cg(A: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, x0: heat.core.dndarray.DNDarray, out: heat.core.dndarray.DNDarray | None = None) heat.core.dndarray.DNDarray[source]
Conjugate gradients method for solving a system of linear equations :math: Ax = b
- lanczos(A: heat.core.dndarray.DNDarray, m: int, v0: heat.core.dndarray.DNDarray | None = None, V_out: heat.core.dndarray.DNDarray | None = None, T_out: heat.core.dndarray.DNDarray | None = None) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
The Lanczos algorithm is an iterative approximation of the solution to the eigenvalue problem, as an adaptation of power methods to find the m “most useful” (tending towards extreme highest/lowest) eigenvalues and eigenvectors of an \(n \times n\) Hermitian matrix, where often \(m<<n\). It returns two matrices \(V\) and \(T\), where:
\(V\) is a Matrix of size \(n\times m\), with orthonormal columns, that span the Krylow subspace n
\(T\) is a Tridiagonal matrix of size \(m\times m\), with coefficients \(\alpha_1,..., \alpha_n\) on the diagonal and coefficients \(\beta_1,...,\beta_{n-1}\) on the side-diagonalsn
- Parameters:
A (DNDarray) – 2D Hermitian (if complex) or symmetric positive-definite matrix. Only distribution along axis 0 is supported, i.e. A.split must be 0 or None.
m (int) – Number of Lanczos iterations
v0 (DNDarray, optional) – 1D starting vector of Euclidean norm 1. If not provided, a random vector will be used to start the algorithm
V_out (DNDarray, optional) – Output Matrix for the Krylow vectors, Shape = (n, m), dtype=A.dtype, must be initialized to zero
T_out (DNDarray, optional) – Output Matrix for the Tridiagonal matrix, Shape = (m, m), must be initialized to zero
- solve(A: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray, out: heat.core.dndarray.DNDarray | None = None) heat.core.dndarray.DNDarray[source]
Computes the solution of a square system of linear equations with a unique solution.
Letting \(\mathbb{K}\) be \(\mathbb{R}\) or \(\mathbb{C}\), this function computes the solution \(X \in \mathbb{K}^{n \times k}\) of the linear system associated to \(A \in \mathbb{K}^{n \times n}, B \in \mathbb{K}^{n \times k}\), which is defined as
\[AX = B\]Supports inputs of integer, float, double, cfloat and cdouble dtypes. Also supports batches of matrices, and if the inputs are batches of matrices then the output has the same batch dimensions.
Letting * be zero or more batch dimensions,
If
Ahas shape (*, n, n) andBhas shape (*, n) (a batch of vectors) or shape (*, n, k) (a batch of matrices or “multiple right-hand sides”), this function returns X of shape (*, n) or (*, n, k) respectively.Otherwise, if
Ahas shape (*, n, n) andBhas shape (n,) or (n, k),Bis broadcast to have shape (*, n) or (*, n, k) respectively. This function then returns the solution of the resulting batch of systems of linear equations.
Note
A and b may only be distributed in the batch dimensions. If both are split, they must be split along matching batch axes.
See also
torch.linalg.solve()is called under the hood on the local data. This docstring is also heavily inspired by the docstring of this function.- Parameters:
A (DNDarray) – Matrix to be inverted of shape (*, n, n) where * is zero or more batch dimensions
b (DNDarray) – Right-hand side of shape (*, n) or (*, n, k) or (n,) or (n, k)
out (DNDarray, optional) – Output Vector
Examples:: –
>>> A = ht.random.randn(3, 3) >>> b = ht.random.randn(3) >>> x = ht.linalg.solve(A, b) >>> ht.allclose(A @ x, b, atol=1e-5) True >>> A = ht.random.randn(2, 3, 3, split=0) >>> B = ht.random.randn(2, 3, 4, split=0) >>> X = ht.linalg.solve(A, B) >>> X.shape (2, 3, 4) >>> ht.allclose(A @ X, B, atol=1e-5) True >>> A = ht.random.randn(2, 3, 3, split=None) >>> B = ht.random.randn(2, 3, 4, split=2) >>> X = ht.linalg.solve(A, B) >>> X.split 2 >>> ht.allclose(A @ X, B, atol=1e-5) True
>>> A = ht.random.randn(2, 3, 3, split=0) >>> b = ht.random.randn(3, 1) >>> x = ht.linalg.solve(A, b) # b is broadcast to size (2, 3, 1) >>> x.shape (2, 3, 1) >>> x.split 0 >>> ht.allclose((A @ x).resplit_(None), b, atol=1e-5) True
- solve_triangular(A: heat.core.dndarray.DNDarray, b: heat.core.dndarray.DNDarray) heat.core.dndarray.DNDarray[source]
Solver for (possibly batched) upper triangular systems of linear equations: it returns x in Ax = b, where A is a (possibly batched) upper triangular matrix and b a (possibly batched) vector or matrix of suitable shape, both provided as input to the function. The implementation builts on the corresponding solver in PyTorch and implements an memory-distributed, MPI-parallel block-wise version thereof.
- Parameters:
A (DNDarray) – An upper triangular invertible square (n x n) matrix or a batch thereof, i.e. a
DNDarrayof shape (…, n, n).b (DNDarray) – a (possibly batched) n x k matrix, i.e. an DNDarray of shape (…, n, k), where the batch-dimensions denoted by … need to coincide with those of A. (Batched) Vectors have to be provided as … x n x 1 matrices and the split dimension of b must the second last dimension if not None.
Note
Since such a check might be computationally expensive, we do not check whether A is indeed upper triangular. If you require such a check, please open an issue on our GitHub page and request this feature.
- qr(A: heat.core.dndarray.DNDarray, mode: str = 'reduced', procs_to_merge: int = 2) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Calculates the QR decomposition of a 2D
DNDarray. Factor the matrixAas QR, whereQis orthonormal andRis upper-triangular. Ifmode = "reduced", function returnsQR(Q=Q, R=R), ifmode = "r"function returnsQR(Q=None, R=R)This function also works for batches of matrices; in this case, the last two dimensions of the input array are considered as the matrix dimensions. The output arrays have the same leading batch dimensions as the input array.
- Parameters:
A (DNDarray of shape (M, N), of shape (...,M,N) in the batched case) – Array which will be decomposed.
mode (str, optional) – default “reduced” returns Q and R with dimensions (M, min(M,N)) and (min(M,N), N). Potential batch dimensions are not modified. “r” returns only R, with dimensions (min(M,N), N).
procs_to_merge (int, optional) – This parameter is only relevant for split=0 (-2, in the batched case) and determines the number of processes to be merged at one step during the so-called TS-QR algorithm. The default is 2. Higher choices might be faster, but will probably result in higher memory consumption. 0 corresponds to merging all processes at once. We only recommend to modify this parameter if you are familiar with the TS-QR algorithm (see the references below).
Notes
The distribution schemes of
QandRdepend on that of the inputA.If
Ais distributed along the columns (A.split = 1), so will beQandR.If
Ais distributed along the rows (A.split = 0),Qtoo will have split=0.Rwon’t be distributed, i.e. R. split = None, ifAis tall-skinny, i.e., if the largest local chunk of data ofAhas at least as many rows as columns. Otherwise,Rwill be distributed along the rows as well, i.e., R.split = 0.
Note that the argument calc_q allowed in earlier Heat versions is no longer supported; calc_q = False is equivalent to mode = “r”. Unlike
numpy.linalg.qr(), ht.linalg.qr only supportsmode="reduced"ormode="r"for the moment, since “complete” may result in heavy memory usage.Heats QR function is built on top of PyTorchs QR function,
torch.linalg.qr(), using LAPACK (CPU) and MAGMA (CUDA) on the backend. Both cases split=0 and split=1 build on a column-block-wise version of stabilized Gram-Schmidt orthogonalization. For split=1 (-1, in the batched case), this is directly applied to the local arrays of the input array. For split=0, a tall-skinny QR (TS-QR) is implemented for the case of tall-skinny matrices (i.e., the largest local chunk of data has at least as many rows as columns), and extended to non tall-skinny matrices by applying a block-wise version of stabilized Gram-Schmidt orthogonalization.References
Basic information about QR factorization/decomposition can be found at, e.g.:
Gene H. Golub and Charles F. Van Loan. 1996. Matrix Computations (3rd Ed.).
For an extensive overview on TS-QR and its variants we refer to, e.g.,
Demmel, James, et al. “Communication-Optimal Parallel and Sequential QR and LU Factorizations.” SIAM Journal on Scientific Computing, vol. 34, no. 1, 2 Feb. 2012, pp. A206–A239., doi:10.1137/080731992.
- hsvd_rank(A: heat.core.dndarray.DNDarray, maxrank: int, compute_sv: bool = False, maxmergedim: int | None = None, safetyshift: int = 5, silent: bool = True) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, float] | Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray] | heat.core.dndarray.DNDarray[source]
Hierarchical SVD (hSVD) with prescribed truncation rank maxrank. If A = U diag(sigma) V^T is the true SVD of A, this routine computes an approximation for U[:,:maxrank] (and sigma[:maxrank], V[:,:maxrank]).
The accuracy of this approximation depends on the structure of A (“low-rank” is best) and appropriate choice of parameters.
One can expect a similar outcome from this routine as for sci-kit learn’s TruncatedSVD (with algorithm=’randomized’) although a different, determinstic algorithm is applied here. Hereby, the parameters n_components and n_oversamples (sci-kit learn) roughly correspond to maxrank and safetyshift (see below).
- Parameters:
A (DNDarray) – 2D-array (float32/64) of which the hSVD has to be computed.
maxrank (int) – truncation rank. (This parameter corresponds to n_components in sci-kit learn’s TruncatedSVD.)
compute_sv (bool, optional) – compute_sv=True implies that also Sigma and V.T are computed and returned. The default is False.
maxmergedim (int, optional) – maximal size of the concatenation matrices during the merging procedure. The default is None and results in an appropriate choice depending on the size of the local slices of A and maxrank. Too small choices for this parameter will result in failure if the maximal size of the concatenation matrices does not allow to merge at least two matrices. Too large choices for this parameter can cause memory errors if the resulting merging problem becomes too large.
safetyshift (int, optional) – Increases the actual truncation rank within the computations by a safety shift. The default is 5. (There is some similarity to n_oversamples in sci-kit learn’s TruncatedSVD.)
silent (bool, optional) – silent=False implies that some information on the computations are printed. The default is True.
- Returns:
if compute_sv=True: U, Sigma, V.T, a-posteriori error estimate for the reconstruction error ||A-U Sigma V^T ||_F / ||A||_F (computed according to [2] along the “true” merging tree). if compute_sv=False: U, a-posteriori error estimate
- Return type:
(Union[ Tuple[DNDarray, DNDarray, DNDarray, float], Tuple[DNDarray, DNDarray, DNDarray], DNDarray])
Notes
The size of the process local SVDs to be computed during merging is proportional to the non-split size of the input A and (maxrank + safetyshift). Therefore, conservative choice of maxrank and safetyshift is advised to avoid memory issues. Note that, as sci-kit learn’s randomized SVD, this routine is different from numpy.linalg.svd because not all singular values and vectors are computed and even those computed may be inaccurate if the input matrix exhibts a unfavorable structure.
Please note that “rank” in the context of SVD always refers to the number of singular values/vectors to compute (i.e., “rank” refers to the mathematical rank of a matrix). This is completely different from the notion of “(MPI-)rank”, i.e., the ID given to a process, in a parallel MPI-application.
See also
References
[1] Iwen, Ong. A distributed and incremental SVD algorithm for agglomerative data analysis on large networks. SIAM J. Matrix Anal. Appl., 37(4), 2016. [2] Himpe, Leibner, Rave. Hierarchical approximate proper orthogonal decomposition. SIAM J. Sci. Comput., 40 (5), 2018.
- hsvd_rtol(A: heat.core.dndarray.DNDarray, rtol: float, compute_sv: bool = False, maxrank: int | None = None, maxmergedim: int | None = None, safetyshift: int = 5, no_of_merges: int | None = None, silent: bool = True) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, float] | Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray] | heat.core.dndarray.DNDarray[source]
Hierchical SVD (hSVD) with prescribed upper bound on the relative reconstruction error. If A = U diag(sigma) V^T is the true SVD of A, this routine computes an approximation for U[:,:r] (and sigma[:r], V[:,:r]) such that the rel. reconstruction error ||A-U[:,:r] diag(sigma[:r]) V[:,:r]^T ||_F / ||A||_F does not exceed rtol.
The accuracy of this approximation depends on the structure of A (“low-rank” is best) and appropriate choice of parameters. This routine is similar to hsvd_rank with the difference that truncation is not performed after a fixed number (namly maxrank many) singular values but after such a number of singular values that suffice to capture a prescribed fraction of the amount of information contained in the input data (rtol).
- Parameters:
A (DNDarray) – 2D-array (float32/64) of which the hSVD has to be computed.
rtol (float) – desired upper bound on the relative reconstruction error ||A-U Sigma V^T ||_F / ||A||_F. This upper bound is processed into ‘local’ tolerances during the actual computations assuming the worst case scenario of a binary “merging tree”; therefore, the a-posteriori error for the relative error using the true “merging tree” (see output) may be significantly smaller than rtol. Prescription of maxrank or maxmergedim (disabled in default) can result in loss of desired precision, but can help to avoid memory issues.
compute_sv (bool, optional) – compute_sv=True implies that also Sigma and V.T are computed and returned. The default is False.
no_of_merges (int, optional) – Maximum number of processes to be merged at each step. If no further arguments are provided (see below), this completely determines the “merging tree” and may cause memory issues. The default is None and results in a binary merging tree. Note that no_of_merges dominates maxrank and maxmergedim in the sense that at most no_of_merges processes are merged even if maxrank and maxmergedim would allow merging more processes.
maxrank (int, optional) – maximal truncation rank. The default is None. Setting at least one of maxrank and maxmergedim is recommended to avoid memory issues, but can result in loss of desired precision. Setting only maxrank (and not maxmergedim) results in an appropriate default choice for maxmergedim depending on the size of the local slices of A and the value of maxrank.
maxmergedim (int, optional) – maximal size of the concatenation matrices during the merging procedure. The default is None and results in an appropriate choice depending on the size of the local slices of A and maxrank. The default is None. Too small choices for this parameter will result in failure if the maximal size of the concatenation matrices does not allow to merge at least two matrices. Too large choices for this parameter can cause memory errors if the resulting merging problem becomes too large. Setting at least one of maxrank and maxmergedim is recommended to avoid memory issues, but can result in loss of desired precision. Setting only maxmergedim (and not maxrank) results in an appropriate default choice for maxrank.
safetyshift (int, optional) – Increases the actual truncation rank within the computations by a safety shift. The default is 5.
silent (bool, optional) – silent=False implies that some information on the computations are printed. The default is True.
- Returns:
if compute_sv=True: U, Sigma, V.T, a-posteriori error estimate for the reconstruction error ||A-U Sigma V^T ||_F / ||A||_F (computed according to [2] along the “true” merging tree used in the computations). if compute_sv=False: U, a-posteriori error estimate
- Return type:
(Union[ Tuple[DNDarray, DNDarray, DNDarray, float], Tuple[DNDarray, DNDarray, DNDarray], DNDarray])
Notes
The maximum size of the process local SVDs to be computed during merging is proportional to the non-split size of the input A and (maxrank + safetyshift). Therefore, conservative choice of maxrank and safetyshift is advised to avoid memory issues. For similar reasons, prescribing only rtol and the number of processes to be merged in each step (without specifying maxrank or maxmergedim) may result in memory issues. Although prescribing maxrank is therefore strongly recommended to avoid memory issues, but may result in loss of desired precision (rtol). If this occures, a separate warning will be raised.
Note that this routine is different from numpy.linalg.svd because not all singular values and vectors are computed and even those computed may be inaccurate if the input matrix exhibts a unfavorable structure.
To avoid confusion, note that rtol in this routine does not have any similarity to tol in scikit learn’s TruncatedSVD.
Please note that “rank” in the context of SVD always refers to the number of singular values/vectors to compute (i.e., “rank” refers to the mathematical rank of a matrix). This is completely different from the notion of “(MPI-)rank”, i.e., the ID given to a process, in a parallel MPI-application.
See also
References
[1] Iwen, Ong. A distributed and incremental SVD algorithm for agglomerative data analysis on large networks. SIAM J. Matrix Anal. Appl., 37(4), 2016. [2] Himpe, Leibner, Rave. Hierarchical approximate proper orthogonal decomposition. SIAM J. Sci. Comput., 40 (5), 2018.
- hsvd(A: heat.core.dndarray.DNDarray, maxrank: int | None = None, maxmergedim: int | None = None, rtol: float | None = None, safetyshift: int = 0, no_of_merges: int | None = 2, compute_sv: bool = False, silent: bool = True, warnings_off: bool = False) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, float] | Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray] | heat.core.dndarray.DNDarray[source]
Computes an approximate truncated SVD of A utilizing a distributed hierarchical algorithm; see the references. The present function hsvd is a low-level routine, provides many options/parameters, but no default values, and is not recommended for usage by non-experts since conflicts arising from inappropriate parameter choice will not be caught. We strongly recommend to use the corresponding high-level functions hsvd_rank and hsvd_rtol instead.
Input
- A: DNDarray
2D-array (float32/64) of which hSVD has to be computed
- maxrank: int, optional
truncation rank of the SVD
- maxmergedim: int, optional
maximal size of the concatenation matrices when “merging” the local SVDs
- rtol: float, optional
upper bound on the relative reconstruction error ||A-U Sigma V^T ||_F / ||A||_F (may deteriorate due to other parameters)
- safetyshift: int, optional
shift that increases the actual truncation rank of the local SVDs during the computations in order to increase accuracy
- no_of_merges: int, optional
maximum number of local SVDs to be “merged” at one step
- compute_sv: bool, optional
determines whether to compute U, Sigma, V.T (compute_sv=True) or not (then U only)
- silent: bool, optional
determines whether to print infos on the computations performed (silent=False)
- warnings_off: bool, optional
switch on and off warnings that are not intended for the high-level routines based on this function
Notes
Please note that “rank” in the context of SVD always refers to the number of singular values/vectors to compute (i.e., “rank” refers to the mathematical rank of a matrix). This is completely different from the notion of “(MPI-)rank”, i.e., the ID given to a process, in a parallel MPI-application.
References
[1] Iwen, Ong. A distributed and incremental SVD algorithm for agglomerative data analysis on large networks. SIAM J. Matrix Anal. Appl., 37(4), 2016. [2] Himpe, Leibner, Rave. Hierarchical approximate proper orthogonal decomposition. SIAM J. Sci. Comput., 40 (5), 2018.
See also
- isvd(new_data: heat.core.dndarray.DNDarray, U_old: heat.core.dndarray.DNDarray, S_old: heat.core.dndarray.DNDarray, Vt_old: heat.core.dndarray.DNDarray, maxrank: int | None = None) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Incremental SVD (iSVD) for the addition of new data to an existing SVD. Given the SVD of an “old” matrix, \(X_\textnormal{old} = `U_\textnormal{old} \cdot S_\textnormal{old} \cdot V_\textnormal{old}^T\), and additional columns \(N\) ("new_data"), this routine computes (a possibly approximate) SVD of the extended matrix \(X_\textnormal{new} = [ X_\textnormal{old} | N]\).
- Parameters:
new_data (DNDarray) – 2D-array (float32/64) of columns that are added to the “old” SVD. It must hold new_data.split != 1 if U_old.split = 0.
U_old (DNDarray) – U-factor of the SVD of the “old” matrix, 2D-array (float32/64). It must hold U_old.split != 0 if new_data.split = 1.
S_old (DNDarray) – Sigma-factor of the SVD of the “old” matrix, 1D-array (float32/64)
Vt_old (DNDarray) – Transpose of V-factor of the SVD of the “old” matrix, 2D-array (float32/64)
maxrank (int, optional) – truncation rank of the SVD of the extended matrix. The default is None, i.e., no bound on the maximal rank is imposed.
Notes
Inexactness may arise due to truncation to maximal rank maxrank if rank of the data to be processed exceeds this rank. If you set maxrank to a high number (or None) in order to avoid inexactness, you may encounter memory issues. The implementation follows the approach described in Ref. [1], Sect. 2.
Please note that “rank” in the context of SVD always refers to the number of singular values/vectors to compute (i.e., “rank” refers to the mathematical rank of a matrix). This is completely different from the notion of “(MPI-)rank”, i.e., the ID given to a process, in a parallel MPI-application.
References
[1] Brand, M. (2006). Fast low-rank modifications of the thin singular value decomposition. Linear algebra and its applications, 415(1), 20-30.
- svd(A: heat.core.dndarray.DNDarray, full_matrices: bool = False, compute_uv: bool = True, qr_procs_to_merge: int = 2, r_max_zolopd: int = 8) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Computes the singular value decomposition of a matrix (the input array
A). For an input DNDarrayAof shape(M, N), the function returns DNDarraysU,S, andV.Tsuch thatA = U @ ht.diag(S) @ V.Twith shapes(M, min(M,N)),(min(M, N),), and(min(M,N),N), respectively, in the case thatcompute_uv=True, or only the vector containing the singular valuesSof shape(min(M, N),)in the case thatcompute_uv=False. By definition of the singular value decomposition, the matrixUis orthogonal, the matrixVis orthogonal, and the entries of the vector ``S``are non-negative real numbers.We refer to, e.g., wikipedia (https://en.wikipedia.org/wiki/Singular_value_decomposition) or to Gene H. Golub and Charles F. Van Loan, Matrix Computations (3rd Ed., 1996), for more detailed information on the singular value decomposition.
- Parameters:
A (ht.DNDarray) – The input array (2D, float32 or float64) for which the singular value decomposition is computed. Must be tall skinny (
M >> N) or short fat (M << n) for the current implementation; an implementation that covers the remaining cases is planned.full_matrices (bool, optional) – currently, only the default value
Falseis supported. This argument is included for compatibility with NumPy.compute_uv (bool, optional) – if
True, the matricesUandV.Tare computed and returned together with the singular valuesS. IfFalse, only the vectorScontaining the singular values is returned.qr_procs_to_merge (int, optional) – the number of processes to merge in the tall skinny QR decomposition that is applied if the input array is tall skinny (
M > N) or short fat (M < N). See the corresponding remarks for :func:heat.linalg.qrfor more details.r_max_zolopd (int, optional) – an internal parameter only relevant for the case that the input matrix is neither tall-skinny nor short-fat. This parameter is passed to the Zolotarev-Polar Decomposition and the symmetric eigenvalue decomposition that is applied in this case. See the documentation of :func:
heat.linalg.polaras well as of :func:heat.linalg.eighfor more details.
Notes
Unlike in NumPy, we currently do not support the option
full_matrices=True, since this can result in heavy memory consumption (in particular for tall skinny and short fat matrices) that should be avoided in the context Heat is designed for. If you nevertheless require this feature, please open an issue on GitHub.The algorithm used for the computation of the singular value depends on the shape of the input array
A. For tall and skinny matrices (M > N), the algorithm is based on the tall-skinny QR decomposition. For the remaining cases we use the approach based on Zolotarev-Polar Decomposition and a symmetric eigenvalue decomposition based on Zolotarev-Polar Decomposition; see Algorithm 5.3 in:Nakatsukasa, Y., & Freund, R. W. (2016). Computing fundamental matrix decompositions accurately via the matrix sign function in two iterations: The power of Zolotarev’s functions. SIAM Review, 58(3).
See also
heat.linalg.qr(),heat.linalg.polar(),heat.linalg.eigh()
- polar(A: heat.core.dndarray.DNDarray, r: int = None, calcH: bool = True, condition_estimate: float = 1e+16, silent: bool = True, r_max: int = 8) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Computes the so-called polar decomposition of the input 2D DNDarray
A, i.e., it returns the orthogonal matrixUand the symmetric, positive definite matrixHsuch thatA = U @ H.Input
- Aht.DNDarray,
The input matrix for which the polar decomposition is computed; must be two-dimensional, of data type float32 or float64, and must have at least as many rows as columns.
- rint, optional, default: None
The parameter r used in the Zolotarev-PD algorithm; if provided, must be an integer between 1 and 8 that divides the number of MPI processes. Higher values of r lead to faster convergence, but memory consumption is proportional to r. If not provided, the largest 1 <= r <= r_max that divides the number of MPI processes is chosen.
- calcHbool, optional, default: True
If True, the function returns the symmetric, positive definite matrix H. If False, only the orthogonal matrix U is returned.
- condition_estimatefloat, optional, default: 1.e16.
This argument allows to provide an estimate for the condition number of the input matrix
A, if such estimate is already known. If a positive number greater than 1., this value is used as an estimate for the condition number of A. If smaller or equal than 1., the condition number is estimated internally. The default value of 1.e16 is the worst case scenario considered in [1].- silentbool, optional, default: True
If True, the function does not print any output. If False, some information is printed during the computation.
- r_maxint, optional, default: 8
See the description of r for the meaning; r_max is only taken into account if r is not provided.
Notes
The implementation follows Algorithm 5.1 in Reference [1]; however, instead of switching from QR to Cholesky decomposition depending on the condition number, we stick to QR decomposition in all iterations.
References
[1] Nakatsukasa, Y., & Freund, R. W. (2016). Computing Fundamental Matrix Decompositions Accurately via the Matrix Sign Function in Two Iterations: The Power of Zolotarev’s Functions. SIAM Review, 58(3), DOI: https://doi.org/10.1137/140990334.
- eigh(A: heat.core.dndarray.DNDarray, r_max_zolopd: int = 8, silent: bool = True) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Computes the symmetric eigenvalue decomposition of a symmetric n x n - matrix A, provided as a DNDarray.
The function returns DNDarrays Lambda (shape (n,) with split = 0) and V (shape (n,n)) such that A = V @ diag(Lambda) @ V^T, where Lambda contains the eigenvalues of A and V is an orthonormal matrix containing the corresponding eigenvectors as columns.
- Parameters:
A (DNDarray) – The input matrix. Must be symmetric.
r_max_zolopd (int, optional) – This is a hyperparameter for the computation of the polar decomposition via
heat.linalg.polar()which is applied multiple times in this function. See the documentation ofheat.linalg.polar()for more details on its meaning and the respective default value.silent (bool, optional) – If True (default), suppresses output messages; otherwise, some information on the recursion is printed to the console.
Notes
Unlike the
torch.linalg.eigh()function, the eigenvalues are returned in descending order. Note that no check of symmetry is performed on the input matrix A; thus, applying this function to a non-symmetric matrix may result in unpredictable behaviour without a specific error message pointing to this issue.The algorithm used for the computation of the symmetric eigenvalue decomposition is based on the Zolotarev polar decomposition; see Algorithm 5.2 in:
Nakatsukasa, Y., & Freund, R. W. (2016). Computing fundamental matrix decompositions accurately via the matrix sign function in two iterations: The power of Zolotarev’s functions. SIAM Review, 58(3).
See also
heat.linalg.polar()
- rsvd(A: heat.core.dndarray.DNDarray, svd_rank: int, n_oversamples: int = 10, power_iter: int = 0, qr_procs_to_merge: int = 2) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray] | Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Randomized SVD (rSVD) with prescribed truncation rank svd_rank. If \(A = U \operatorname{diag}(S) V^T\) is the true SVD of A, this routine computes an approximation for U[:,:svd_rank] (and S[:svd_rank], V.T[:,:svd_rank]).
The accuracy of this approximation depends on the structure of A (“low-rank” is best) and appropriate choice of parameters.
- Parameters:
A (DNDarray) – 2D-array (float32/64) of which the rSVD has to be computed.
svd_rank (int) – truncation rank of the SVD. (This parameter corresponds to n_components in scikit-learn’s TruncatedSVD.)
n_oversamples (int, optional) – number of oversamples. The default is 10.
power_iter (int, optional) – number of power iterations. The default is 0. Choosing power_iter > 0 can improve the accuracy of the SVD approximation in the case of slowly decaying singular values, but increases the computational cost.
qr_procs_to_merge (int, optional) – number of processes to merge at each step of QR decomposition in the power iteration (if power_iter > 0). The default is 2. See the corresponding remarks for
heat.linalg.qr()for more details.
Notes
Memory requirements: the SVD computation of a matrix of size (svd_rank + n_oversamples) x (svd_rank + n_oversamples) must fit into the memory of a single process. The implementation follows Algorithm 4.4 (randomized range finder) and Algorithm 5.1 (direct SVD) in [1].
Please note that “rank” in the context of SVD always refers to the number of singular values/vectors to compute (i.e., “rank” refers to the mathematical rank of a matrix). This is completely different from the notion of “(MPI-)rank”, i.e., the ID given to a process, in a parallel MPI-application.
References
[1] Halko, N., Martinsson, P. G., & Tropp, J. A. (2011). Finding structure with randomness: Probabilistic algorithms for constructing approximate matrix decompositions. SIAM review, 53(2), 217-288.
- reigh(A: heat.core.dndarray.DNDarray, n_eigenvalues: int, n_oversamples: int = 10, power_iter: int = 0, qr_procs_to_merge: int = 2) Tuple[heat.core.dndarray.DNDarray, heat.core.dndarray.DNDarray][source]
Randomized eigenvalue decomposition (rEIGH). Only the top n_eigenvalues eigenvalues (ordered by magnitude) and corresponding eigenvectors are computed.
- Parameters:
A (DNDarray) – 2D-array (float32/64) of which the rEIGH has to be computed. Must be symmetric.
n_eigenvalues (int) – number of eigenvalues to compute. (This parameter corresponds to n_components in scikit-learn’s PCA.)
n_oversamples (int, optional) – number of oversamples. The default is 10.
power_iter (int, optional) – number of power iterations. The default is 0. Choosing power_iter > 0 can improve the accuracy of the eigenvalue approximation in the case of slowly decaying eigenvalues, but increases the computational cost.
qr_procs_to_merge (int, optional) – number of processes to merge at each step of QR decomposition in the power iteration (if power_iter > 0). The default is 2. See the corresponding remarks for
heat.linalg.qr()for more details.
Notes
Memory requirements: the symmetric eigenvalue decomposition of a matrix of size (n_eigenvalues + n_oversamples) x (n_eigenvalues + n_oversamples) must fit into the memory of a single process. The implementation follows Algorithm 4.4 (randomized range finder) and Algorithm 5.3 (eigenvalue decomposition from an SVD) in [1].
References
[1] Halko, N., Martinsson, P. G., & Tropp, J. A. (2011). Finding structure with randomness: Probabilistic algorithms for constructing approximate matrix decompositions. SIAM review, 53(2), 217-288.