Merge remote-tracking branch 'IBMQuantum/Dev' into Dev

This commit is contained in:
Jay M. Gambetta 2017-05-16 00:32:26 -04:00
commit 9664b47f56
3 changed files with 37 additions and 45 deletions

View File

@ -11,7 +11,7 @@ import numpy as np
def destroy(dim):
"""Annihilation operator.
dim integer dimension (for qubits dim = 2**n where n is number of qubits)
dim = integer dimension (for qubits dim = 2**n where n is number of qubits)
returns a complex numpy array
"""
a = np.zeros((dim, dim), dtype=complex)
@ -23,9 +23,9 @@ def destroy(dim):
def operator_qi(gate, qubit, number_of_qubits):
"""Apply the single qubit gate.
"""Apply the single-qubit gate.
gate is the single qubit gate
gate is the single-qubit gate
qubit is the qubit to apply it on counts from 0 and order
is q_{n-1} ... otimes q_1 otimes q_0
number_of_qubits is the number of qubits in the system

View File

@ -10,29 +10,29 @@ import numpy as np
class Pauli:
"""A simple class representing Pauli Operators
The Form is P = (-i)^dot(v,w) Z^v X^w
where v element of Z_2^n
where w element of Z_2^n
That is there are 4^n elements (no phases in this group)
"""A simple class representing Pauli Operators.
For example for 1 qubit
P_00 = Z^0 X^0 = I
P_01 = X
P_10 = Z
P_11 = -iZX = (-i) iY = Y
The form is P = (-i)^dot(v,w) Z^v X^w where v and w are elements of Z_2^n.
That is, there are 4^n elements (no phases in this group).
Multiplication is P1*P2 = (-i)^dot(v1+v2,w1+w2) Z^(v1+v2) X^(w1+w2) where sums are mod 2
For example, for 1 qubit
P_00 = Z^0 X^0 = I
P_01 = X
P_10 = Z
P_11 = -iZX = (-i) iY = Y
Multiplication is P1*P2 = (-i)^dot(v1+v2,w1+w2) Z^(v1+v2) X^(w1+w2)
where the sums are taken modulo 2.
"""
def __init__(self, v, w):
""" makes the Pauli class """
"""Make the Pauli class."""
self.v = v
self.w = w
self.numberofqubits = len(v)
def __str__(self):
""" Outputs the pauli as first row v and second row w"""
"""Output the Pauli as first row v and second row w."""
stemp = '\nv = '
for i in self.v:
stemp += str(i) + '\t'
@ -42,18 +42,16 @@ class Pauli:
return stemp + '\n'
def __mul__(self, other):
""" Multiples two Paulis """
"""Multiply two Paulis."""
if self.numberofqubits != other.numberofqubits:
print('Paulis cannot be multipled - different number of qubits')
print('Paulis cannot be multiplied - different number of qubits')
vnew = (self.v + other.v) % 2
wnew = (self.w + other.w) % 2
# print vnew
# print wnew
paulinew = Pauli(vnew, wnew)
return paulinew
def toLabel(self):
""" prints out the labels in X, Y, Z format"""
"""Print out the labels in X, Y, Z format."""
plabel = ''
for jindex in range(self.numberofqubits):
if self.v[jindex] == 0 and self.w[jindex] == 0:
@ -67,7 +65,7 @@ class Pauli:
return plabel
def toQASM(self, qubits):
""" prints out the qasm format for the Pauli"""
"""Print out the qasm format for the Pauli."""
if len(qubits) == self.numberofqubits:
qasmlabel = ''
for jindex in qubits:
@ -83,20 +81,16 @@ class Pauli:
qasmlabel += 'barrier q;\n'
return qasmlabel
else:
print('the qubit vector did match the pauli')
print('the qubit vector matched the Pauli')
return -1
def to_matrix(self):
""" converts pauli to a matrix representation"""
"""Convert Pauli to a matrix representation."""
X = np.array([[0, 1], [1, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)
I = np.array([[1, 0], [0, 1]], dtype=complex)
Xtemp = 1
# print self.numberofqubits
for k in range(self.numberofqubits):
# print k
# print self.v[k]
# print self.w[k]
if self.v[k] == 0:
tempz = I
elif self.v[k] == 1:
@ -111,15 +105,12 @@ class Pauli:
print('the x string is not of the form 0 and 1')
ope = np.dot(tempz, tempx)
Xtemp = np.kron(Xtemp, ope)
# print Xtemp
paulimat = (-1j)**np.dot(self.v, self.w) * Xtemp
# print paulimat
return paulimat
def random_pauli(numberofqubits):
'''This function returns a random Pauli on numberofqubits
'''
"""Return a random Pauli on numberofqubits."""
v = np.array(list(bin(random.getrandbits(numberofqubits))
[2:].zfill(numberofqubits))).astype(np.int)
w = np.array(list(bin(random.getrandbits(numberofqubits))
@ -128,21 +119,22 @@ def random_pauli(numberofqubits):
def InversePauli(other):
'''This function returns the inverse of a pauli. This is honestly a trival function but to make sure that it is consistent with the clifford benchmarking
'''
"""Return the inverse of a Pauli."""
v = other.v
w = other.w
return Pauli(v, w)
def pauli_group(numberofqubits, case=0):
''' Returns the Pauli group -- 4^n elements where the phases have been removed.
case 0 is by ordering by Pauli weights and
case 1 is by ordering by I,X,Y,Z counting last qubit fastest
@param numberofqubits
@param case determines ordering of group elements (0=weight,1=tensor)
"""Return the Pauli group with 4^n elements.
The phases have been removed.
case 0 is ordered by Pauli weights and
case 1 is ordered by I,X,Y,Z counting last qubit fastest.
@param numberofqubits is number of qubits
@param case determines ordering of group elements (0=weight, 1=tensor)
@return list of Pauli objects
'''
"""
if numberofqubits < 5:
tempset = []
if case == 0:
@ -152,13 +144,13 @@ def pauli_group(numberofqubits, case=0):
np.count_nonzero(np.array(x.toLabel(), 'c') == b'I'))
elif case == 1:
# the pauli set is in tensor order II IX IY IZ XI ...
# the Pauli set is in tensor order II IX IY IZ XI ...
for kindex in range(4**numberofqubits):
v = np.zeros(numberofqubits)
w = np.zeros(numberofqubits)
# looping over all the qubits
for jindex in range(numberofqubits):
# making the pauli for each kindex i fill it in from the
# making the Pauli for each kindex i fill it in from the
# end first
element = int((kindex) / (4**(jindex))) % 4
if element == 0:
@ -176,5 +168,5 @@ def pauli_group(numberofqubits, case=0):
tempset.append(Pauli(v, w))
return tempset
else:
print('please set the number of qubits less then 5')
print('please set the number of qubits to less than 5')
return -1

View File

@ -1,7 +1,7 @@
"""
Quantum Optimization tools.
These are simple methods for common tasks in our optimization,
These are simple methods for common tasks in our optimization.
Author: Jay Gambetta
"""
@ -18,7 +18,7 @@ def cost_classical(data, n, alpha, beta):
alpha is a vector with elements q0 -- qn
beta is a matrix of couplings
NOTE THIS SHOULD BE MADE TO WORK WITH UPPER TRIANGLE
NOTE THIS SHOULD BE MADE TO WORK WITH THE UPPER TRIANGLE.
"""
temp = 0
tot = sum(data.values())