Package: quantastica-qps-api
Quantum Programming Studio APIPython wrapper forQuantum Programming StudioHTTP API.Quick start1. Install QPS API package:pipinstallquantastica-qps-api2. Find your QPS API token:Loginto Quantum Programming Studio, go toProfile -> API Accessand copy your API token.3. Configure QPS API package with your API token:fromquantastica.qps_apiimportQPSQPS.save_account("YOUR_API_TOKEN")That will create a local configuration file where your API token will be stored for future use.Now you are ready to use QPS API.Quick start example:find circuit from initial/final vector pairs using Quantum Algorithm Generatorfromquantastica.qps_apiimportQPSvector_pairs=[[[1,0,0,0],[0.5+0j,0.5+0j,0.5+0j,0.5+0j]],[[0,1,0,0],[0.5+0j,0+0.5j,-0.5+0j,0-0.5j]],[[0,0,1,0],[0.5+0j,-0.5+0j,0.5+0j,-0.5+0j]],[[0,0,0,1],[0.5+0j,0-0.5j,-0.5+0j,0+0.5j]]]job_id=QPS.generator.circuit_from_vectors(vector_pairs,settings={"instruction_set":["h","cu1","swap"]})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Account managementQPS.save_account(api_token, api_url=None)Run this onceto setup your QPS REST API account. Method will create configuration file and your api token will be stored there for future use.If needed, you can clear your token by runningQPS.save_account("")(or by deleting a configuration file).Ifapi_urlis not provided thenhttps://quantum-circuit.com/api/will be set as default.QPS.config_path()You can get config file path by runningQPS.config_path().Default configuration file path:On Unix, directory is obtained from environment variable HOME if it is set; otherwise the current user’s home directory is looked up in the password directory through the built-in module pwd.On Windows, USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used.Quantum Algorithm Generator APIQuantum Algorithm Generatoris a tool based on machine learning which reverse engineers quantum circuits from state vectors (wave functions). Additionally, it can be used to find quantum algorithm for boolean function from truth table, to transpile circuits and to decompose unitary matrices.Generator job managementProblem sent to generator is called a "job". Each job has unique ID. As generator is resource intensive tool, it is configured to execute only one job at a time. While generator is solving a job, other jobs are queued. When generator finishes executing a job, it takes the next one from the queue.API provides functions for job manipulation: you can list all jobs (filtered by status), stop running job, cancel queued jobs, stop/cancel all jobs, start previously canceled (draft) job, etc.QPS.generator.list_jobs(status_filter=None)List all jobs, optionally filtered by status.status_filterString, optional. Can be:draft,queued,running,error,done.Example 1- list all (unfiltered) generator jobs:fromquantastica.qps_apiimportQPSjobs=QPS.generator.list_jobs()print(jobs)Example output:{
	"list": [
		{ "_id": "r9LskFoLPQW5w7HTp", "name": "Bell state", "type": "vectors", "status": "done" },
		{ "_id": "R8tJH7XoZ233oTREy", "name": "4Q Gauss", "type": "vectors", "status": "queued" },
		{ "_id": "h7fzYbFz8MJvkNhiX", "name": "Challenge", "type": "unitary", "status": "draft" },
		{ "_id": "PC5PNXiGqhh2HmkX8", "name": "Experiment", "type": "vectors", "status": "error"},
		{ "_id": "SNhiCqSCT2WwRWKCd", "name": "Decompose", "type": "unitary", "status": "running" }
	]
}Example 2- listrunningjobs:fromquantastica.qps_apiimportQPSjobs=QPS.generator.list_jobs(status_filter="running")print(jobs)Example output:{
	"list": [
		{ "_id": "SNhiCqSCT2WwRWKCd", "name": "Decompose", "type": "unitary", "status": "running" }
	]
}QPS.generator.job_status(job_id)Get job status.Example:fromquantastica.qps_apiimportQPSstatus=QPS.generator.job_status("PC5PNXiGqhh2HmkX8")print(status)Example output:{ "_id": "PC5PNXiGqhh2HmkX8", "name": "Experiment", "type": "vectors", "status": "error", "message": "connect ECONNREFUSED" }QPS.generator.get_job(job_id, wait=True)Get generator job referenced by ID. Ifwaitargument isTrue(default), then function will wait for a job to finish (or fail) before returning. IfwaitisFalse, then job will be immediatelly returned even if it is still running (in which case it will not contain a solution).Example:fromquantastica.qps_apiimportQPSjob=QPS.generator.get_job("r9LskFoLPQW5w7HTp")print(job)Example output:{
	"_id": "r9LskFoLPQW5w7HTp",
	"name": "Bell",
	"type": "vectors",
	"source": {
		"vectors": {
			"text1": "[ 1, 0, 0, 0 ]",
			"text2": "[ 1/sqrt(2), 0, 0, 1/sqrt(2) ]",
			"endianness1": "little",
			"endianness2": "little"
		}
	},
	"problem": [
		{
			"input": [ 1, 0, 0, 0 ],
			"output": [ 0.7071067811865475, 0, 0, 0.7071067811865475 ]
		}
	],
	"settings": {
		"max_diff": 0.001,
		"diff_method": "distance",
		"single_solution": False,
		"pre_processing": "",
		"allowed_gates": "u3,cx",
		"coupling_map": [],
		"min_gates": 0,
		"max_gates": 0
	},
	"status": "done",
	"output": {
		"circuits": [
			{
				"qubits": 2,
				"cregs": [],
				"diff": 0,
				"program": [
					{
						"name": "u3",
						"wires": [ 0 ],
						"options": {
							"params": {
								"theta": -1.570796370506287,
								"phi": -3.141592741012573,
								"lambda": -5.327113628387451
							}
						}
					},
					{
						"name": "cx",
						"wires": [ 0, 1 ],
						"options": {}
					}
				],
				"index": 0,
				"qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[0];\ncx q[0], q[1];\n",
				"qasmExt": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[0];\ncx q[0], q[1];\n"
			},
			{
				"qubits": 2,
				"cregs": [],
				"diff": 0,
				"program": [
					{
						"name": "u3",
						"wires": [ 1 ],
						"options": {
							"params": {
								"theta": -1.570796370506287,
								"phi": -3.141592741012573,
								"lambda": -5.327113628387451
							}
						}
					},
					{
						"name": "cx",
						"wires": [ 1, 0 ],
						"options": {}
					}
				],
				"index": 1,
				"qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[1];\ncx q[1], q[0];\n",
				"qasmExt": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[1];\ncx q[1], q[0];\n"				
			}
		],
		"error_code": 0,
		"message": "",
		"time_taken": 0.002,
		"version": "0.1.0"
	},
	"queuedAt": "2021-02-06T23:39:29.676Z",
	"startedAt": "2021-02-06T23:39:29.926Z",
	"finishedAt": "2021-02-06T23:39:30.383Z"
}QPS.generator.stop_job(job_id)Stop running or cancel queued job. Job will be put intodraftstate, and you can start it again later by callingstart_job().Example:fromquantastica.qps_apiimportQPSresponse=QPS.generator.stop_job("SNhiCqSCT2WwRWKCd")print(response)Example output:{ _id: "SNhiCqSCT2WwRWKCd", message: "OK" }QPS.generator.stop_all_jobs(status_filter=None)Stop running job / cancel all queued jobs.status_filter- you can stop only a running job by providingstatus_filter="running"(after this, next job from the queue will be executed). Or, you can cancel all queued jobs by providingstatus_filter="queued"(running job will not be affected - it will continue running).Example 1- stop running job and remove all jobs from queue:fromquantastica.qps_apiimportQPSstopped=QPS.generator.stop_all_jobs()print(stopped)Example output:{
	"stopped": [ 
		{ "_id": "SNhiCqSCT2WwRWKCd", "name": "Decompose", "type": "unitary" },
		{ "_id": "R8tJH7XoZ233oTREy", "name": "4Q Gauss", "type": "vectors" }
	]
}Example 2- stop only a running job. Next job from queue, if any, will start:fromquantastica.qps_apiimportQPSstopped=QPS.generator.stop_all_jobs(status_filter="running")print(stopped)Example output:{
	"stopped": [
		{ "_id": "SNhiCqSCT2WwRWKCd", "name": "Decompose", "type": "unitary" }
	]
}Example 3- cancel all queued jobs. Running job will not be affected:fromquantastica.qps_apiimportQPSstopped=QPS.generator.stop_all_jobs(status_filter="queued")print(stopped)Example output:{
	"stopped": [
		{ "_id": "R8tJH7XoZ233oTREy", "name": "4Q Gauss", "type": "vectors" }
	]
}QPS.generator.start_job(job_id)Start previously stopped/canceled job (can be any job with statusdraft).Example:fromquantastica.qps_apiimportQPSresponse=QPS.generator.start_job("SNhiCqSCT2WwRWKCd")print(response)Example output:{ _id: "SNhiCqSCT2WwRWKCd", message: "OK" }Circuit from vectorsFind quantum circuit from pairs of initial & final state vectors (wave functions).QPS.generator.circuit_from_vectors(vector_pairs, endianness = "little", job_name=None, settings = {}, start_job=True)vector_pairsis list containing vector pairs. Each vector pair is list with 2 elements: initial vector and final vector. All vectors in all pairs must be of same length (same number of qubits).endiannessstring. Orientation of bits in state vector (most significant bit/first qubit or least significant bit/first qubit). Can belittle(like Qiskit) orbig. Default islittle.job_namestring is optional. You can give it a human readable name.settingsobject is optional. Default is:{"allowed_gates":"u3,cx","max_diff":1e-3,"diff_method":"distance","single_solution":True,"pre_processing":""}Note: ifsettingsargument is provided, it will overwrite default values, but only provided keys will be overwritten - not entire default settings object.start_jobif this argument isTrue(default) the job will be immediatelly sent to execution queue. Ifstart_jobisFalsethen it will stay indraftstate and you will be able to start it later by callingstart_job()method.Example:fromquantastica.qps_apiimportQPSvector_pairs=[[[1,0,0,0],[0.5+0j,0.5+0j,0.5+0j,0.5+0j]],[[0,1,0,0],[0.5+0j,0+0.5j,-0.5+0j,0-0.5j]],[[0,0,1,0],[0.5+0j,-0.5+0j,0.5+0j,-0.5+0j]],[[0,0,0,1],[0.5+0j,0-0.5j,-0.5+0j,0+0.5j]]]job_id=QPS.generator.circuit_from_vectors(vector_pairs,settings={"instruction_set":["h","cu1","swap"],"single_solution":False})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
swap q[0], q[1];
cu1 (2.356194496154785) q[0], q[1];
h q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
cu1 (2.356194496154785) q[0], q[1];
h q[0];
swap q[0], q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
cu1 (2.356194496154785) q[0], q[1];
swap q[0], q[1];
h q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
swap q[0], q[1];
h q[0];
cu1 (2.356194496154785) q[0], q[1];
h q[1];State preparationGet circuit which will transform ground state (all qubits reset) to desired final state vector.QPS.generator.state_preparation(final_vector, endianness = "little", job_name=None, settings = {}, start_job=True)final_vectoris target vector.endiannessstring. Orientation of bits in state vector (most significant bit/first qubit or least significant bit/first qubit). Can belittle(like Qiskit) orbig. Default islittle.job_namestring is optional. You can give it a human readable name.settingsobject is optional. Default: seeQPS.generator.circuit_from_vectors().start_jobif this argument isTrue(default) the job will be immediatelly sent to execution queue. Ifstart_jobisFalsethen it will stay indraftstate and you will be able to start it later by callingstart_job()method.Example:fromquantastica.qps_apiimportQPSdesired_state=[0.5,0.5,0.5,0.5]job_id=QPS.generator.state_preparation(desired_state,settings={"instruction_set":["u3","cx"]})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
u3 (1.570796370506287, 0, 1.217840194702148) q[0];
u3 (1.570796370506287, 0, 0.621559917926788) q[1];TranspileTranspile circuit (change instruction set).QPS.generator.transpile(input_qasm, method="replace_blocks", method_options={}, job_name=None, settings = {}, start_job=True)input_qasmis string containing OpenQASM 2.0 code.methodis method name string. Can be one of: "replace_circuit", "replace_blocks", "replace_gates". Default: "replace_blocks".method_optionsdict with following structure:If method isreplace_blocksthen:{ "block_size": 2, "two_pass": False }(maximum block size is 4).For other methods: no options (method_optionsis ignored)job_namestring is optional. You can give it a human readable name.settingsobject is optional. Default is:{"allowed_gates":"u3,cx","max_diff":1e-3,"diff_method":"distance","single_solution":True,"pre_processing":"experimental1"}Defaultdiff_methodisdistance, which means that input and output circuit's global phase will match. That also means longer running time and possibly deeper output circuit (especially with new IBM's instruction setid, x, sx, rz, cx). If you are relaxed about global phase (like Qiskit's transpile method), then provide"diff_method": "ignorephase"insettings.Note: ifsettingsargument is provided, it will overwrite default values, but only provided keys will be overwritten - not entire default settings object.start_jobif this argument isTrue(default) the job will be immediatelly sent to execution queue. Ifstart_jobisFalsethen it will stay indraftstate and you will be able to start it later by callingstart_job()method.Example:fromquantastica.qps_apiimportQPSinput_qasm="""OPENQASM 2.0;include "qelib1.inc";qreg q[2];h q[0];cx q[0], q[1];"""job_id=QPS.generator.transpile(input_qasm,settings={"instruction_set":["id","x","sx","rz","cx"],"diff_method":"ignorephase"})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
sx q[0];
rz (1.570796370506287) q[0];
sx q[0];
cx q[0], q[1];Decompose matrixDecompose unitary matrix (find circuit from matrix).QPS.generator.decompose_unitary(unitary, endianness = "big", job_name=None, settings = {}, start_job=True)unitarymatrix operator.endianness- orientation of the matrix. Can belittleendian (like Qiskit) orbigendian. Default isbig. Note that default endianness of the matrix differs from default endianness of vectors in other methods. That's to be aligned with QPS. In Qiskit, both matrices and vectors arelittleendian. So, if you are solving unitary from Qiskit then provideendianness = "little"argument.job_namestring is optional. You can give it a human readable name.settingsobject is optional. Default is:{"allowed_gates":"u3,cx","max_diff":1e-3,"diff_method":"distance","single_solution":True,"pre_processing":""}Note: ifsettingsargument is provided, it will overwrite default values, but only provided keys will be overwritten - not entire default settings object.start_jobif this argument isTrue(default) the job will be immediatelly sent to execution queue. Ifstart_jobisFalsethen it will stay indraftstate and you will be able to start it later by callingstart_job()method.Example:fromquantastica.qps_apiimportQPSunitary=[[0.5+0.0j,0.5+0.0j,0.5+0.0j,0.5+0.0j],[0.5+0.0j,0.5+0.0j,-0.5+0.0j,-0.5+0.0j],[0.5+0.0j,-0.5+0.0j,0.0+0.5j,0.0-0.5j],[0.5+0.0j,-0.5+0.0j,0.0-0.5j,0.0+0.5j]]job_id=QPS.generator.decompose_unitary(unitary,settings={"instruction_set":["h","cu1","swap"],"single_solution":False})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
swap q[0], q[1];
cu1 (1.570796370506287) q[0], q[1];
h q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
cu1 (1.570796370506287) q[0], q[1];
h q[0];
swap q[0], q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
h q[1];
cu1 (1.570796370506287) q[0], q[1];
swap q[0], q[1];
h q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
swap q[0], q[1];
h q[0];
cu1 (1.570796370506287) q[0], q[1];
h q[1];Create algorithm from truth tableCreate circuit which implements logical expression whose truth table is given.QPS.generator.circuit_from_truth_table(truth_table_csv, column_defs, csv_delimiter=None, additional_qubits=1, job_name=None, settings={}, start_job=True)truth_table_csvis string containing truth table in CSV formatcolumn_defslist of strings describing each column from truth table:"input","output"or"ignore"csv_delimiterCSV column delimiter char:None,","(comma) or"\t"(tab). If delimiter isNone(default) it will be automatically detected.additional_qubitsnumber of qubits to add (to displace input and output qubits).job_namestring is optional. You can give it a human readable name.settingsobject is optional. Default is:{"allowed_gates":"x,cx,ccx,swap","max_diff":1e-3,"diff_method":"distance","single_solution":True,"pre_processing":""}Example:fromquantastica.qps_apiimportQPStruth_table="""A,B,A_NAND_B0,0,10,1,11,0,11,1,0"""job_id=QPS.generator.circuit_from_truth_table(truth_table,["input","input","output"])job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):raiseException(job_output["message"])else:if(len(job_output["circuits"])==0):raiseException("No results.")else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
x q[2];
ccx q[0], q[1], q[2];Run problem fileSolve problem provided in internal format used by generator.QPS.generator.solve(problem, settings = {}, start_job=True)problemobject - generator job exported to json from QPS.settingsargument is optional. If provided, it will overwrite keys inproblem.settings. Note that only provided keys will be overwritten - not entireproblem.settingsobject.start_jobif this argument isTrue(default) the job will be immediatelly sent to execution queue. Ifstart_jobisFalsethen it will stay indraftstate and you will be able to start it later by callingstart_job()method.Example:fromquantastica.qps_apiimportQPSproblem={"name":"Bell","type":"vectors","source":{"vectors":{"text1":"[ 1, 0, 0, 0 ]","text2":"[ 1/sqrt(2), 0, 0, 1/sqrt(2) ]","endianness1":"little","endianness2":"little"}},"problem":[{"input":[1,0,0,0],"output":[0.7071067811865475,0,0,0.7071067811865475]}],"settings":{"allowed_gates":"u3,cx","coupling_map":[],"min_gates":0,"max_gates":0,"max_diff":0.001,"diff_method":"distance","single_solution":False,"pre_processing":""}}job_id=QPS.generator.solve(problem)job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):print(job_output["message"])else:forcircuitinjob_output["circuits"]:print(circuit["qasm"])Example output:OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
u3 (-1.570796370506287, -3.141592741012573, -2.675650835037231) q[0];
cx q[0], q[1];

OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
u3 (-1.570796370506287, -3.141592741012573, -2.675650835037231) q[1];
cx q[1], q[0];Generator output formatGenerator job object has following structure:{"name":String,"type":String,"source":Object,"problem":Array,"settings":Object,"status":String,"output":Object,"queuedAt":String,"startedAt":String,"finishedAt":String}Keys important to user are:nameString: name of the jobstatusString: can bedraft,queued,running,error,done.outputObject with following structure:{"error_code":Integer,"message":String,"time_taken":Float,"version":String,"circuits":ArrayofObject}error_codeInteger: 0 on success, non-zero on errormessageString: error message if error code is non-zerotime_takenFloat: number of secondsversionString: generator versioncircuitsArray: resulting circuits. Each is object with following structure:{"qubits":Integer,"cregs":Array,"program":Array,"diff":Float,"index":Integer,"qasm":String,"qasmExt":String}Keys important to user are:qasmOpenQASM 2.0 source code of the resulting circuit.qasmExtOpenQASM 2.0 with extended instruction set (all gates supported by Quantum Programming Studio).Difference betweenqasmandqasmExt: if circuit contains gate supported by QPS but not directly supported by OpenQASM 2.0 thenqasmwill contain equivalent circuit transpiled to OpenQASM 2.0 instruction set, butqasmExtwill contain gates as is.For example if circuit contains IONQ native gategpi2(2.51678906856393)on first qubit:qasmwill be:OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
u3 (1.5707963267948966, 0.9459927417690333, -0.9459927417690333) q[0];qasmExtwill contain:OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
gpi2 (2.51678906856393) q[0];Example job object with output:{"_id":"r9LskFoLPQW5w7HTp","name":"Bell","type":"vectors","source":{"vectors":{"text1":"[ 1, 0, 0, 0 ]","text2":"[ 1/sqrt(2), 0, 0, 1/sqrt(2) ]","endianness1":"little","endianness2":"little"}},"problem":[{"input":[1,0,0,0],"output":[0.7071067811865475,0,0,0.7071067811865475]}],"settings":{"max_diff":0.001,"diff_method":"distance","single_solution":False,"pre_processing":"","allowed_gates":"u3,cx","coupling_map":[],"min_gates":0,"max_gates":0},"status":"done","output":{"circuits":[{"qubits":2,"cregs":[],"diff":0,"program":[{"name":"u3","wires":[0],"options":{"params":{"theta":-1.570796370506287,"phi":-3.141592741012573,"lambda":-5.327113628387451}}},{"name":"cx","wires":[0,1],"options":{}}],"index":0,"qasm":"OPENQASM 2.0;\ninclude\"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[0];\ncx q[0], q[1];\n","qasmExt":"OPENQASM 2.0;\ninclude\"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[0];\ncx q[0], q[1];\n"},{"qubits":2,"cregs":[],"diff":0,"program":[{"name":"u3","wires":[1],"options":{"params":{"theta":-1.570796370506287,"phi":-3.141592741012573,"lambda":-5.327113628387451}}},{"name":"cx","wires":[1,0],"options":{}}],"index":1,"qasm":"OPENQASM 2.0;\ninclude\"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[1];\ncx q[1], q[0];\n","qasmExt":"OPENQASM 2.0;\ninclude\"qelib1.inc\";\nqreg q[2];\nu3 (-1.570796370506287, -3.141592741012573, -5.327113628387451) q[1];\ncx q[1], q[0];\n"}],"error_code":0,"message":"","time_taken":0.002,"version":"0.1.0"},"createdAt":"2021-02-06T23:39:29.108Z","modifiedAt":"2021-02-06T23:39:30.383Z","queuedAt":"2021-02-06T23:39:29.676Z","startedAt":"2021-02-06T23:39:29.926Z","finishedAt":"2021-02-06T23:39:30.383Z"}Using Generator with QiskitGenerator is using OpenQASM 2.0 format for input and output, so integration with Qiskit (and other frameworks that support QASM) is easy.Exampletranspile Qiskit circuit:fromqiskitimportQuantumCircuitfromqiskit.circuit.randomimportrandom_circuitfromqiskit.quantum_infoimportOperatorfromquantastica.qps_apiimportQPS# Generate random Qiskit circuitqc=random_circuit(5,5,measure=False)# Get QASM codeinput_qasm=qc.qasm()# Transpile with generatorjob_id=QPS.generator.transpile(input_qasm,settings={"instruction_set":["id","u3","cx"],"diff_method":"ignorephase"})job=QPS.generator.get_job(job_id,wait=True)job_status=job["status"]job_output=job["output"]if(job_status=="error"):raiseException(job_output["message"])transpiled_circuit=job_output["circuits"][0]# Get QASM codetranspiled_qasm=transpiled_circuit["qasm"]# Create Qiskit circuittranspiled_qc=QuantumCircuit.from_qasm_str(transpiled_qasm)# Show circuitprint("Depth:",transpiled_qc.depth())print("Ops:",sum(jfori,jintranspiled_qc.count_ops().items()))display(transpiled_qc.draw(output="mpl"))Quantum Language Converter APIQuantum Language Converteris a tool which converts quantum program between different quantum programming languages and frameworks. It is also available as aq-convertcommand line tool and as a web UI athttps://quantum-circuit.com/qconvert.QPS has integrated quantum language converter API which you can access directly from python code:QPS.converter.convert(input, source, dest)Convertsinputquantum program given as string fromsourceformat intodestformat.inputString. Program source codesourceString. Input format:qasmOpenQASM 2.0source codequilQuilsource codeqobjQObjionqIONQ(json)quantum-circuitquantum-circuitobject (json)toasterQubit Toasterobject (json)destString. Output format:qiskitQiskitqasmOpenQASM 2.0qasm-extOpenQASM 2.0 with complete instruction set supported by QPS (and other Quantastica tools)qobjQObjquilQuilpyquilpyQuilbraketBraketcirqCirqtfqTensorFlow QuantumqsharpQSharpquestQuESTjsquantum-circuit(javascript)quantum-circuitquantum-circuit(json)toasterQubit ToastersvgSVG (standalone)svg-inlineSVG (inline)Example 1- convert QASM 2.0 program to QUIL:fromquantastica.qps_apiimportQPSinput_program="""OPENQASM 2.0;include "qelib1.inc";qreg q[2];creg c[2];h q[0];cx q[0], q[1];measure q[0] -> c[0];measure q[1] -> c[1];"""output_program=QPS.converter.convert(input_program,"qasm","quil")print(output_program)Output:DECLARE ro BIT[2]
H 0
CNOT 0 1
MEASURE 0 ro[0]
MEASURE 1 ro[1]Example 2- convert QASM 2.0 program to circuit drawing as vector image:fromquantastica.qps_apiimportQPSinput_program="""OPENQASM 2.0;include "qelib1.inc";qreg q[2];creg c[2];h q[0];cx q[0], q[1];measure q[0] -> c[0];measure q[1] -> c[1];"""output_svg=QPS.converter.convert(input_program,"qasm","svg")open("output.svg","w").write(output_svg)Utils APIQPS.utils.random_circuit(num_qubits=5, output_format="quantum-circuit", options=None)Returns random quantum circuit.num_qubitsInteger. Number of qubits. Default:5.formatString. Output format. The same asQPS.converter.convert()function'sdestargument. Example:"qasm". Default:"quantum-circuit".optionsDict. Optional. Can contain following keys:instruction_setList of gates to use. Example:["u3", "cx"]. Default:[ "u3", "rx", "ry", "rz", "cx", "cz" ].num_gatesInteger. Number of gates in the circuit. Default isnum_qubits * 8.mid_circuit_measurementBool. Default:False.mid_circuit_resetBool. Default:False.classic_controlBool. Default:False.