def eigenSystemRealizationAlgorithmWithDataCorrelation(markov_parameters, state_dimension): # Sizes p = int(np.floor((len(markov_parameters) - 1) / 2)) xi = p tau = gamma = 1 + 2 * xi * tau if markov_parameters[0].shape == (): (output_dimension, input_dimension) = (1, 1) else: (output_dimension, input_dimension) = markov_parameters[0].shape # Hankel matrices H(0) and H(1) H0 = np.zeros([p * output_dimension, p * input_dimension]) H1 = np.zeros([p * output_dimension, p * input_dimension]) for i in range(p): for j in range(p): H0[i * output_dimension:(i + 1) * output_dimension, j * input_dimension:(j + 1) * input_dimension] = markov_parameters[i + j + 1] H1[i * output_dimension:(i + 1) * output_dimension, j * input_dimension:(j + 1) * input_dimension] = markov_parameters[i + j + 2] # SVD H(0) print(H0.shape) (R, sigma, St) = LA.svd(H0, full_matrices=True) Sigma = np.diag(sigma) # Matrices Rn, Sn, Sigman Rn = R[:, 0:state_dimension] Snt = St[0:state_dimension, :] Sigman = Sigma[0:state_dimension, 0:state_dimension] # Identified matrices A_id = np.matmul(matpow(Sigman, -1/2), np.matmul(np.transpose(Rn), np.matmul(H1, np.matmul(np.transpose(Snt), matpow(Sigman, -1/2))))) B_temp = np.matmul(matpow(Sigman, 1/2), Snt) B_id = B_temp[:, 0:input_dimension] C_temp = np.matmul(Rn, matpow(Sigman, 1/2)) C_id = C_temp[0:output_dimension, :] D_id = markov_parameters[0] def A(tk): return A_id def B(tk): return B_id def C(tk): return C_id def D(tk): return D_id return A, B, C, D, H0, H1, R, Sigma, St, Rn, Sigman, Snt
def test_watrous_bounds(): # Test cases borrowed from qutip, # https://github.com/qutip/qutip/blob/master/qutip/tests/test_metrics.py # which were in turn generated using QuantumUtils for MATLAB # (https://goo.gl/oWXhO9) by Christopher Granade choi0 = kraus2choi(I_MAT) choi1 = kraus2choi(X_MAT) wbounds = dm.watrous_bounds(choi0 - choi1) assert wbounds[0] / 2 <= 2.0 or np.isclose(wbounds[0] / 2, 2.0, rtol=1e-2) assert wbounds[1] / 2 >= 2.0 or np.isclose(wbounds[1] / 2, 2.0, rtol=1e-2) turns_dnorm = [[1.000000e-03, 3.141591e-03], [3.100000e-03, 9.738899e-03], [1.000000e-02, 3.141463e-02], [3.100000e-02, 9.735089e-02], [1.000000e-01, 3.128689e-01], [3.100000e-01, 9.358596e-01]] for turns, target in turns_dnorm: choi0 = kraus2choi(X_MAT) choi1 = kraus2choi(matpow(X_MAT, 1 + turns)) wbounds = dm.watrous_bounds(choi0 - choi1) assert wbounds[0] / 2 <= target or np.isclose( wbounds[0] / 2, target, rtol=1e-2) assert wbounds[1] / 2 >= target or np.isclose( wbounds[1] / 2, target, rtol=1e-2) hadamard_mixtures = [[1.000000e-03, 2.000000e-03], [3.100000e-03, 6.200000e-03], [1.000000e-02, 2.000000e-02], [3.100000e-02, 6.200000e-02], [1.000000e-01, 2.000000e-01], [3.100000e-01, 6.200000e-01]] for p, target in hadamard_mixtures: chan0 = kraus2superop(I_MAT) * (1 - p) + kraus2superop(H_MAT) * p chan1 = kraus2superop(I_MAT) choi0 = superop2choi(chan0) choi1 = superop2choi(chan1) wbounds = dm.watrous_bounds(choi0 - choi1) assert wbounds[0] / 2 <= target or np.isclose( wbounds[0] / 2, target, rtol=1e-2) assert wbounds[1] / 2 >= target or np.isclose( wbounds[1] / 2, target, rtol=1e-2) choi0 = kraus2choi(I_MAT) choi1 = kraus2choi(matpow(Y_MAT, 0.5)) wbounds = dm.watrous_bounds(choi0 - choi1) assert wbounds[0] / 2 <= np.sqrt(2) or np.isclose( wbounds[0] / 2, np.sqrt(2), rtol=1e-2) assert wbounds[1] / 2 >= np.sqrt(2) or np.isclose( wbounds[0] / 2, np.sqrt(2), rtol=1e-2)
def getInitialConditionResponseMarkovParameters(A, C, number_steps): markov_parameters = [C(0)] for i in range(1, number_steps - 1): markov_parameters.append(np.matmul(C(0), matpow(A(0), i))) return markov_parameters
def getMarkovParameters(A, B, C, D, number_steps): markov_parameters = [D(0)] for i in range(number_steps - 1): markov_parameters.append( np.matmul(C(0), np.matmul(matpow(A(0), i), B(0)))) return markov_parameters
def test_diamond_norm_distance(): if int(os.getenv('SKIP_SCS', 0)) == 1: return pytest.skip('Having issues with SCS, skipping for now') # Test cases borrowed from qutip, # https://github.com/qutip/qutip/blob/master/qutip/tests/test_metrics.py # which were in turn generated using QuantumUtils for MATLAB # (https://goo.gl/oWXhO9) by Christopher Granade choi0 = kraus2choi(I_MAT) choi1 = kraus2choi(X_MAT) dnorm = dm.diamond_norm_distance(choi0, choi1) assert np.isclose(2.0, dnorm, rtol=0.01) turns_dnorm = [[1.000000e-03, 3.141591e-03], [3.100000e-03, 9.738899e-03], [1.000000e-02, 3.141463e-02], [3.100000e-02, 9.735089e-02], [1.000000e-01, 3.128689e-01], [3.100000e-01, 9.358596e-01]] for turns, target in turns_dnorm: choi0 = kraus2choi(X_MAT) choi1 = kraus2choi(matpow(X_MAT, 1 + turns)) dnorm = dm.diamond_norm_distance(choi0, choi1) assert np.isclose(target, dnorm, rtol=0.01) hadamard_mixtures = [[1.000000e-03, 2.000000e-03], [3.100000e-03, 6.200000e-03], [1.000000e-02, 2.000000e-02], [3.100000e-02, 6.200000e-02], [1.000000e-01, 2.000000e-01], [3.100000e-01, 6.200000e-01]] for p, target in hadamard_mixtures: chan0 = kraus2superop(I_MAT) * (1 - p) + kraus2superop(H_MAT) * p chan1 = kraus2superop(I_MAT) choi0 = superop2choi(chan0) choi1 = superop2choi(chan1) dnorm = dm.diamond_norm_distance(choi0, choi1) assert np.isclose(dnorm, target, rtol=0.01) choi0 = kraus2choi(I_MAT) choi1 = kraus2choi(matpow(Y_MAT, 0.5)) dnorm = dm.diamond_norm_distance(choi0, choi1) assert np.isclose(dnorm, np.sqrt(2), rtol=0.01)
def __pow__(self, t: float) -> 'Gate': """Return this gate raised to the given power.""" # Note: This operation cannot be performed within the tensorflow or # torch backends in general. Subclasses of Gate may override # for special cases. N = self.qubit_nb matrix = asarray(self.vec.flatten()) matrix = matpow(matrix, t) matrix = np.reshape(matrix, ([2] * (2 * N))) return Gate(matrix, self.qubits)
def __pow__(self, t: float) -> "Gate": """Return this gate raised to the given power.""" matrix = matpow(self.asoperator(), t) return Unitary(matrix, self.qubits)
def test_diamon_norm(): # Test cases borrowed from qutip, # https://github.com/qutip/qutip/blob/master/qutip/tests/test_metrics.py # which were in turn generated using QuantumUtils for MATLAB # (https://goo.gl/oWXhO9) by Christopher Granade _I = np.asarray([[1, 0], [0, 1]]) _X = np.asarray([[0, 1], [1, 0]]) _Y = np.asarray([[0, -1.0j], [1.0j, 0]]) _H = np.asarray([[1, 1], [1, -1]]) / np.sqrt(2) def _gate_to_superop(gate): dim = gate.shape[0] superop = np.outer(gate, gate.conj().T) superop = np.reshape(superop, [dim] * 4) superop = np.transpose(superop, [0, 3, 1, 2]) return superop def _superop_to_choi(superop): dim = superop.shape[0] superop = np.transpose(superop, (0, 2, 1, 3)) choi = np.reshape(superop, [dim**2] * 2) return choi def _gate_to_choi(gate): return _superop_to_choi(_gate_to_superop(gate)) choi0 = _gate_to_choi(_I) choi1 = _gate_to_choi(_X) dnorm = dm.diamond_norm(choi0, choi1) assert np.isclose(2.0, dnorm, rtol=0.01) turns_dnorm = [[1.000000e-03, 3.141591e-03], [3.100000e-03, 9.738899e-03], [1.000000e-02, 3.141463e-02], [3.100000e-02, 9.735089e-02], [1.000000e-01, 3.128689e-01], [3.100000e-01, 9.358596e-01]] for turns, target in turns_dnorm: choi0 = _gate_to_choi(_X) choi1 = _gate_to_choi(matpow(_X, 1 + turns)) dnorm = dm.diamond_norm(choi0, choi1) assert np.isclose(target, dnorm, rtol=0.01) hadamard_mixtures = [[1.000000e-03, 2.000000e-03], [3.100000e-03, 6.200000e-03], [1.000000e-02, 2.000000e-02], [3.100000e-02, 6.200000e-02], [1.000000e-01, 2.000000e-01], [3.100000e-01, 6.200000e-01]] for p, target in hadamard_mixtures: chan0 = _gate_to_superop(_I) * (1 - p) + _gate_to_superop(_H) * p chan1 = _gate_to_superop(_I) choi0 = _superop_to_choi(chan0) choi1 = _superop_to_choi(chan1) dnorm = dm.diamond_norm(choi0, choi1) assert np.isclose(dnorm, target, rtol=0.01) choi0 = _gate_to_choi(_I) choi1 = _gate_to_choi(matpow(_Y, 0.5)) dnorm = dm.diamond_norm(choi0, choi1) assert np.isclose(dnorm, np.sqrt(2), rtol=0.01)
def ERADC(Markov_list, tau, n): ## Sizes alpha = int(np.floor((len(Markov_list) - 1) / (2 * (1 + tau)))) xi = alpha gamma = 1 + 2 * xi * tau if Markov_list[0].shape == (): (m, r) = (1, 1) else: (m, r) = Markov_list[0].shape ## Building Hankel Matrices H = np.zeros([alpha * m, alpha * r, gamma + 1]) for i in range(alpha): for j in range(alpha): for k in range(gamma + 1): H[i * m:(i + 1) * m, j * r:(j + 1) * r, k] = Markov_list[i + j + 1 + k] ## Building Data Correlation Matrices R = np.zeros([alpha * m, alpha * m, gamma + 1]) for i in range(gamma + 1): R[:, :, i] = np.matmul(H[:, :, i], np.transpose(H[:, :, 0])) (c, scc, cc) = LA.svd(R[:, :, 0], full_matrices=True) PlotSingularValues.PlotSingularValues(scc, 'scc', 'r') ## Building Block Correlation Hankel Matrices H0 = np.zeros([(xi + 1) * alpha * m, (xi + 1) * alpha * m]) H1 = np.zeros([(xi + 1) * alpha * m, (xi + 1) * alpha * m]) for i in range(xi + 1): for j in range(xi + 1): H0[i * alpha * m:(i + 1) * alpha * m, j * alpha * m:(j + 1) * alpha * m] = R[:, :, (i + j) * tau] H1[i * alpha * m:(i + 1) * alpha * m, j * alpha * m:(j + 1) * alpha * m] = R[:, :, (i + j) * tau + 1] # R0 = R[:, :, 0] # h0 = np.zeros([alpha*m, alpha*r]) # for i in range(alpha): # for j in range(i+1): # h0[i*m:(i+1)*m, j*r:(j+1)*r] = Markov_list[i-j] # T = R0 - np.matmul(h0, np.transpose(h0)) # # (t1, sv, t2) = LA.svd(T, full_matrices=True) # PlotSingularValues.PlotSingularValues(sv, 'T', 'b') ## SVD H(0) (R, sigma, St) = LA.svd(H0, full_matrices=True) PlotSingularValues.PlotSingularValues(sigma, 'ERA/DC', 'r') Sigma = np.diag(sigma) ## Matrices Rn, Sn, Sigman Rn = R[:, 0:n] Snt = St[0:n, :] Sigman = Sigma[0:n, 0:n] ## Identified matrices A_id = np.matmul( matpow(Sigman, -1 / 2), np.matmul( np.transpose(Rn), np.matmul(H1, np.matmul(np.transpose(Snt), matpow(Sigman, -1 / 2))))) B_temp1 = np.matmul(Rn, matpow(Sigman, 1 / 2)) B_temp2 = B_temp1[0:alpha * m, :] B_temp3 = np.matmul(LA.pinv(B_temp2), H[:, :, 0]) B_id = B_temp3[:, 0:r] C_temp = np.matmul(Rn, matpow(Sigman, 1 / 2)) C_id = C_temp[0:m, :] D_id = Markov_list[0] return (A_id, B_id, C_id, D_id)
def eigenSystemRealizationAlgorithmFromInitialConditionResponse(output_signals, state_dimension, input_dimension): # Number of Signals number_signals = len(output_signals) # Number of steps number_steps = output_signals[0].number_steps # Dimensions output_dimension = output_signals[0].dimension # Building pseudo Markov parameters markov_parameters = [] for i in range(number_steps): Yk = np.zeros([output_dimension, number_signals]) for j in range(number_signals): Yk[:, j] = output_signals[j].data[:, i] markov_parameters.append(Yk) # Sizes p = int(np.floor((len(markov_parameters) - 1) / 2)) #p = 200 if markov_parameters[0].shape == (): (output_dimension, number_signals) = (1, 1) else: (output_dimension, number_signals) = markov_parameters[0].shape # Hankel matrices H(0) and H(1) H0 = np.zeros([p * output_dimension, p * number_signals]) H1 = np.zeros([p * output_dimension, p * number_signals]) for i in range(p): for j in range(p): H0[i * output_dimension:(i + 1) * output_dimension, j * number_signals:(j + 1) * number_signals] = markov_parameters[i + j] H1[i * output_dimension:(i + 1) * output_dimension, j * number_signals:(j + 1) * number_signals] = markov_parameters[i + j + 1] # SVD H(0) (R, sigma, St) = LA.svd(H0, full_matrices=True) Sigma = np.diag(sigma) # Matrices Rn, Sn, Sigman Rn = R[:, 0:state_dimension] Snt = St[0:state_dimension, :] Sigman = Sigma[0:state_dimension, 0:state_dimension] # Identified matrices A_id = np.matmul(matpow(Sigman, -1 / 2), np.matmul(np.transpose(Rn), np.matmul(H1, np.matmul(np.transpose(Snt), matpow(Sigman, -1 / 2))))) B_temp = np.matmul(matpow(Sigman, 1 / 2), Snt) x0 = B_temp[:, 0:number_signals] C_temp = np.matmul(Rn, matpow(Sigman, 1 / 2)) C_id = C_temp[0:output_dimension, :] def A(tk): return A_id def B(tk): return np.zeros([state_dimension, input_dimension]) def C(tk): return C_id def D(tk): return(np.zeros([output_dimension, input_dimension])) return A, B, C, D, x0, H0, H1, R, Sigma, St, Rn, Sigman, Snt