def _steadystate_power_liouvillian(L, ss_args, has_mkl=0): """Creates modified Liouvillian for power based SS methods. """ perm = None perm2 = None rev_perm = None n = L.shape[0] if ss_args['solver'] == 'mkl': L = L.data - (1e-15) * sp.eye(n, n, format='csr') kind = 'csr' else: L = L.data.tocsc() - (1e-15) * sp.eye(n, n, format='csc') kind = 'csc' if settings.debug: old_band = sp_bandwidth(L)[0] old_pro = sp_profile(L)[0] logger.debug('Original bandwidth: %i' % old_band) logger.debug('Original profile: %i' % old_pro) if ss_args['use_wbm']: if settings.debug: logger.debug('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() with warnings.catch_warnings(): warnings.filterwarnings( "ignore", "qutip graph functions are deprecated", DeprecationWarning, ) perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], kind) ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end - _wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] wbm_pro = sp_profile(L)[0] logger.debug('WBM bandwidth: %i' % wbm_band) logger.debug('WBM profile: %i' % wbm_pro) if ss_args['use_rcm']: if settings.debug: logger.debug('Calculating Reverse Cuthill-Mckee ordering...') ss_args['info']['perm'].append('rcm') _rcm_start = time.time() perm2 = sp.csgraph.reverse_cuthill_mckee(L) _rcm_end = time.time() ss_args['info']['rcm_time'] = _rcm_end - _rcm_start rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, kind) if settings.debug: new_band = sp_bandwidth(L)[0] new_pro = sp_profile(L)[0] logger.debug('RCM bandwidth: %i' % new_band) logger.debug('Bandwidth reduction factor: %f' % (old_band / new_band)) logger.debug('RCM profile: %i' % new_pro) logger.debug('Profile reduction factor: %f' % (old_pro / new_pro)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def _steadystate_LU_liouvillian(L, ss_args, has_mkl=0): """Creates modified Liouvillian for LU based SS methods. """ perm = None perm2 = None rev_perm = None n = int(np.sqrt(L.shape[0])) form = 'csr' if has_mkl: L = L.data + sp.csr_matrix( (ss_args['weight']*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) else: form = 'csc' L = L.data.tocsc() + sp.csc_matrix( (ss_args['weight']*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) if settings.debug: old_band = sp_bandwidth(L)[0] old_pro = sp_profile(L)[0] logger.debug('Orig. NNZ: %i' % L.nnz) if ss_args['use_rcm']: logger.debug('Original bandwidth: %i' % old_band) if ss_args['use_wbm']: if settings.debug: logger.debug('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], form) ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end-_wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] logger.debug('WBM bandwidth: %i' % wbm_band) if ss_args['use_rcm']: if settings.debug: logger.debug('Calculating Reverse Cuthill-Mckee ordering...') _rcm_start = time.time() perm2 = reverse_cuthill_mckee(L) _rcm_end = time.time() rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, form) ss_args['info']['perm'].append('rcm') ss_args['info']['rcm_time'] = _rcm_end-_rcm_start if settings.debug: rcm_band = sp_bandwidth(L)[0] rcm_pro = sp_profile(L)[0] logger.debug('RCM bandwidth: %i' % rcm_band) logger.debug('Bandwidth reduction factor: %f' % (old_band/rcm_band)) logger.debug('Profile reduction factor: %f' % (old_pro/rcm_pro)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def test_graph_maximum_bipartite_matching(): "Graph: Maximum Bipartite Matching" A = sp.diags(np.ones(25), offsets=0, format='csc') perm = np.random.permutation(25) perm2 = np.random.permutation(25) B = sp_permute(A, perm, perm2) perm = maximum_bipartite_matching(B) C = sp_permute(B, perm, []) assert_equal(any(C.diagonal() == 0), False)
def _pseudo_inverse_sparse(L, rhoss, method='splu', use_umfpack=False, use_rcm=False): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csc') I = sp.eye(N * N, N * N, format='csc') Q = I - P if use_rcm: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csc').tocsc() Q = sp_permute(Q, perm, perm, 'csc') permc_spec = 'NATURAL' else: A = L.data.tocsc() A.sort_indices() permc_spec = 'COLAMD' if method == 'spsolve': sp.linalg.use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack) LIQ = sp.linalg.spsolve(A, Q) elif method == 'splu': lu = sp.linalg.splu(A, permc_spec=permc_spec) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=permc_spec, fill_factor=10, drop_tol=1e-8) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csc_matrix(Q * LIQ) if use_rcm: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csc') return Qobj(R, dims=L.dims)
def _steadystate_power_liouvillian(L, ss_args, has_mkl=0): """Creates modified Liouvillian for power based SS methods. """ perm = None perm2 = None rev_perm = None n = L.shape[0] if ss_args['solver'] == 'mkl': L = L.data - (1e-15) * sp.eye(n, n, format='csr') kind = 'csr' else: L = L.data.tocsc() - (1e-15) * sp.eye(n, n, format='csc') kind = 'csc' orig_nnz = L.nnz if settings.debug: old_band = sp_bandwidth(L)[0] old_pro = sp_profile(L)[0] logger.debug('Original bandwidth: %i' % old_band) logger.debug('Original profile: %i' % old_pro) if ss_args['use_wbm']: if settings.debug: logger.debug('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], kind) ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end-_wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] wbm_pro = sp_profile(L)[0] logger.debug('WBM bandwidth: %i' % wbm_band) logger.debug('WBM profile: %i' % wbm_pro) if ss_args['use_rcm']: if settings.debug: logger.debug('Calculating Reverse Cuthill-Mckee ordering...') ss_args['info']['perm'].append('rcm') _rcm_start = time.time() perm2 = reverse_cuthill_mckee(L) _rcm_end = time.time() ss_args['info']['rcm_time'] = _rcm_end-_rcm_start rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, kind) if settings.debug: new_band = sp_bandwidth(L)[0] new_pro = sp_profile(L)[0] logger.debug('RCM bandwidth: %i' % new_band) logger.debug('Bandwidth reduction factor: %f' % (old_band/new_band)) logger.debug('RCM profile: %i' % new_pro) logger.debug('Profile reduction factor: %f' % (old_pro/new_pro)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def test_sparse_symmetric_permute(): "Sparse: Symmetric Permute" # CSR version A = rand_dm(25, 0.5) perm = np.random.permutation(25) x = sp_permute(A.data, perm, perm).toarray() z = _permutateIndexes(A.full(), perm, perm) assert_equal((x - z).all(), 0) # CSC version B = A.data.tocsc() y = sp_permute(B, perm, perm).toarray() assert_equal((y - z).all(), 0)
def _pseudo_inverse_sparse(L, rhoss, method='splu', **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csc') I = sp.eye(N * N, N * N, format='csc') Q = I - P if pseudo_args['use_rcm']: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csc').tocsc() Q = sp_permute(Q, perm, perm, 'csc') else: A = L.data.tocsc() A.sort_indices() if method == 'spsolve': sp.linalg.use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack) LIQ = sp.linalg.spsolve(A, Q) elif method == 'splu': lu = sp.linalg.splu(A, permc_spec=pseudo_args['permc_spec'], diag_pivot_thresh=pseudo_args['diag_pivot_thresh'], options=dict(ILU_MILU=pseudo_args['ILU_MILU'])) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=pseudo_args['permc_spec'], fill_factor=pseudo_args['fill_factor'], drop_tol=pseudo_args['drop_tol']) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csc_matrix(Q * LIQ) if pseudo_args['use_rcm']: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csc') return Qobj(R, dims=L.dims)
def _pseudo_inverse_sparse(L, rhoss, method='splu', **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csr') I = sp.eye(N*N, N*N, format='csr') Q = I - P if pseudo_args['use_rcm']: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csr') Q = sp_permute(Q, perm, perm, 'csr') else: if not settings.has_mkl: A = L.data.tocsc() A.sort_indices() if method == 'splu': if settings.has_mkl: LIQ = mkl_spsolve(A,Q.toarray()) else: lu = sp.linalg.splu(A, permc_spec=pseudo_args['permc_spec'], diag_pivot_thresh=pseudo_args['diag_pivot_thresh'], options=dict(ILU_MILU=pseudo_args['ILU_MILU'])) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=pseudo_args['permc_spec'], fill_factor=pseudo_args['fill_factor'], drop_tol=pseudo_args['drop_tol']) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csr_matrix(Q * LIQ) if pseudo_args['use_rcm']: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csr') return Qobj(R, dims=L.dims)
def _pseudo_inverse_sparse(L, rhoss, method='splu', use_umfpack=False, use_rcm=False): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = sp.kron(rhoss_vec.data, tr_op_vec.data.T, format='csc') I = sp.eye(N*N, N*N, format='csc') Q = I - P if use_rcm: perm = reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm, 'csc').tocsc() Q = sp_permute(Q, perm, perm, 'csc') permc_spec = 'NATURAL' else: A = L.data.tocsc() A.sort_indices() permc_spec = 'COLAMD' if method == 'spsolve': sp.linalg.use_solver(assumeSortedIndices=True, useUmfpack=use_umfpack) LIQ = sp.linalg.spsolve(A, Q) elif method == 'splu': lu = sp.linalg.splu(A, permc_spec=permc_spec) LIQ = lu.solve(Q.toarray()) elif method == 'spilu': lu = sp.linalg.spilu(A, permc_spec=permc_spec, fill_factor=10, drop_tol=1e-8) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csc_matrix(Q * LIQ) if use_rcm: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csc') return Qobj(R, dims=L.dims)
def test_sparse_symmetric_reverse_permute(): "Sparse: Symmetric Reverse Permute" # CSR version A = rand_dm(25, 0.5) perm = np.random.permutation(25) x = sp_permute(A.data, perm, perm) B = sp_reverse_permute(x, perm, perm) assert_equal((A.full() - B.toarray()).all(), 0) # CSC version B = A.data.tocsc() perm = np.random.permutation(25) x = sp_permute(B, perm, perm) B = sp_reverse_permute(x, perm, perm) assert_equal((A.full() - B.toarray()).all(), 0)
def test_graph_weighted_matching(): "Graph: Weighted Bipartite Matching" A = sp.rand(25, 25, density=0.1, format='csc') a_len = len(A.data) A.data = np.ones(a_len) d = np.arange(0, 25) + 2 B = sp.diags(d, offsets=0, format='csc') A = A+B perm = np.random.permutation(25) perm2 = np.random.permutation(25) B = sp_permute(A, perm, perm2) perm = weighted_bipartite_matching(B) C = sp_permute(B, perm, []) assert_equal(np.sum(A.diagonal()), np.sum(C.diagonal()))
def _steadystate_power_liouvillian(L, ss_args): """Creates modified Liouvillian for power based SS methods. """ perm = None perm2 = None rev_perm = None n = L.shape[0] L = L.data.tocsc() - (1e-15) * sp.eye(n, n, format='csc') orig_nnz = L.nnz if settings.debug: old_band = sp_bandwidth(L)[0] old_pro = sp_profile(L)[0] logger.debug('Original bandwidth: %i' % old_band) logger.debug('Original profile: %i' % old_pro) if ss_args['use_wbm']: if settings.debug: logger.debug('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], 'csc') ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end - _wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] wbm_pro = sp_profile(L)[0] logger.debug('WBM bandwidth: %i' % wbm_band) logger.debug('WBM profile: %i' % wbm_pro) if ss_args['use_rcm']: if settings.debug: logger.debug('Calculating Reverse Cuthill-Mckee ordering...') ss_args['info']['perm'].append('rcm') _rcm_start = time.time() perm2 = reverse_cuthill_mckee(L) _rcm_end = time.time() ss_args['info']['rcm_time'] = _rcm_end - _rcm_start rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, 'csc') if settings.debug: new_band = sp_bandwidth(L)[0] new_pro = sp_profile(L)[0] logger.debug('RCM bandwidth: %i' % new_band) logger.debug('Bandwidth reduction factor: %f' % (old_band / new_band)) logger.debug('RCM profile: %i' % new_pro) logger.debug('Profile reduction factor: %f' % (old_pro / new_pro)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def _steadystate_LU_liouvillian(L, ss_args): """Creates modified Liouvillian for LU based SS methods. """ perm = None perm2 = None rev_perm = None dims = L.dims[0] n = prod(L.dims[0][0]) L = L.data.tocsc() + sp.csc_matrix( (ss_args['weight']*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) if settings.debug: old_band = sp_bandwidth(L)[0] print('NNZ:', L.nnz) if ss_args['use_rcm']: print('Original bandwidth:', old_band) if ss_args['use_wbm']: if settings.debug: print('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], 'csc') ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end-_wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] print('WBM bandwidth:', wbm_band) if ss_args['use_rcm']: if settings.debug: print('Calculating Reverse Cuthill-Mckee ordering...') _rcm_start = time.time() perm2 = reverse_cuthill_mckee(L) _rcm_end = time.time() rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, 'csc') ss_args['info']['perm'].append('rcm') ss_args['info']['rcm_time'] = _rcm_end-_rcm_start if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth:', rcm_band) print('Bandwidth reduction factor:', round( old_band/rcm_band, 1)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def _steadystate_LU_liouvillian(L, ss_args): """Creates modified Liouvillian for LU based SS methods. """ perm = None perm2 = None rev_perm = None dims = L.dims[0] n = prod(L.dims[0][0]) L = L.data.tocsc() + sp.csc_matrix( (ss_args['weight'] * np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n**2, n**2)) if settings.debug: old_band = sp_bandwidth(L)[0] print('NNZ:', L.nnz) if ss_args['use_rcm']: print('Original bandwidth:', old_band) if ss_args['use_wbm']: if settings.debug: print('Calculating Weighted Bipartite Matching ordering...') _wbm_start = time.time() perm = weighted_bipartite_matching(L) _wbm_end = time.time() L = sp_permute(L, perm, [], 'csc') ss_args['info']['perm'].append('wbm') ss_args['info']['wbm_time'] = _wbm_end - _wbm_start if settings.debug: wbm_band = sp_bandwidth(L)[0] print('WBM bandwidth:', wbm_band) if ss_args['use_rcm']: if settings.debug: print('Calculating Reverse Cuthill-Mckee ordering...') _rcm_start = time.time() perm2 = reverse_cuthill_mckee(L) _rcm_end = time.time() rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, 'csc') ss_args['info']['perm'].append('rcm') ss_args['info']['rcm_time'] = _rcm_end - _rcm_start if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth:', rcm_band) print('Bandwidth reduction factor:', round(old_band / rcm_band, 1)) L.sort_indices() return L, perm, perm2, rev_perm, ss_args
def test_sp_bandwidth(): "Sparse: Bandwidth" # Bandwidth test 1 A = create(25) + destroy(25) + qeye(25) band = sp_bandwidth(A.data) assert_equal(band[0], 3) assert_equal(band[1] == band[2] == 1, 1) # Bandwidth test 2 A = np.array([[1, 0, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 1, 0, 1], [0, 0, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1, 0, 1]], dtype=np.int32) A = sp.csr_matrix(A) out1 = sp_bandwidth(A) assert_equal(out1[0], 13) assert_equal(out1[1] == out1[2] == 6, 1) # Bandwidth test 3 perm = reverse_cuthill_mckee(A) B = sp_permute(A, perm, perm) out2 = sp_bandwidth(B) assert_equal(out2[0], 5) assert_equal(out2[1] == out2[2] == 2, 1) # Asymmetric bandwidth test A = destroy(25) + qeye(25) out1 = sp_bandwidth(A.data) assert_equal(out1[0], 2) assert_equal(out1[1], 0) assert_equal(out1[2], 1)
def test_column_permutation(): "Graph: Column Permutation" A = sp.rand(5, 5, 0.25, format='csc') perm = column_permutation(A) B = sp_permute(A, [], perm) counts = np.diff(B.indptr) assert_equal(np.all(np.argsort(counts) == np.arange(5)), True)
def _steadystate_eigen(L, ss_args): """ Internal function for solving the steady state problem by finding the eigenvector corresponding to the zero eigenvalue of the Liouvillian using ARPACK. """ if settings.debug: print('Starting Eigen solver...') dims = L.dims[0] shape = prod(dims[0]) L = L.data.tocsc() if ss_args['use_rcm']: if settings.debug: old_band = sp_bandwidth(L)[0] print('Original bandwidth:', old_band) perm = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth:', rcm_band) print('Bandwidth reduction factor:', round(old_band/rcm_band, 1)) eigval, eigvec = eigs(L, k=1, sigma=1e-15, tol=ss_args['tol'], which='LM', maxiter=ss_args['maxiter']) if ss_args['use_rcm']: eigvec = eigvec[np.ix_(rev_perm,)] data = vec2mat(eigvec) data = 0.5 * (data + data.conj().T) out = Qobj(data, dims=dims, isherm=True) return out/out.tr()
def _steadystate_direct_sparse(L, ss_args): """ Direct solver that uses scipy sparse matrices """ if settings.debug: print('Starting direct solver...') dims = L.dims[0] weight = np.abs(L.data.data.max()) n = prod(L.dims[0][0]) b = np.zeros((n ** 2, 1), dtype=complex) b[0, 0] = weight L = L.data + sp.csr_matrix( (weight*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) L.sort_indices() use_solver(assumeSortedIndices=True, useUmfpack=ss_args['use_umfpack']) if ss_args['use_rcm']: perm = symrcm(L) L = sp_permute(L, perm, perm) b = b[np.ix_(perm,)] v = spsolve(L, b) if ss_args['use_rcm']: rev_perm = np.argsort(perm) v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) return Qobj(data, dims=dims, isherm=True)
def test_sp_bandwidth(): "Sparse: Bandwidth" # Bandwidth test 1 A = create(25)+destroy(25)+qeye(25) band = sp_bandwidth(A.data) assert_equal(band[0], 3) assert_equal(band[1] == band[2] == 1, 1) # Bandwidth test 2 A = np.array([[1, 0, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 1, 0, 1], [0, 0, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1, 0, 1]], dtype=np.int32) A = sp.csr_matrix(A) out1 = sp_bandwidth(A) assert_equal(out1[0], 13) assert_equal(out1[1] == out1[2] == 6, 1) # Bandwidth test 3 perm = reverse_cuthill_mckee(A) B = sp_permute(A, perm, perm) out2 = sp_bandwidth(B) assert_equal(out2[0], 5) assert_equal(out2[1] == out2[2] == 2, 1) # Asymmetric bandwidth test A = destroy(25)+qeye(25) out1 = sp_bandwidth(A.data) assert_equal(out1[0], 2) assert_equal(out1[1], 0) assert_equal(out1[2], 1)
def _steadystate_iterative(L, ss_args): """ Iterative steady state solver using the LGMRES algorithm and a sparse incomplete LU preconditioner. """ if settings.debug: print('Starting GMRES solver...') dims = L.dims[0] n = prod(L.dims[0][0]) b = np.zeros(n ** 2) b[0] = 1.0 L = L.data.tocsc() + sp.csc_matrix( (1e-1 * np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) if ss_args['use_rcm']: if settings.debug: print('Original bandwidth ', sp_bandwidth(L)) perm = symrcm(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') b = b[np.ix_(perm,)] if settings.debug: print('RCM bandwidth ', sp_bandwidth(L)) L.sort_indices() if ss_args['M'] is None and ss_args['use_precond']: M = _iterative_precondition(L, n, ss_args['drop_tol'], ss_args['diag_pivot_thresh'], ss_args['fill_factor']) v, check = gmres(L, b, tol=ss_args['tol'], M=ss_args['M'], maxiter=ss_args['maxiter']) if check > 0: raise Exception("Steadystate solver did not reach tolerance after " + str(check) + " steps.") elif check < 0: raise Exception( "Steadystate solver failed with fatal error: " + str(check) + ".") if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) return Qobj(data, dims=dims, isherm=True)
def _steadystate_eigen(L, ss_args): """ Internal function for solving the steady state problem by finding the eigenvector corresponding to the zero eigenvalue of the Liouvillian using ARPACK. """ ss_args['info'].pop('weight', None) if settings.debug: logger.debug('Starting Eigen solver.') dims = L.dims[0] L = L.data.tocsc() if ss_args['use_rcm']: ss_args['info']['perm'].append('rcm') if settings.debug: old_band = sp_bandwidth(L)[0] logger.debug('Original bandwidth: %i' % old_band) perm = sp.csgraph.reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') if settings.debug: rcm_band = sp_bandwidth(L)[0] logger.debug('RCM bandwidth: %i' % rcm_band) logger.debug('Bandwidth reduction factor: %f' % (old_band / rcm_band)) _eigen_start = time.time() eigval, eigvec = eigs(L, k=1, sigma=1e-15, tol=ss_args['tol'], which='LM', maxiter=ss_args['maxiter']) _eigen_end = time.time() ss_args['info']['solution_time'] = _eigen_end - _eigen_start if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(L * eigvec, np.inf) if ss_args['use_rcm']: eigvec = eigvec[np.ix_(rev_perm, )] _temp = vec2mat(eigvec) data = dense2D_to_fastcsr_fmode(_temp, _temp.shape[0], _temp.shape[1]) data = 0.5 * (data + data.H) out = Qobj(data, dims=dims, isherm=True) if ss_args['return_info']: return out / out.tr(), ss_args['info'] else: return out / out.tr()
def _steadystate_eigen(L, ss_args): """ Internal function for solving the steady state problem by finding the eigenvector corresponding to the zero eigenvalue of the Liouvillian using ARPACK. """ ss_args['info'].pop('weight', None) if settings.debug: print('Starting Eigen solver...') dims = L.dims[0] shape = prod(dims[0]) L = L.data.tocsc() if ss_args['use_rcm']: ss_args['info']['perm'].append('rcm') if settings.debug: old_band = sp_bandwidth(L)[0] print('Original bandwidth:', old_band) perm = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth:', rcm_band) print('Bandwidth reduction factor:', round(old_band / rcm_band, 1)) _eigen_start = time.time() eigval, eigvec = eigs(L, k=1, sigma=1e-15, tol=ss_args['tol'], which='LM', maxiter=ss_args['maxiter']) _eigen_end = time.time() ss_args['info']['solution_time'] = _eigen_end - _eigen_start if ss_args['use_rcm']: eigvec = eigvec[np.ix_(rev_perm, )] data = vec2mat(eigvec) data = 0.5 * (data + data.conj().T) out = Qobj(data, dims=dims, isherm=True) if ss_args['return_info']: return out / out.tr(), ss_args['info'] else: return out / out.tr()
def test_graph_rcm_boost(): "Graph: Reverse Cuthill-McKee Ordering (boost)" M = np.zeros((10, 10)) M[0, [3, 5]] = 1 M[1, [2, 4, 6, 9]] = 1 M[2, [3, 4]] = 1 M[3, [5, 8]] = 1 M[4, 6] = 1 M[5, [6, 7]] = 1 M[6, 7] = 1 M = M+M.T M = sp.csr_matrix(M) perm = reverse_cuthill_mckee(M, 1) ans_perm = np.array([9, 7, 6, 4, 1, 5, 0, 2, 3, 8]) assert_equal((perm - ans_perm).all(), 0) P = sp_permute(M, perm, perm) bw = sp_bandwidth(P) assert_equal(bw[2], 4)
def _steadystate_eigen(L, ss_args): """ Internal function for solving the steady state problem by finding the eigenvector corresponding to the zero eigenvalue of the Liouvillian using ARPACK. """ ss_args['info'].pop('weight', None) if settings.debug: logger.debug('Starting Eigen solver.') dims = L.dims[0] L = L.data.tocsc() if ss_args['use_rcm']: ss_args['info']['perm'].append('rcm') if settings.debug: old_band = sp_bandwidth(L)[0] logger.debug('Original bandwidth: %i' % old_band) perm = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') if settings.debug: rcm_band = sp_bandwidth(L)[0] logger.debug('RCM bandwidth: %i' % rcm_band) logger.debug('Bandwidth reduction factor: %f' % (old_band/rcm_band)) _eigen_start = time.time() eigval, eigvec = eigs(L, k=1, sigma=1e-15, tol=ss_args['tol'], which='LM', maxiter=ss_args['maxiter']) _eigen_end = time.time() ss_args['info']['solution_time'] = _eigen_end - _eigen_start if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(L*eigvec, np.inf) if ss_args['use_rcm']: eigvec = eigvec[np.ix_(rev_perm,)] _temp = vec2mat(eigvec) data = dense2D_to_fastcsr_fmode(_temp, _temp.shape[0], _temp.shape[1]) data = 0.5 * (data + data.H) out = Qobj(data, dims=dims, isherm=True) if ss_args['return_info']: return out/out.tr(), ss_args['info'] else: return out/out.tr()
def test_sparse_nonsymmetric_reverse_permute(): "Sparse: Nonsymmetric Reverse Permute" # CSR square array check A = rand_dm(25, 0.5) rperm = np.random.permutation(25) cperm = np.random.permutation(25) x = sp_permute(A.data, rperm, cperm) B = sp_reverse_permute(x, rperm, cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSC square array check A = rand_dm(25, 0.5) rperm = np.random.permutation(25) cperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, rperm, cperm) B = sp_reverse_permute(x, rperm, cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSR column vector check A = coherent(25, 1) rperm = np.random.permutation(25) x = sp_permute(A.data, rperm, []) B = sp_reverse_permute(x, rperm, []) assert_equal((A.full() - B.toarray()).all(), 0) # CSC column vector check A = coherent(25, 1) rperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, rperm, []) B = sp_reverse_permute(x, rperm, []) assert_equal((A.full() - B.toarray()).all(), 0) # CSR row vector check A = coherent(25, 1).dag() cperm = np.random.permutation(25) x = sp_permute(A.data, [], cperm) B = sp_reverse_permute(x, [], cperm) assert_equal((A.full() - B.toarray()).all(), 0) # CSC row vector check A = coherent(25, 1).dag() cperm = np.random.permutation(25) B = A.data.tocsc() x = sp_permute(B, [], cperm) B = sp_reverse_permute(x, [], cperm) assert_equal((A.full() - B.toarray()).all(), 0)
def _pseudo_inverse_sparse(L, rhoss, w=None, **pseudo_args): """ Internal function for computing the pseudo inverse of an Liouvillian using sparse matrix methods. See pseudo_inverse for details. """ N = np.prod(L.dims[0][0]) rhoss_vec = operator_to_vector(rhoss) tr_op = tensor([identity(n) for n in L.dims[0][0]]) tr_op_vec = operator_to_vector(tr_op) P = zcsr_kron(rhoss_vec.data, tr_op_vec.data.T) I = sp.eye(N * N, N * N, format='csr') Q = I - P if w is None: L = 1.0j * (1e-15) * spre(tr_op) + L else: if w != 0.0: L = 1.0j * w * spre(tr_op) + L else: L = 1.0j * (1e-15) * spre(tr_op) + L if pseudo_args['use_rcm']: perm = sp.csgraph.reverse_cuthill_mckee(L.data) A = sp_permute(L.data, perm, perm) Q = sp_permute(Q, perm, perm) else: if ss_args['solver'] == 'scipy': A = L.data.tocsc() A.sort_indices() if pseudo_args['method'] == 'splu': if settings.has_mkl: A = L.data.tocsr() A.sort_indices() LIQ = mkl_spsolve(A, Q.toarray()) else: pspec = pseudo_args['permc_spec'] diag_p_thresh = pseudo_args['diag_pivot_thresh'] pseudo_args = pseudo_args['ILU_MILU'] lu = sp.linalg.splu(A, permc_spec=pspec, diag_pivot_thresh=diag_p_thresh, options=dict(ILU_MILU=pseudo_args)) LIQ = lu.solve(Q.toarray()) elif pseudo_args['method'] == 'spilu': lu = sp.linalg.spilu(A, permc_spec=pseudo_args['permc_spec'], fill_factor=pseudo_args['fill_factor'], drop_tol=pseudo_args['drop_tol']) LIQ = lu.solve(Q.toarray()) else: raise ValueError("unsupported method '%s'" % method) R = sp.csr_matrix(Q * LIQ) if pseudo_args['use_rcm']: rev_perm = np.argsort(perm) R = sp_permute(R, rev_perm, rev_perm, 'csr') return Qobj(R, dims=L.dims)
def _steadystate_direct_sparse(L, ss_args): """ Direct solver that uses scipy sparse matrices """ if settings.debug: print('Starting direct LU solver...') dims = L.dims[0] n = prod(L.dims[0][0]) b = np.zeros(n ** 2, dtype=complex) b[0] = ss_args['weight'] L = L.data.tocsc() + sp.csc_matrix( (ss_args['weight']*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) L.sort_indices() use_solver(assumeSortedIndices=True, useUmfpack=ss_args['use_umfpack']) if not ss_args['use_umfpack']: # Use superLU solver orig_nnz = L.nnz if settings.debug: old_band = sp_bandwidth(L)[0] print('Original NNZ:', orig_nnz) if ss_args['use_rcm']: print('Original bandwidth:', old_band) if ss_args['use_wbm']: perm = weighted_bipartite_matching(L) L = sp_permute(L, perm, [], 'csc') b = b[np.ix_(perm,)] if ss_args['use_rcm']: perm2 = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, 'csc') b = b[np.ix_(perm2,)] if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth:', rcm_band) print('Bandwidth reduction factor:', round( old_band/rcm_band, 1)) lu = splu(L, permc_spec=ss_args['permc_spec'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) v = lu.solve(b) if settings.debug and _scipy_check: L_nnz = lu.L.nnz U_nnz = lu.U.nnz print('L NNZ:', L_nnz, ';', 'U NNZ:', U_nnz) print('Fill factor:', (L_nnz+U_nnz)/orig_nnz) else: # Use umfpack solver v = spsolve(L, b) if (not ss_args['use_umfpack']) and ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) return Qobj(data, dims=dims, isherm=True)
def _steadystate_iterative(L, ss_args): """ Iterative steady state solver using the GMRES or LGMRES algorithm and a sparse incomplete LU preconditioner. """ if settings.debug: print('Starting '+ss_args['method']+' solver...') dims = L.dims[0] n = prod(L.dims[0][0]) b = np.zeros(n ** 2) b[0] = ss_args['weight'] L = L.data.tocsc() + sp.csc_matrix( (ss_args['weight']*np.ones(n), (np.zeros(n), [nn * (n + 1) for nn in range(n)])), shape=(n ** 2, n ** 2)) if ss_args['use_wbm']: perm = weighted_bipartite_matching(L) L = sp_permute(L, perm, [], 'csc') b = b[np.ix_(perm,)] if ss_args['use_rcm']: if settings.debug: old_band = sp_bandwidth(L)[0] print('Original bandwidth ', old_band) perm2 = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm2) L = sp_permute(L, perm2, perm2, 'csc') b = b[np.ix_(perm2,)] if settings.debug: rcm_band = sp_bandwidth(L)[0] print('RCM bandwidth ', rcm_band) print('Bandwidth reduction factor:', round(old_band/rcm_band, 1)) L.sort_indices() if ss_args['M'] is None and ss_args['use_precond']: ss_args['M'] = _iterative_precondition(L, n, ss_args) # Select iterative solver type if ss_args['method'] == 'iterative-gmres': v, check = gmres(L, b, tol=ss_args['tol'], M=ss_args['M'], maxiter=ss_args['maxiter']) elif ss_args['method'] == 'iterative-lgmres': v, check = lgmres(L, b, tol=ss_args['tol'], M=ss_args['M'], maxiter=ss_args['maxiter']) else: raise Exception("Invalid iterative solver method.") if check > 0: raise Exception("Steadystate solver did not reach tolerance after " + str(check) + " steps.") elif check < 0: raise Exception( "Steadystate solver failed with fatal error: " + str(check) + ".") if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) return Qobj(data, dims=dims, isherm=True)
def _steadystate_power(L, ss_args): """ Inverse power method for steady state solving. """ ss_args['info'].pop('weight', None) if settings.debug: logger.debug('Starting iterative inverse-power method solver.') tol = ss_args['tol'] maxiter = ss_args['maxiter'] use_solver(assumeSortedIndices=True) rhoss = Qobj() sflag = issuper(L) if sflag: rhoss.dims = L.dims[0] else: rhoss.dims = [L.dims[0], 1] n = prod(rhoss.shape) L = L.data.tocsc() - (1e-15) * sp.eye(n, n, format='csc') L.sort_indices() orig_nnz = L.nnz # start with all ones as RHS v = np.ones(n, dtype=complex) if ss_args['use_rcm']: if settings.debug: old_band = sp_bandwidth(L)[0] logger.debug('Original bandwidth: %i' % old_band) perm = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') v = v[np.ix_(perm, )] if settings.debug: new_band = sp_bandwidth(L)[0] logger.debug('RCM bandwidth: %i' % new_band) logger.debug('Bandwidth reduction factor: %f' % round(old_band / new_band, 2)) _power_start = time.time() # Get LU factors lu = splu(L, permc_spec=ss_args['permc_spec'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) if settings.debug and _scipy_check: L_nnz = lu.L.nnz U_nnz = lu.U.nnz logger.debug('L NNZ: %i ; U NNZ: %i' % (L_nnz, U_nnz)) logger.debug('Fill factor: %f' % ((L_nnz + U_nnz) / orig_nnz)) it = 0 while (la.norm(L * v, np.inf) > tol) and (it < maxiter): v = lu.solve(v) v = v / la.norm(v, np.inf) it += 1 if it >= maxiter: raise Exception('Failed to find steady state after ' + str(maxiter) + ' iterations') _power_end = time.time() ss_args['info']['solution_time'] = _power_end - _power_start ss_args['info']['iterations'] = it if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(L * v, np.inf) if settings.debug: logger.debug('Number of iterations: %i' % it) if ss_args['use_rcm']: v = v[np.ix_(rev_perm, )] # normalise according to type of problem if sflag: trow = sp.eye(rhoss.shape[0], rhoss.shape[0], format='coo') trow = sp_reshape(trow, (1, n)) data = v / sum(trow.dot(v)) else: data = data / la.norm(v) data = sp.csr_matrix(vec2mat(data)) rhoss.data = 0.5 * (data + data.conj().T) rhoss.isherm = True if ss_args['return_info']: return rhoss, ss_args['info'] else: return rhoss
def _steadystate_power(L, ss_args): """ Inverse power method for steady state solving. """ ss_args['info'].pop('weight', None) if settings.debug: print('Starting iterative inverse-power method solver...') tol = ss_args['tol'] maxiter = ss_args['maxiter'] use_solver(assumeSortedIndices=True) rhoss = Qobj() sflag = issuper(L) if sflag: rhoss.dims = L.dims[0] else: rhoss.dims = [L.dims[0], 1] n = prod(rhoss.shape) L = L.data.tocsc() - (1e-15) * sp.eye(n, n, format='csc') L.sort_indices() orig_nnz = L.nnz # start with all ones as RHS v = np.ones(n,dtype=complex) if ss_args['use_rcm']: if settings.debug: old_band = sp_bandwidth(L)[0] print('Original bandwidth:', old_band) perm = reverse_cuthill_mckee(L) rev_perm = np.argsort(perm) L = sp_permute(L, perm, perm, 'csc') v = v[np.ix_(perm,)] if settings.debug: new_band = sp_bandwidth(L)[0] print('RCM bandwidth:', new_band) print('Bandwidth reduction factor:', round(old_band/new_band, 2)) # Get LU factors lu = splu(L, permc_spec=ss_args['permc_spec'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) if settings.debug and _scipy_check: L_nnz = lu.L.nnz U_nnz = lu.U.nnz print('L NNZ:', L_nnz, ';', 'U NNZ:', U_nnz) print('Fill factor:', (L_nnz+U_nnz)/orig_nnz) _power_start = time.time() it = 0 while (la.norm(L * v, np.inf) > tol) and (it < maxiter): v = lu.solve(v) v = v / la.norm(v, np.inf) it += 1 if it >= maxiter: raise Exception('Failed to find steady state after ' + str(maxiter) + ' iterations') _power_end = time.time() ss_args['info']['solution_time'] = _power_end-_power_start ss_args['info']['iterations'] = it if settings.debug: print('Number of iterations:', it) if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] # normalise according to type of problem if sflag: trow = sp.eye(rhoss.shape[0], rhoss.shape[0], format='coo') trow = sp_reshape(trow, (1, n)) data = v / sum(trow.dot(v)) else: data = data / la.norm(v) data = sp.csr_matrix(vec2mat(data)) rhoss.data = 0.5 * (data + data.conj().T) rhoss.isherm = True if ss_args['return_info']: return rhoss, ss_args['info'] else: return rhoss