def from_dict(dict): return FinishedExperiment( backend_name=dict.get('backend_name', ''), backend_version=dict.get('backend_version', None), date=dateutil.parser.parse(dict['date']) if 'date' in dict else None, qobj=Qobj.from_dict(dict.get('qobj', {})), job_id=dict.get('job_id', ''), status=JobStatus[dict['job_status']] if 'job_status' in dict else JobStatus.INITIALIZING, results=[ExperimentResult.from_dict(d) for d in dict.get('results', [])], noise_model=NoiseModel.from_dict(dict['noise_model']) if 'noise_model' in dict and dict['noise_model'] is not None else None, external_id=dict.get('external_id', None), theta=dict.get('theta', np.arange(0, 2*np.pi, 0.1)), # fixing a bug here.... argh! parameters=dict.get('parameters', []) )
def from_data(date=None, qobj=None, backend=None, job_id=None, noise_model=None, external_id=None, theta=None): # type: (str, dict, str, str, dict, str, list) -> FinishedExperiment """ We expect a dict with a qobj, job_id, backend name and optionally a noise model. When we have a Aer backend the simulation is redone to have the results. If the backend is a IBMQ then it is retrieved from the API. Thus it can take some time until this call ends. :param date: a string :param qobj: a dictionary :param job_id: a string :param noise_model: a dictionary :return: the Finished Experiment """ if theta is None: theta = [] if 'ibmq' in backend and job_id is not None: backend_obj = provider().get_backend(backend) # type: IBMQBackend job = backend_obj.retrieve_job(job_id) # type: IBMQJob qobj = job.qobj().to_dict() qobj = Qobj.from_dict(qobj) date = job.creation_date() elif date is not None and qobj is not None and backend is not None: if isinstance(qobj, dict): qobj = Qobj.from_dict(qobj) backend_obj = qiskit.Aer.get_backend(backend) # type: AerBackend job = backend_obj.run(qobj=qobj, noise_model=noise_model) # type: AerJob job_id = job.job_id() else: raise ValueError("Either use a IBMQ backend with a job_id or provide a date, qobj, backend.") if noise_model is not None: noise_model = NoiseModel.from_dict(noise_model) if isinstance(date, str): date = dateutil.parser.parse(date) # type: datetime.datetime external_id = 'job_{}'.format(date.strftime("%Y%m%dT%H%M%SZ")) if external_id is None else external_id running_experiment = RunningExperiment(date=date, qobj=qobj, noise_model=noise_model, job=job, external_id=external_id) while not running_experiment.is_done(): time.sleep(10) LOG.info("Simulation job {} is not done yet.".format(job_id)) fin_ex = FinishedExperiment.from_running_experiment(running_experiment) fin_ex.set_theta(theta) return fin_ex
def test_from_dict(self): noise_ops_1q = [((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1)] noise_ops_2q = [((PauliGate('II'), [0, 1]), 0.9), ((PauliGate('IX'), [0, 1]), 0.045), ((PauliGate('XI'), [0, 1]), 0.045), ((PauliGate('XX'), [0, 1]), 0.01)] noise_model = NoiseModel() with self.assertWarns(DeprecationWarning): noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [0]) noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [1]) noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [0, 1]) noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [1, 0]) deserialized = NoiseModel.from_dict(noise_model.to_dict()) self.assertEqual(noise_model, deserialized)
def approximate_noise_model(model, *, operator_string=None, operator_dict=None, operator_list=None): """Return an approximate noise model. Args: model (NoiseModel): the noise model to be approximated. operator_string (string or None): a name for a premade set of building blocks for the output channel (Default: None). operator_dict (dict or None): a dictionary whose values are the building blocks for the output channel (Default: None). operator_list (dict or None): list of building blocks for the output channel (Default: None). Returns: NoiseModel: the approximate noise model. Raises: NoiseError: if number of qubits is not supported or approximation failsed. Additional Information ---------------------- The operator input precedence is as follows: list < dict < string if a string is given, dict is overwritten; if a dict is given, list is overwritten possible values for string are 'pauli', 'reset', 'clifford' For further information see `NoiseTransformer.named_operators`. """ # We need to iterate over all the errors in the noise model. # No nice interface for this now, easiest way is to mimic as_dict error_list = [] # Add default quantum errors for operation, error in model._default_quantum_errors.items(): error = approximate_quantum_error(error, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) error_dict = error.to_dict() error_dict["operations"] = [operation] error_list.append(error_dict) # Add specific qubit errors for operation, qubit_dict in model._local_quantum_errors.items(): for qubits_str, error in qubit_dict.items(): error = approximate_quantum_error(error, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) error_dict = error.to_dict() error_dict["operations"] = [operation] error_dict["gate_qubits"] = [model._str2qubits(qubits_str)] error_list.append(error_dict) # Add non-local errors for operation, qubit_dict in model._nonlocal_quantum_errors.items(): for qubits_str, noise_dict in qubit_dict.items(): for noise_str, error in noise_dict.items(): error = approximate_quantum_error( error, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) error_dict = error.to_dict() error_dict["operations"] = [operation] error_dict["gate_qubits"] = [model._str2qubits(qubits_str)] error_dict["noise_qubits"] = [model._str2qubits(noise_str)] error_list.append(error_dict) # Add default readout error if model._default_readout_error is not None: error = approximate_quantum_error(model._default_readout_error, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) error_dict = error.to_dict() error_list.append(error_dict) # Add local readout error for qubits_str, error in model._local_readout_errors.items(): error = approximate_quantum_error(error, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) error_dict = error.to_dict() error_dict["gate_qubits"] = [model._str2qubits(qubits_str)] error_list.append(error_dict) approx_noise_model = NoiseModel.from_dict({ "errors": error_list, "x90_gates": model._x90_gates }) # Update basis gates approx_noise_model._basis_gates = model._basis_gates return approx_noise_model
def __init__(self, backend, project=None, no_save=False, quiet=False): """Load a noise model from either a local file or IBMQ""" if not quiet: print("Building circuit with noise from '{}'".format(backend)) # If a file exists called like the backend, then load the model from that. # In this case, we also try to load a coupling map from # a file with .map extension. If it does not exist, no # worries, we just assume it is default (i.e., empty). noise_filename = "{}.noise".format(backend) coupling_map_filename = "{}.map".format(backend) if path.exists(noise_filename): if not quiet: print("Loading noise model from {}".format(noise_filename)) with open(noise_filename, "rb") as infile: self.noise_model = NoiseModel.from_dict(pickle.load(infile)) self.coupling_map = None if path.exists(coupling_map_filename): if not quiet: print("Loading coupling map from {}".format( coupling_map_filename)) with open(coupling_map_filename, "r") as coupling_infile: self.coupling_map = CouplingMap( literal_eval(coupling_infile.read())) # Otherwise, load the noise model from IBMQ (requires token) # account properties to be stored in default location # and save the noise model for future use, unless the no_save flag is set else: # Build noise model from backend properties provider = IBMQ.load_account() if project is None: backend = provider.get_backend(backend) else: # load a specific project (hub, group, project) = splitProjectInfo(project) if not quiet: print( f"IBMQ backend (hub: {hub}, group: {group}, project: {project})" ) provider_project = IBMQ.get_provider(hub=hub, group=group, project=project) backend = provider_project.get_backend(backend) self.noise_model = NoiseModel.from_backend(backend) # Get coupling map from backend self.coupling_map = backend.configuration().coupling_map # Save the model and coupling map (if not default) to file if not no_save: if not quiet: print("Saving to {} the noise model for future use".format( noise_filename)) with open(noise_filename, "wb") as outfile: pickle.dump(self.noise_model.to_dict(), outfile) if self.coupling_map is not None: if not quiet: print("Saving to {} the coupling map for future use". format(coupling_map_filename)) with open(coupling_map_filename, "w") as coupling_outfile: coupling_outfile.write(str(self.coupling_map))
clicking = False color = (255,255,255) # User prompts allowing for n number of slices and n number of shots num_slice = int(input("How many quantum slices do you want? Type 0 for standard game, and >1 for quantum game. : ")) num_shots = int(input("How many shots do you want to simulate on slice collision? Must be >0 : ")) # Filepath to IBM font font_path = "IBMPlexMono-Medium.ttf" # Generate an Aer noise model for device f = open('noise_file.txt', 'r') noise_dict_file = json.loads(f.read()) # Feature of Aer to export/import noise models from dictionaries noise_model = NoiseModel.from_dict(noise_dict_file) basis_gates = noise_model.basis_gates # Generate a quantum circuit q = QuantumRegister(2) c = ClassicalRegister(2) qc = QuantumCircuit(q, c) qc.h(q[0]) qc.cx(q[0], q[1]) qc.measure(q, c) # Allows for the game to reset after win or loss. def restart(): global monster, boatx, boaty, clicking
b = np.zeros((2**n_sys_qubit, )) b[0] = 1.0 load_architecture = True # True: load architure locally # False: need to save an IBM account beforehand # instances of RACBEM be = BlockEncoding(n_be_qubit, n_sys_qubit) qsp = QSPCircuit(n_sig_qubit, n_be_qubit, n_sys_qubit) # retrieve backends and architectures backend = GetBackend() if load_architecture: if os.path.exists(backend_name + '_backend_config.pkl'): noise_backend = pickle.load( open(backend_name + '_backend_config.pkl', 'rb')) noise_model = NoiseModel.from_dict(noise_backend['noise_dict']) coupling_map = noise_backend['coupling_map'] tot_q_device = noise_backend['tot_q_device'] print("load architecture locally at: %s_backend_config.pkl\n" % (backend_name)) else: raise Exception( "no locally saved architecture: %s_backend_config.pkl" % (backend_name), load_architecture) else: noise_backend = GetBackend(backend_name=backend_name) coupling_map = noise_backend.configuration().coupling_map noise_model = NoiseModel.from_backend(noise_backend) tot_q_device = noise_backend.configuration().n_qubits pickle.dump( {
# copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. import scipy from qiskit import * from qiskit.quantum_info import * from qiskit.providers.aer.noise import NoiseModel from qiskit.providers.aer.utils import insert_noise sys.path.append("..") from json_tools import * from basis_ops import * from decomposition import * from diamond_norm import * noise_model = NoiseModel.from_dict(json_from_file("2020_04_08.json")) noise_model.add_quantum_error(noise_model._local_quantum_errors['cx']['2,3'], 'cx', [0,2]) noise_model.add_quantum_error(noise_model._local_quantum_errors['cx']['3,2'], 'cx', [2,0]) # target ops qc = QuantumCircuit(1) qc.ry(2.*np.arccos(np.sqrt(0.56789)), 0) qc_noisy = insert_noise(qc, noise_model, transpile=True) ry_unitary = Operator(qc).data ry_choi = Choi(qc).data ry_noisy = Choi(qc_noisy).data qc = QuantumCircuit(2) qc.cx(0,1)
def scale_noise_model(noise_model, sigma): """Retrieve the noise model from qiskit backend and scale it. After retrieving the noise model from a backend, create a new noise model by scaling the probability. We assume that there are only two types of noises: 'roerror': readout error. probabilities is of type np.array(np.array()). Each inner array is a discrete probability distribution. We assume the one closest to 1.0 to be the 'correct' option. Example of scaling of the noise: prob = [0.90, 0.06, 0.04] then prob[0] is identified to be the correct one. then after scaling prob = [1-(1-0.90)*sigma, 0.06*sigma, 0.04*sigma] 'qerror': standard quantum error. There are two possibilities: 'kraus': a Kraus operator. It is already a quantum channel, and therefore 'probabilities' is always [1.0]. This type of error mode is discarded at the moment. not 'kraus': scale it the same way as the 'roerror'. Args: noise_model: noise_model obtained from a quantum backend, or a custom noise_model sigma : scaling factor for the noise. 0 <= sigma <= 1 When sigma = 1.0, the result should be the same as the noise model retrieved from the backend without 'kraus'. When sigma = 0.0, the result should be noiseless Returns: noise_model_scaled: scaled noise model. """ # dump out the noise model noise_dict = noise_model.to_dict() new_noise_dict = { 'errors': [], 'x90_gates': [], } for ierr in range(0, len(noise_dict['errors'])): err = noise_dict['errors'][ierr] if err['type'] == 'roerror': assert err['operations'] == ['measure'] probs = err['probabilities'] for iprob in range(0, len(probs)): # Note that this directly modifies the value of probs prob = probs[iprob] imax = np.argmax(prob) for idx in range(0, len(prob)): if idx != imax: prob[idx] *= sigma prob[imax] = 1.0 - (1.0 - prob[imax]) * sigma new_noise_dict['errors'].append(err) elif err['type'] == 'qerror': prob = err['probabilities'] if prob == [1.0]: # This is a Kraus opeartor. # https://qiskit.org/documentation/stubs/qiskit.quantum_info.Kraus.html assert True else: # other errors, the same treatment as roerror assert len(prob) > 1 imax = np.argmax(prob) for idx in range(0, len(prob)): if idx != imax: prob[idx] *= sigma prob[imax] = 1.0 - (1.0 - prob[imax]) * sigma new_noise_dict['errors'].append(err) new_noise_model = NoiseModel.from_dict(new_noise_dict) return new_noise_model