Basicops operators (WIP)#

  1. lazylinop.wip.basicops.average()

  2. lazylinop.wip.basicops.mean()

  3. lazylinop.wip.basicops.khatri_rao()

lazylinop.wip.basicops.average(op, axis=0, weights=None)#

Computes the weighted average LazyLinOp of op along the specified axis.

Args:
op: LazyLinOp or compatible linear operator

The operator whose average is computed.

axis: int, optional

Axis along which the average is computed (0 or 1).

weights: None or numpy.ndarray (vector of scalars), optional
  • weights[i] is the weight of the row i (resp. column i) if axis=0 (resp. if axis=1).

  • If None (default) all columns/rows have the same weight.

Returns:

LazyLinOp for mean of op.

Examples:
>>> import lazylinop as lz
>>> import lazylinop.wip.basicops as lzb
>>> lzo1 = lz.ones((2, 3)) * 2
>>> lzo2 = lz.ones((2, 3)) * 3
>>> lzo = lz.vstack((lzo1, lzo2))
>>> w0 = [1, .5, 1.5, 2]
>>> a1 = lzb.average(lzo, axis=0, weights=w0)
>>> print(a1)
<1x3 LazyLinOp with unspecified dtype>
>>> print(a1.toarray())
[[2.7 2.7 2.7]]
>>> np_a1 = np.average(lzo.toarray(), axis=0, weights=w0)
>>> print(np.allclose(a1.toarray(), np_a1))
True
>>> w1 = [1, 2.2, 3]
>>> a2 = lzb.average(lzo, axis=1, weights=w1)
>>> print(a2.toarray())
[[2.]
 [2.]
 [3.]
 [3.]]
>>> np_a2 = np.average(lzo.toarray(), axis=1, weights=w1)
>>> print(np.allclose(a2.toarray().ravel(), np_a2))
True
lazylinop.wip.basicops.mean(op, axis=0, meth='ones')#

Computes the arithmetic mean LazyLinOp of op along the specified axis.

Args:
op: LazyLinOp or compatible linear operator

The operator whose mean is computed.

axis: int, optional

Axis along which the mean is computed (0 or 1).

meth: str

The method used to compute the mean.

  • 'ones': op is multiplied by appropriate ones().

  • 'avg': average() is called with same weights for every columns/rows.

Returns:

LazyLinOp for mean of op.

Example:
>>> import lazylinop
>>> import lazylinop.wip.basicops as lz
>>> lzo = lazylinop.ones((2, 3))
>>> lzo_m = lz.mean(lzo, axis=0)
>>> print(lzo_m)
<1x3 LazyLinOp with unspecified dtype>
>>> print(lzo_m.toarray())
[[1. 1. 1.]]
>>> lzo2 = lzo * 2
>>> lzo_m2 = lz.mean(lzo2, axis=1)
>>> print(lzo_m2.toarray())
[[2.]
 [2.]]
lazylinop.wip.basicops.khatri_rao(A, B, column=True, backend='auto')#

Returns a LazyLinOp `L for the Khatri-Rao product. Khatri-Rao product is a column-wise Kronecker product we denote \(K_c\) while the row-wise product is \(K_r\). If \(A\) and \(B\) are two matrices then \(K_c(A,~B)^T = K_r(A^T,~B^T)\). Therefore, we easily get the adjoint of the column-wize Khatri-Rao product. If matrix \(A\) shape is \((M,~N)\) and shape of \(B\) is \((P,~N)\), the shape of the Khatri-Rao product \(K_c\) is \((MP,~N)\). The function does not explicitly compute the matrix. It uses the trick \(K_c(A,~B)x = vec(Bdiag(x)A.T)\) where \(x\) is a vector of length \(N\) and \(diag(x)\) a diagonal matrix of size \(N^2\).

Shape of L is \((MP,~N)\).

Args:
A: np.ndarray or LazyLinOp

First matrix, it can be LazyLinOp or NumPy array.

B: np.ndarray or LazyLinOp

Second matrix, it can be LazyLinOp or NumPy array.

column: bool, optional

  • True (default) computes Khatri-Rao product column-wize.

  • False computes row-wize product.

backend: str, optional

  • ‘scipy’ uses SciPy Khatri-Rao product. It does not work for row-wise product. If A or B is a LazyLinOp, the backend computes dense matrix before to compute Khatri-Rao product. It could be very slow.

  • ‘lazylinop’ uses Khatri-Rao vector product trick.

  • ‘auto’ uses the best backend.

Returns:

LazyLinOp

Examples:
>>> import numpy as np
>>> import scipy as sp
>>> from lazylinop.wip.basicops import khatri_rao
>>> A = np.full((2, 2), 1)
>>> B = np.eye(3, 2, k=0)
>>> x = np.random.rand(2)
>>> K = khatri_rao(A, B)
>>> S = sp.linalg.khatri_rao(A, B)
>>> np.allclose(K @ x, S @ x)
True