from os import linesep as __linesep__
[docs]def registers(c=None,
q=None):
"""Generate a QASM String containing the specified number of classical and quantum registers.
Args:
c(int): The number of Classic registers. (default None)
q(int): The number of Quantum registers, in other words the number of logical Qubits. (default None)
Returns:
str: A string object containing the generated QASM."""
# Check if qregs have been specified.
if q is not None:
# Create qregs string.
qreg_str = f"qreg q[{str(q)}];"
# Check if qregs are set to None.
elif q is None:
# Set qregs string to an empty string.
qreg_str = ''
# Check if cregs have been specified.
if c is not None:
# Create cregs string.
creg_str = f"creg c[{str(c)}];"
# Check if cregs is set to None.
elif c is None:
# Set cregs string to an empty string.
creg_str = ''
# Assemble full string containing classical and quantum registers separated by the OS's line separator.
reg_str = qreg_str + __linesep__ + creg_str + __linesep__
# Return generated QASM registers.
return reg_str
[docs]def gate(self=str('h'),
targetA=None,
targetB=None,
targetC=None,
angle=None,
theta=None,
Utheta=None,
Uphi=None,
Ulambda=None,
custom_name=None,
custom_params=None):
"""Generate a gate from it's name as a string passed to self, and a list of targets passed to targets.
Args:
self(str): The name used to represent the gate in QASM. For example, a Hadamard Gate is 'h'. (default str('h'))
targetA(int): First target qubit. (default None)
targetB(int): Second target qubit. (default None)
targetC(int): Third target qubit. (default None)
angle(float): Angle to specify in Radians for rotation gates like RX, RY, RZ. (default None)
theta(float): Theta value in to specify for rotation gates like RX, RY, RZ. Exactly the same as the angle parameter. (default None)
Utheta(str): Theta value for U-gates. (default None)
Uphi(str): Phi value for U-gates. (default None)
Ulambda(str): Lambda value for U-gates. (default None)
custom_name(str): Name for user-defined opaque gate declarations, unitary gate declarations, and user-defined unitary gates. (default None)
custom_params(str): Parameters for user-defined opaque gate declarations, unitary gate declarations, and user-defined unitary gates. (default None)
Returns:
str: A string object containing the specified gate as QASM."""
angle_gates = ['rx', 'ry', 'rz',
'crx', 'cry', 'crz',
'rxx', 'ryy', 'rzz',
'rzx', 'p']
if angle is None and theta is not None:
angle = theta
# Ensure Integer Variables Have Correct Types
if targetA is not None:
targetA = int(targetA)
if targetB is not None:
targetB = int(targetB)
if targetC is not None:
targetC = int(targetC)
# Check if a U gate was specified.
if self == 'U':
# Compile a U gate.
compiled_gate = f'U({Utheta},{Uphi},{Ulambda}) q[{targetA}];'
# Return compiled U gate.
return compiled_gate
# Create an empty string for variable 'targets'
targets = ''
# Check if targetA is not a default value.
# Generate first target qubit.
targetA_qasm = f'q[{targetA}]'
# Add translated target to 'targets'.
targets = targets + targetA_qasm
# Check if targetB is not a default value.
if targetB is not None and targetB >= 0:
# Generate second target qubit.
targetB_qasm = f', q[{targetB}]'
# Add translated target to 'targets'.
targets = targets + targetB_qasm
# Check if targetC is not a default value.
if targetC is not None and targetC >= 0:
# Generate third target qubit.
targetC_qasm = f', q[{targetC}]'
# Add translated instruction to 'targets'.
targets = targets + targetC_qasm
# Compile gate instruction by combining the gate name with the target specification(s).
compiled_gate = f'{self} ' + f'{targets};'
# Check if specified gate is a unitary gate.
if self == 'unitary':
# Compile unitary gate.
compiled_gate = f'{custom_name}({custom_params}) {targets};'
# Check if gate is declaring a unitary gate.
elif self == 'gate':
# Compile unitary gate declaration.
compiled_gate = f'gate {custom_name}({custom_params}) {targets};'
# Check if gate is declaring an opaque gate.
elif self == 'opaque':
# Compile opaque gate declaration.
compiled_gate = f'opaque {custom_name}({custom_params}) {targets};'
elif self in angle_gates:
compiled_gate = f'{self}({angle}) {targets};'
# Return compiled gate.
return compiled_gate
[docs]def measurement(qreg=int(0),
creg=int(0)):
"""Generate QASM that takes a measurement from a qubit and stores it in a classical register.
Args:
qreg(int): Number of the Qubit to measure. (default 0)
creg(int): Number of the Classical Register to store the measurement to. (default 1)
Returns:
str: Generated QASM containing measurement instruction."""
# Ensure Integer Variables Have Correct Types
if qreg is not None:
qreg = int(qreg)
if creg is not None:
creg = int(creg)
# Generate a measurement argument for QASM 2.0.
meas_str = f'measure q[{str(qreg)}] -> c[{str(creg)}];'
# Return generated measurement argument.
return meas_str
[docs]def if_statement(creg_name=str('c'),
operator=str('=='),
creg_val=int(0),
gate_name=str('x'),
targetA=None,
targetB=None,
targetC=None,
Utheta=None,
Uphi=None,
Ulambda=None,
custom_name=None,
custom_params=None):
"""Generate a gate controlled by a classical if statement as a QASM string from specified parameters.
Args:
creg_name(str): Classical register to run if statement against. (default 'c')
operator(str): Operator to compare values with. (default str('=='))
creg_val(int): Value to compare with creg_name. (default int(0))
gate_name(str): The name used to represent the gate in QASM. For example, a Hadamard Gate is 'h'. (default str('h'))
targetA(int): First target qubit. (default None)
targetB(int): Second target qubit. (default None)
targetC(int): Third target qubit. (default None)
Utheta(float): Theta value for U-gates. (default None)
Uphi(float): Phi value for U-gates. (default None)
Ulambda(float): Lambda value for U-gates. (default None)
custom_name(str): Name for user-defined opaque gate declarations, unitary gate declarations, and user-defined unitary gates. (default None)
custom_params(str): Parameters for user-defined opaque gate declarations, unitary gate declarations, and user-defined unitary gates. (default None)
Returns:
str: A string object containing the specified gate as QASM."""
# Ensure Variables Have Correct Types
if creg_name is not None:
creg_name = str(creg_name)
if operator is not None:
operator = str(operator)
if creg_val is not None:
creg_val = str(int(creg_val))
if gate_name is not None:
gate_name = str(gate_name)
if targetA is not None:
targetA = str(int(targetA))
if targetB is not None:
targetB = str(int(targetB))
if targetC is not None:
targetC = str(int(targetC))
if Utheta is not None:
Utheta = str(float(Utheta))
if Uphi is not None:
Uphi = str(float(Uphi))
if Ulambda is not None:
Ulambda = str(float(Ulambda))
if custom_name is not None:
custom_name = str(custom_name)
if custom_params is not None:
custom_params = str(custom_params)
# Compile gate to apply if statement is fulfilled
compiled_gate = gate(gate_name, targetA, targetB,
targetC, Utheta, Uphi, Ulambda,
custom_name, custom_params)
# Compile if statement
if_str = f'if ({creg_name}{operator}{creg_val}) {compiled_gate}'
# Return compiled if statement
return if_str