def main(): """ Hauptprogramm, das die Funktionalitaet der sparse.Sparse-Klasse demonstriert. Input: - Return: - """ # Abfrage der Parameter dis und dim: abbr = 1 while abbr == 1: try: dis = int( input('Geben Sie eine die Feinheit der Diskretisierung ein' + ' (eine natuerliche Zahl)\n')) if dis < 1: print( 'Nicht gueltiger Wert eingegeben. Versuchen Sie erneut.\n') abbr = 1 else: abbr = 0 except ValueError: print('Nicht gueltiger Wert eingegeben. Versuchen Sie erneut.\n') abbr = 1 abbr = 1 while abbr == 1: try: dim = int(input('Geben Sie die Raumdimension ein (1, 2 oder 3)\n')) if dim not in [1, 2, 3]: print( 'Nicht gueltiger Wert eingegeben. Versuchen Sie erneut.\n') abbr = 1 else: abbr = 0 except ValueError: print('Nicht gueltiger Wert eingegeben. Versuchen Sie erneut.\n') abbr = 1 sparse_obj = sparse.Sparse(dim, dis) matrix = sparse_obj.return_mat_d() print('Es wurden die Dimension {} und die Diskretisierung {} gewaehlt.'. format(dim, dis)) # Gebe Matrix aus, falls diese nicht groesser als 20x20 ist: if matrix.get_shape()[0] <= 20: print('Die Koeffizientenmatrix ist:\n', matrix.todense()) print( 'Die Anzahl der nicht-Null-Eintraege in der Koeffizientenmatrix ist ' + '{}'.format(sparse_obj.anz_nn_abs())) print('Die Anzahl der Null-Eintraege in der Koeffizientenmatrix ist ' + '{}.'.format(sparse_obj.anz_n_abs())) print( 'Die relative Anzahl der nicht-Null-Eintraege in der Koeffizientenmatrix ist ' '{}.'.format(sparse_obj.anz_nn_rel())) print( 'Die relative Anzahl der Null-Eintraege in der Koeffizientenmatrix ist ' '{}.'.format(sparse_obj.anz_n_rel()))
def main(): """ Hauptprogramm, das die in __dok__ ausgefuehrte Funktionalitaet besitzt. """ plotb = plt.subplots(1, 1, figsize=(20, 10))[1] colors = ["r", "g", "b"] for dim in [1, 2, 3]: # Aus Laufzeit-Gruenden werden fuer jedes dim andere n-Werte untersucht: if dim == 1: n_arr = np.unique(np.logspace(np.log10(3), 4, 50, dtype=int)) if dim == 2: n_arr = np.unique(np.logspace(np.log10(3), 2, 50, dtype=int)) if dim == 3: n_arr = np.unique(np.logspace(np.log10(3), 1.3, 20, dtype=int)) # Ermitteln der Nicht-Null-Eintraege fuer jedes gewuenschte n: k = 0 anz_nn = np.zeros(len(n_arr), dtype=float) for dis in n_arr: sparse_obj_dis = sparse.Sparse(dim, dis) anz_nn[k] = sparse_obj_dis.anz_nn_rel() k += 1 # Plotbefehle: plotb.loglog(n_arr, anz_nn, label=r"Nicht-Null-Eintraege von " + r"$A^{{({})}}$ (rel. Anzahl)".format(dim), color=colors[dim - 1]) plotb.plot(n_arr, (n_arr - 1)**(2 * dim), label=r"vollbesetzte Matrix der Groesse " + r"$(n-1)^{}$".format(dim), ls="--", color=colors[dim - 1]) plotb.axhline(1, ls=":", color="k", alpha=0.6) plotb.set_xlabel(r"$n$") plotb.set_ylabel(r"Eintraege") plotb.legend(loc="best", framealpha=1) plt.show()
def matrixProduct(matA, matB): """Two matrix multiplication function. Parameters ---------- matA : numpy array or sp.Sparse Leftmost matrix in product. matB : numpy array or sp.Sparse Rightmost matrix in product. Returns ------- numpy array or sp.Sparse Matrix being a product of (matA x matB). """ if isinstance(matA, np.ndarray) & isinstance(matB, np.ndarray): if matA.shape[1] != matB.shape[0]: print( f"Non axN Nxb matching matrices : {matA.shape[0]}x{matA.shape[1]} and {matB.shape[0]}x{matB.shape[1]}" ) else: matZ = np.zeros((matA.shape[0], matB.shape[1])) for i in range(matZ.shape[0]): for j in range(matZ.shape[1]): for n in range(matA.shape[1]): matZ[i][j] += matA[i][n] * matB[n][j] return matZ elif isinstance(matA, sp.Sparse) & isinstance(matB, sp.Sparse): matZ = {} for a in matA.matrixDict: for b in matB.matrixDict: if a[0] == b[1]: if (b[0], a[1]) in matZ: matZ[(b[0], a[1])] += matA.matrixDict[a] * matB.matrixDict[b] else: matZ[(b[0], a[1])] = matA.matrixDict[a] * matB.matrixDict[b] return sp.Sparse(matZ, (matA.size[0], matB.size[1])) else: raise TypeError("Incorrect type for one or more matrices in product: \ numpy array or custom sparse matrix please")
def matrixInv(mat): """ Find the matrix inverse for square matrix mat. Parameters ---------- mat : numpy array or sp.Sparse Matrix whose inverse will be found. Returns ------- numpy array or sp.Sparse Inverted matrix whose operation reverses that of mat. """ if isinstance(mat, np.ndarray): return inverter(mat[0]) elif isinstance(mat, sp.Sparse): #cons = np.array([ (-1)**((x+1)//2) for x in range(m.factorial(mat.size))]) return sp.Sparse(inverter(mat.asMatrix)) else: raise TypeError("Incorrect type for matrix to invert: \ numpy array or custom sparse matrix please")
def kroneckerProduct(matA, matB): """Function calculating the kronecker product between two matrices I.e. higher-dimensional tensor product. Parameters ---------- matA : numpy array or sp.Sparse Leftmost matrix in kronecker product. matB : numpy array or sp.Sparse Rightmost array in product. Returns ------- numpy array or sp.Sparse Kronecker product of matA (x) matB. """ if isinstance(matA, np.ndarray) & isinstance(matB, np.ndarray): matZ = np.zeros( (matA.shape[0] * matB.shape[0], matA.shape[1] * matB.shape[1])) for i in range(matZ.shape[0]): for j in range(matZ.shape[1]): matZ[i][j] = matA[i // matB.shape[0]][j // matB.shape[1]] * matB[ i % matB.shape[0]][j % matB.shape[1]] return matZ elif isinstance(matA, sp.Sparse) & isinstance(matB, sp.Sparse): matZ = {} for a in matA.matrixDict: for b in matB.matrixDict: matZ[(b[0] + a[0] * matB.size[0], b[1] + a[1] * matB.size[1])] = matA.matrixDict[a] * matB.matrixDict[b] return sp.Sparse( matZ, (matA.size[0] * matB.size[0], matA.size[1] * matB.size[1])) else: raise TypeError("Incorrect type for matries in kronecker product: \ numpy array or custom sparse matrix please")
def main(): """ Hauptprogramm """ fig, ax = plt.subplots(1, 1, figsize=(20, 10)) ax.tick_params(left=True, right=True, bottom=True, top=True, which='major', length=10) ax.tick_params(right=True, direction='in', which='both') ax.tick_params(left=True, right=True, bottom=True, top=True, which='minor', length=5) #ax_arr = ax_arr.flatten() #print(ax_arr[1]) colors = ["r", "g", "b"] for dim in [1, 2, 3]: if dim == 1: n_arr = np.unique(np.logspace(np.log10(3), 4, 50, dtype=int)) if dim == 2: n_arr = np.unique(np.logspace(np.log10(3), 2, 50, dtype=int)) if dim == 3: n_arr = np.unique(np.logspace(np.log10(3), 1.3, 20, dtype=int)) #print(n_arr) k = 0 anz_nn = np.zeros(len(n_arr), dtype=float) for dis in n_arr: sparse_obj_dis = sparse.Sparse(dim, dis) print(sparse_obj_dis.anz_n_rel()) anz_nn[k] = sparse_obj_dis.anz_nn_rel() k += 1 #print(dim-1) #print(ax) ax.loglog(n_arr, anz_nn, label=r"Nicht-Null-Eintraege von $A^{{({})}}$ (rel. Anzahl)". format(dim), color=colors[dim - 1]) ax.plot( n_arr, (n_arr - 1)**(2 * dim), label=r"vollbesetzte Matrix der Groesse $(n-1)^{}$".format(dim), ls="--", color=colors[dim - 1]) ax.axhline(1, ls=":", color="k", alpha=0.6) #print(anz_n.min()) #print(n_arr) #for j in np.arange(len(n_arr)): # n_arr[j] = float(n_arr[j]) n_arr_fl = n_arr.astype(float) # for i in [2,-2,-3,-4,-5]: # ax.plot(n_arr_fl, n_arr_fl**i, label="{}".format(i)) ax.set_xlabel(r"$n$") ax.set_ylabel(r"Eintraege") ax.legend(loc=(0.5, 0.2), framealpha=1) plt.subplots_adjust(left=0.07, right=0.99, bottom=0.09, top=0.99) plt.savefig("Bericht/Bilder/nn_eintraege.png", dpi=300) plt.show()
def constructGate(code, Sparse=False): """ Function constructing matrix representing gate dynamically Works by parsing a carefully formatted string (code), with characters representing the gate at each qubit and returns the operation as a matrix. First character is the gate to be applied to the most significant qubit, etc. i.e. the code "HHI" represents the operation HxHxI(qubit1xqubit2xqubit3) where x denotes the tensor product Parameters ---------- code : str Sequence/"code" used to generate specific paralel gate. Returns ------- numpy array or sp.Sparse Matrix which when acted on a particular register will have the same effect as applying the theoretical quantum gate. """ matrix = np.array( [[1]] ) # This is starts by making a 1x1 identity matrix so the first kronecker product is the first gate. if Sparse: matrix = sp.Sparse(matrix) # If sparse makes the matrix sparse. TofN = 0 # This is for storing the control number, number of qubits that are connected to the controlled gate eg: CCNot Gate => 3X. for char in code: if char.isdigit(): # Sets the control number. TofN = int(str(TofN) + char) elif TofN != 0: # If a control number was set this creatses the controlled gate matrix if Sparse: # Two methods for sparse or not. gate = sgates[ char] # Gets the sparse gate matrix from dictioanary. l = 2**TofN - gate.size[ 0] # These two lines create and identity sparse matrix but then force it to be 2x2 longer. Tof = sp.Sparse( np.identity(l), (l + gate.size[0], l + gate.size[0]) ) # sp.Sparse takes two parameters; a matrix and a double this being the shape. for pos in gate.matrixDict: # This part adds the sparse gate matrix to the new forced sparse identiy. Tof.matrixDict[((Tof.size[0])-(gate.size[0])+pos[0]%(gate.size[0]) \ , (Tof.size[1])-(gate.size[1])+pos[1]%(gate.size[1]))] \ = gate.matrixDict[(pos[0]%(gate.size[0]),pos[1]%(gate.size[1]))] else: Tof = np.identity( 2**TofN) # For non sparse we start with an identity. gate = gates[char] # Gets gate from dictionary for x in range( len(gates) ): # This adds the 2x2 gate matrix to the end of the identity. for y in range(len(gates)): Tof[len(Tof)-len(gate)+x%len(gate)][len(Tof)-len(gate) \ +y%len(gate)] = gate[x%len(gate)][y%len(gate)] matrix = kroneckerProduct( matrix, Tof ) # Whether sparse or not this does the kronecker product of the existing matrix with the new controlled gate matrix. TofN = 0 else: # This is the main part if there is no control element.. if Sparse: # This changes the gate dictionary depending on whether we are using sparse matrices or not. matrix = kroneckerProduct( matrix, sgates[char] ) # Then whether we are sparse or not it does the kronecker product on the matrix. else: matrix = kroneckerProduct(matrix, gates[char]) return matrix
import math as m from time import time import sparse as sp #Hard-coded basic gates (for 1 qubit) gates = { 'H': 1 / m.sqrt(2) * np.array([[1, 1], [1, -1]]), 'I': np.identity(2), 'X': np.array([[0, 1], [1, 0]]), 'Y': np.array([[0, -1j], [1j, 0]]), 'Z': np.array([[1, 0], [0, -1]]) } #Hard-coded basic gates (for 1 qubit), in sparse form sgates = { 'H': sp.Sparse(gates['H']), 'I': sp.Sparse(gates['I']), 'X': sp.Sparse(gates['X']), 'Y': sp.Sparse(gates['Y']), 'Z': sp.Sparse(gates['Z']) } ### Matrix Addition! ------------------------------------------------------------------------------------------------- def matrixSum(matA, matB): """ Function summing two matrices. Parameters ---------- matA : numpy array or sp.Sparse