def v_init(array: LargeArrayType, v: Union[da.Array, np.ndarray], log: int = 0) -> Union[da.Array, Tuple[da.Array, dict]]: """Computes estimation of left Eigenvectors of `a` from an initial guess `v` Parameters ---------- array : LargeArrayType array of which the left eigenvectors will be estimated v : array_like Initial guess of right right hand eigenvectors of `array`. Usually will come from a SVD of a subarray of `array` log : bool See logging in `time_param_log` Returns ------- U : Dask Array estimation of left Eigenvectors of `array` """ x_k = array.dot(v) U, _, _ = tsqr(x_k, compute_svd=True) if log: return U, {} else: return U
def _sub_svd(array: LargeArrayType, sub_array: LargeArrayType, k: int = 5, log: int = 1) -> Union[da.core.Array, Tuple[da.core.Array, dict]]: """Helper function for computing SVD of `sub_array` Parameters ---------- array : LargeArrayType array of which the top `k` left eigenvectors will be estimated sub_array : LargeArrayType array of which the top `k` left eigenvectors will be calculated k : int number of eigenvectors of `sub_array` to compute log : bool See logging in `time_param_log` Returns ------- U : Dask Array estimation of left Eigenvectors of `array` """ # VSU' <--- SVD of A' V, _, _ = tsqr(sub_array, compute_svd=True) # SVD of A' -> VSU' U = v_init(array, V[:, :k]) U = U.rechunk({0: 'auto', 1: -1}) if log: return U, {} else: return U
def test_tsqr(m, n, chunks, error_type): mat = np.random.rand(m, n) data = da.from_array(mat, chunks=chunks, name="A") # qr m_q = m n_q = min(m, n) m_r = n_q n_r = n # svd m_u = m n_u = min(m, n) n_s = n_q m_vh = n_q n_vh = n d_vh = max(m_vh, n_vh) # full matrix returned if error_type is None: # test QR q, r = tsqr(data) assert_eq((m_q, n_q), q.shape) # shape check assert_eq((m_r, n_r), r.shape) # shape check assert_eq(mat, da.dot(q, r)) # accuracy check assert_eq(np.eye(n_q, n_q), da.dot(q.T, q)) # q must be orthonormal assert_eq(r, da.triu(r.rechunk(r.shape[0]))) # r must be upper triangular # test SVD u, s, vh = tsqr(data, compute_svd=True) s_exact = np.linalg.svd(mat)[1] assert_eq(s, s_exact) # s must contain the singular values assert_eq((m_u, n_u), u.shape) # shape check assert_eq((n_s, ), s.shape) # shape check assert_eq((d_vh, d_vh), vh.shape) # shape check assert_eq(np.eye(n_u, n_u), da.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(d_vh, d_vh), da.dot(vh, vh.T)) # vh must be orthonormal assert_eq(mat, da.dot(da.dot(u, da.diag(s)), vh[:n_q])) # accuracy check else: with pytest.raises(error_type): q, r = tsqr(data) with pytest.raises(error_type): u, s, vh = tsqr(data, compute_svd=True)
def test_tsqr(m, n, chunks, error_type): mat = np.random.rand(m, n) data = da.from_array(mat, chunks=chunks, name='A') m_q = m n_q = min(m, n) m_r = n_q n_r = n m_qtq = n_q if error_type is None: q, r = tsqr(data) assert_eq((m_q, n_q), q.shape) # shape check assert_eq((m_r, n_r), r.shape) # shape check assert_eq(mat, da.dot(q, r)) # accuracy check assert_eq(np.eye(m_qtq, m_qtq), da.dot(q.T, q)) # q must be orthonormal assert_eq(r, da.triu(r.rechunk(r.shape[0]))) # r must be upper triangular else: with pytest.raises(error_type): q, r = tsqr(data)
def test_tsqr(m, n, chunks, error_type): mat = np.random.rand(m, n) data = da.from_array(mat, chunks=chunks, name='A') # qr m_q = m n_q = min(m, n) m_r = n_q n_r = n # svd m_u = m n_u = min(m, n) n_s = n_q m_vh = n_q n_vh = n d_vh = max(m_vh, n_vh) # full matrix returned if error_type is None: # test QR q, r = tsqr(data) assert_eq((m_q, n_q), q.shape) # shape check assert_eq((m_r, n_r), r.shape) # shape check assert_eq(mat, da.dot(q, r)) # accuracy check assert_eq(np.eye(n_q, n_q), da.dot(q.T, q)) # q must be orthonormal assert_eq(r, da.triu(r.rechunk(r.shape[0]))) # r must be upper triangular # test SVD u, s, vh = tsqr(data, compute_svd=True) s_exact = np.linalg.svd(mat)[1] assert_eq(s, s_exact) # s must contain the singular values assert_eq((m_u, n_u), u.shape) # shape check assert_eq((n_s,), s.shape) # shape check assert_eq((d_vh, d_vh), vh.shape) # shape check assert_eq(np.eye(n_u, n_u), da.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(d_vh, d_vh), da.dot(vh, vh.T)) # vh must be orthonormal assert_eq(mat, da.dot(da.dot(u, da.diag(s)), vh[:n_q])) # accuracy check else: with pytest.raises(error_type): q, r = tsqr(data) with pytest.raises(error_type): u, s, vh = tsqr(data, compute_svd=True)
def subspace_to_V(x: ArrayType, a: Optional["LargeArrayType"] = None, k: Optional[int] = None) -> ArrayType: x_t = a.T.dot(x) V, _, _ = tsqr(x_t, compute_svd=True) V = V.T if k: V = svd_to_trunc_svd(v=V, k=k) return V
def test_tsqr_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, chunks=(10, n), name='A') q, r = tsqr(data) q = np.array(q) r = np.array(r) assert np.allclose(mat, np.dot(q, r)) # accuracy check assert np.allclose(np.eye(n, n), np.dot(q.T, q)) # q must be orthonormal assert np.all(r == np.triu(r)) # r must be upper triangular
def test_tsqr_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, blockshape=(10, n), name='A') q, r = tsqr(data) q = np.array(q) r = np.array(r) assert np.allclose(mat, np.dot(q, r)) # accuracy check assert np.allclose(np.eye(n, n), np.dot(q.T, q)) # q must be orthonormal assert np.all(r == np.triu(r)) # r must be upper triangular
def test_tsqr_irregular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = da.from_array(mat, chunks=(3, n), name='A')[1:] mat2 = mat[1:, :] q, r = tsqr(data) q = np.array(q) r = np.array(r) assert_eq(mat2, np.dot(q, r)) # accuracy check assert_eq(np.eye(n, n), np.dot(q.T, q)) # q must be orthonormal assert_eq(r, np.triu(r)) # r must be upper triangular
def test_tsqr_irregular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, chunks=(3, n), name='A')[1:] mat2 = mat[1:, :] q, r = tsqr(data) q = np.array(q) r = np.array(r) assert np.allclose(mat2, np.dot(q, r)) # accuracy check assert np.allclose(np.eye(n, n), np.dot(q.T, q)) # q must be orthonormal assert np.all(r == np.triu(r)) # r must be upper triangular
def test_tsqr_svd_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, blockshape=(10, n), name='A') u, s, v = tsqr(data, compute_svd=True) u = np.array(u) s = np.array(s) v = np.array(v) assert np.allclose(mat, np.dot(u, np.dot(np.diag(s), v))) # accuracy check assert np.allclose(np.eye(n, n), np.dot(u.T, u)) # u must be orthonormal assert np.allclose(np.eye(n, n), np.dot(v.T, v)) # v must be orthonormal assert np.allclose(s, np.linalg.svd(mat)[1]) # s must contain the singular
def test_tsqr_svd_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = da.from_array(mat, chunks=(10, n), name='A') u, s, vt = tsqr(data, compute_svd=True) usvt = da.dot(u, da.dot(da.diag(s), vt)) s_exact = np.linalg.svd(mat)[1] assert_eq(mat, usvt) # accuracy check assert_eq(np.eye(n, n), da.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(n, n), da.dot(vt, vt.T)) # v must be orthonormal assert_eq(s, s_exact) # s must contain the singular values
def test_tsqr_svd_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, chunks=(10, n), name='A') u, s, v = tsqr(data, compute_svd=True) u = np.array(u) s = np.array(s) v = np.array(v) assert np.allclose(mat, np.dot(u, np.dot(np.diag(s), v))) # accuracy check assert np.allclose(np.eye(n, n), np.dot(u.T, u)) # u must be orthonormal assert np.allclose(np.eye(n, n), np.dot(v.T, v)) # v must be orthonormal assert np.allclose(s, np.linalg.svd(mat)[1]) # s must contain the singular
def test_tsqr_svd_regular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = da.from_array(mat, chunks=(10, n), name='A') u, s, vt = tsqr(data, compute_svd=True) u = np.array(u) s = np.array(s) vt = np.array(vt) usvt = np.dot(u, np.dot(np.diag(s), vt)) s_exact = np.linalg.svd(mat)[1] assert_eq(mat, usvt) # accuracy check assert_eq(np.eye(n, n), np.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(n, n), np.dot(vt, vt.T)) # v must be orthonormal assert_eq(s, s_exact) # s must contain the singular values
def test_tsqr_svd_irregular_blocks(): m, n = 20, 10 mat = np.random.rand(m, n) data = from_array(mat, chunks=(3, n), name='A')[1:] mat2 = mat[1:, :] u, s, vt = tsqr(data, compute_svd=True) u = np.array(u) s = np.array(s) vt = np.array(vt) usvt = np.dot(u, np.dot(np.diag(s), vt)) s_exact = np.linalg.svd(mat2)[1] assert np.allclose(mat2, usvt) # accuracy check assert np.allclose(np.eye(n, n), np.dot(u.T, u)) # u must be orthonormal assert np.allclose(np.eye(n, n), np.dot(vt, vt.T)) # v must be orthonormal assert np.allclose(s, s_exact) # s must contain the singular values
def test_tsqr_uncertain(m_min, n_max, chunks, vary_rows, vary_cols, error_type): mat = np.random.rand(m_min * 2, n_max) m, n = m_min * 2, n_max mat[0:m_min, 0] += 1 _c0 = mat[:, 0] _r0 = mat[0, :] c0 = da.from_array(_c0, chunks=m_min, name="c") r0 = da.from_array(_r0, chunks=n_max, name="r") data = da.from_array(mat, chunks=chunks, name="A") if vary_rows: data = data[c0 > 0.5, :] mat = mat[_c0 > 0.5, :] m = mat.shape[0] if vary_cols: data = data[:, r0 > 0.5] mat = mat[:, _r0 > 0.5] n = mat.shape[1] # qr m_q = m n_q = min(m, n) m_r = n_q n_r = n # svd m_u = m n_u = min(m, n) n_s = n_q m_vh = n_q n_vh = n d_vh = max(m_vh, n_vh) # full matrix returned if error_type is None: # test QR q, r = tsqr(data) q = q.compute() # because uncertainty r = r.compute() assert_eq((m_q, n_q), q.shape) # shape check assert_eq((m_r, n_r), r.shape) # shape check assert_eq(mat, np.dot(q, r)) # accuracy check assert_eq(np.eye(n_q, n_q), np.dot(q.T, q)) # q must be orthonormal assert_eq(r, np.triu(r)) # r must be upper triangular # test SVD u, s, vh = tsqr(data, compute_svd=True) u = u.compute() # because uncertainty s = s.compute() vh = vh.compute() s_exact = np.linalg.svd(mat)[1] assert_eq(s, s_exact) # s must contain the singular values assert_eq((m_u, n_u), u.shape) # shape check assert_eq((n_s, ), s.shape) # shape check assert_eq((d_vh, d_vh), vh.shape) # shape check assert_eq(np.eye(n_u, n_u), np.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(d_vh, d_vh), np.dot(vh, vh.T)) # vh must be orthonormal assert_eq(mat, np.dot(np.dot(u, np.diag(s)), vh[:n_q])) # accuracy check else: with pytest.raises(error_type): q, r = tsqr(data) with pytest.raises(error_type): u, s, vh = tsqr(data, compute_svd=True)
def subspace_to_SVD( x: ArrayType, a: Optional["LargeArrayType"] = None, k: Optional[int] = None, full_v: bool = False, sqrt_s: bool = True, log: int = 0 ) -> Union[Tuple[ArrayType, ArrayType, ArrayType], Tuple[ArrayType, ArrayType, ArrayType, dict]]: """Computes Truncated SVD of an array using an active subspace. Let A be a {N \times P} matrix Let x be a subspace of AA' U, S, V = subspace_to_SVD(x) USV.shape = (N, k) U, S, V = subspace_to_SVD(x, A, full_v=True) USV.shape == AA'.shape USV is low rank approximation to AA' Parameters ---------- x : array_like, shape (N, K) or (N, ) Active subspace of aa' a : array_like, shape (N, P), optional Array to be factored into USV from active subspace of x k : int Number of components of SVD to return 1 <= k <= x.shape[1] full_v : bool Whether to return: V as a {K by K} matrix if full_v is False Or; V as a {K by P} matrix if full_v is True Requires a to be given as matrix sqrt_s : bool Whether to return the square root of the singular values of x. log : int >= 0 Indicator in how many layers to log Returns ------- u : (N, k) dask array Unitary array. Top k = min(K, k {if supplied}) left singular vectors of x s : (k, ) dask array Vector of of Top k = min(K, k {if supplied}) singular values in decreasing order v : (k, P) or (k, k) dask array Unitary array. Top k = min(K, k {if supplied}) right singular vectors of x. If full_v is True right singular vectors will be in (k, P) If full_v is false right singular vectors will be in (k, k) """ flog = {} U, S, V = tsqr(x, compute_svd=True) if full_v: V = subspace_to_V(x, a, k) if sqrt_s: S = np.sqrt(S) if k: U, S, V = svd_to_trunc_svd(U, S, V, k=k) if log: return U, S, V, flog else: return U, S, V
def _solution_step(self, x, **kwargs): q, _ = tsqr(x) x = self.array.dot(self.array.T.dot(q)) if self.factor: x = x / self.factor return x.persist()
def test_tsqr_uncertain(m_min, n_max, chunks, vary_rows, vary_cols, error_type): mat = np.random.rand(m_min * 2, n_max) m, n = m_min * 2, n_max mat[0:m_min, 0] += 1 _c0 = mat[:, 0] _r0 = mat[0, :] c0 = da.from_array(_c0, chunks=m_min, name='c') r0 = da.from_array(_r0, chunks=n_max, name='r') data = da.from_array(mat, chunks=chunks, name='A') if vary_rows: data = data[c0 > 0.5, :] mat = mat[_c0 > 0.5, :] m = mat.shape[0] if vary_cols: data = data[:, r0 > 0.5] mat = mat[:, _r0 > 0.5] n = mat.shape[1] # qr m_q = m n_q = min(m, n) m_r = n_q n_r = n # svd m_u = m n_u = min(m, n) n_s = n_q m_vh = n_q n_vh = n d_vh = max(m_vh, n_vh) # full matrix returned if error_type is None: # test QR q, r = tsqr(data) q = q.compute() # because uncertainty r = r.compute() assert_eq((m_q, n_q), q.shape) # shape check assert_eq((m_r, n_r), r.shape) # shape check assert_eq(mat, np.dot(q, r)) # accuracy check assert_eq(np.eye(n_q, n_q), np.dot(q.T, q)) # q must be orthonormal assert_eq(r, np.triu(r)) # r must be upper triangular # test SVD u, s, vh = tsqr(data, compute_svd=True) u = u.compute() # because uncertainty s = s.compute() vh = vh.compute() s_exact = np.linalg.svd(mat)[1] assert_eq(s, s_exact) # s must contain the singular values assert_eq((m_u, n_u), u.shape) # shape check assert_eq((n_s,), s.shape) # shape check assert_eq((d_vh, d_vh), vh.shape) # shape check assert_eq(np.eye(n_u, n_u), np.dot(u.T, u)) # u must be orthonormal assert_eq(np.eye(d_vh, d_vh), np.dot(vh, vh.T)) # vh must be orthonormal assert_eq(mat, np.dot(np.dot(u, np.diag(s)), vh[:n_q])) # accuracy check else: with pytest.raises(error_type): q, r = tsqr(data) with pytest.raises(error_type): u, s, vh = tsqr(data, compute_svd=True)