NOW I AM DOING THE QISKIT:
the QuantumCircuit construction takes in the number of quantum wires as the input, optionally classical wire can also be put like qc = QuantumCircuit(2,2), this gives us two quantum wires and two clasical wires, another more friendly way is through Quantum registes: useful to treat groups of quantum or classical wires as a unit. like qr = QuantumRegister(number of qubits, ‘names’); the qubits will be names like names0 names1 and so on, also the ClassicalRegisters(nu, ‘names’) the naming convention is same no to send these into the cirucit we could send then in bunch like this QuantumCircuit(qr1,qr2,qr..,cr1,cr2,..) both of these registers have the attribues name and size to them that gives the information
now the quantumcircuit class has some methods to insert circuits into these wires, to do is qc.gatename(the specific wire name or the list of wires to apply the gate for single qubit gates or a quantum register) like qc.h(0) or qc.h([1,2]) ie takes only one arugment while for multi qubit qc.gatename(0,1) for two argumente wala gates like cnot, also to make multiple of thems put them in a list like, yesma first ko le controlled qubi linxa ani second ko le target qubit linxa testai garea list ma haal first list ma controlled qubits, second ma targets ALL EXAMPLES BELOW:
To show the cirucit just made use qc.draw() the non unitaries (also called the barrier oprations) are: qc.reset(bits here) qc.barrier(optionally the list of gates or single gate or no gate) then puts a barrier also that the gates on eitehr sider of the barrier are not candiates for being optimized together as the circuit is coneverted to run on the hardware The methods commonly used to measure quantum circuits are measure() and measure_all(). The former is useful when the quantum circuit contains classical wires on which to receive the result of a measurement. The latter is useful when the quantum circuit doesn’t have any classical wires. qc.measure(the quantum wire, the classical wire) the wires could also be llist is for measurng the bits into designated cbits now qc.measure_all() gives you your own classical wires; it ignores your classical wires and makes its own these were about adding instructions to the ciruit now about getting information of the circuit qc.depth() return the depth (critical path) of a circuit if directives such as barrier were removed so its the horizontal measure of the circuit, qc.width() returns the sum of qubits wires and classical wires; its the vertical measure of the circuit qc.size() no of gates in the ciruict; its the overall measure of the circuit ATTRIBUTES ARE: qc.num_clbits and qc.num_qubits, qc.clbits, qc.qubits obtains list of classical and quantum bits in the order of their regiseter added
the APPEND() method to the qc class takes in an instruciton or gate(is the section of unitary oprations) into the circuit; the instruction class is inside the qiskit.circuit.library so you would do from qiskit.circuit.library import NAME to use append do qc.APPEND(instructions, the list of qubits to use cannot add multiple gates at once) only list is allowed no the indivual qubits, also the list of qubits might be followd by a list of cbits as well for some gats. The instruction class consists of all the things we could add by dotting the qc as BELOW: Something on INSTRUCTION class: the measure, barreir and reset are direct subclasses while gates is anothe subclass that involves the unitay ggates some attributes are inst.definition that returns the definiton in terms of basic gates while for the gate class it will get sexy now gate.control(no of qbits) returns controlled version of the gate gate.to_matrix() returns the matrix of the given gate
qc.copy() to copy the circuit qc.compose(yo cicuit) does return the merged circuit and does not effect the orignal ones the .decompose() returns the decomposed bersion of the ricuit which is just soem random U gates for already atomic gates while for some boxed gates you want to know the insides do the decompose. to_gate(label=‘name’) create the gate unitary if u want geernal (non unitaries) to_instruciton(label=‘name’) with gien number of qubits and cbits
SOMETHING ABOUT SAVING STATES IN AER SIMULATOR:
A REVISION HERE: QuantumCircuit(no of qubits, no of classical bits) QuantumCircuit(series of quantumreg, series of classreg) ATTRIBUTES AND METHODS OF QuantumCircuit: (in the list parameter, we could just send registers) >num_clbits, num_qubits, clbits, qubits >depth(), width(), size() >draw() >NON UNITARY GATES: >barrier(qubits/lists) >measure(qubits/lists,cbits/lists) >measure_all() automatically adds the classical bits for its onw use >reset(qubit/lists) >UNITARY GATES >SINGLE >i(qubit/lists/reg) >x(qubit/lists/reg) >y(qubit/lists/reg) >z(qubit/lists/reg) >h(qubit/lists/reg) >p(angle, qubit/lists/reg) >s(qubit/lists/reg)(sdg) >t(qubit/lists/reg)(tdg) >ry(angle, qubit/lists/reg) >rx(angle, qubit/lists/reg) >rz(angle, qubit/lists/reg) >u(angle, angle, angle) >DOUBLE: >CONTROLLED VERSION (for all except s and t) c()(angle*, controlqubit/lists, targetqubit/lists) >swap(firstqubit/lists, secondqubit/lists) >TRIPE: >ccx(firstq/l, secondq/l, thirdq/l) >cswap(firstq/l, secondq/l, thirdq/l) >MULTIPLE >mcx(lists of control qubits, secondq) >append(instruction(sub)classesobj, list of qubits/qreg, list of cbits/creg (if required)) >Barrier(no of qubits) >Measure() >Reset(no of qubits) >qc.initialize([0 0 0 1], optionally wires or list of wires) does initialize to 11 state and likewise >Gateclass: >IGate(), XGate(), ZGate(), YGate(), HGate() >PhaseGate(angle), SGate() [SdgGate], TGate() [TdgGate] >RYGate(angle), RXGate(angle), RZ(gate) >UGate(angle, agnle, agnle) >Controlled Versions* like before >SwapGate() >CCXGate(), CSwapGate() >ATTRIBUTES AND METHOS: >.definition; gives smipler view >control(no of control qubis) returns not change >to_matrix() returns how will it even cahnge >qc.compose(another qc) returns not change >qc.decompose() returns not change >qc.copy() returns real copy not reference >qc.to_gate(label=‘name’), qc.to_instruction(label=‘name’) >qc.qasm() gives you the qasm code for the circuit >qc = QuantumCircuit.from_qasm_str(the path or code here)
RUNNING THE CIRCUITS IS ALSO NECESSARY LAMO: so there is a qiskit.providers which contain the objects for and simulators, the providers are.basicaer and aer identity the provider → get the reference from the provider → transpile → give (get) the job → manipulate the job from qiskit import BasicAer and if you do BasicAer.backend() to print it gives us list of backends available to use. what we usually use are the qasm_simulator and statevector_simulator to get the refecenr to the backedn we use backend = BasicAer.get_backend(‘simulator name’) Now the IBMQ is actually the factory that gives us the providers, and these providers have acccess to ibm quantum systems for eg the ibm-q is one of the providers full name: ibm-q/open/main (hub, group, project) has access to some basics quantumd evicces of ibm Do this import IMBQ > IMBQ.save_account(‘apikeyfromibmwesite’) > IBMQ.load_account() > provider = IBMQ.get_provider(hub=‘ibm-q’) now this provider is the reference to the actual provider and can be used just like before. IBM gives about 5 qubits for free you should also do transpiling which is to use only gates available on the BasicAer qasm_simulator as folows: tqc = transpile(qc, backend)[another alternative is the execture function use it like job = execute(qc, backend, shot=1212)] returns you the transpiled circuit you need to import transpile to run do this job = backend.run(tqc, shots=21) now the way to manipulate your jobs are: >METHODS: job_id(), status(), result() now the got results have methods of theirs owns like >get_counts() count of meassurment outcomes per basis state from higher to lower qubits, if available >get_statevector() returns the list of complex probabliyt, ifavilb >get_unitary() returns the what
NOW the variations are (as the default shots are 1000 or 1024) >ST: prefers no meausermnet (uselss when measuremesnt), ignores shots get_counts, statevectors >UN: no measurements, ignores shots unitary >QASM: needs measurements in circuis, considers the shots gets_counts
on the other hand we have the aer simualtor can do all the threes at once, which when backend(‘aer_simulator’) derives the possbile results for it to give us statevectors need to mention the point in the circuit itself, by qc.save_statevector, for unitary need to tell by qc.save_unitary(), while for getcounts need to have measurements in the system (else give whatever)
VISUALIZAIONS:
so there is (matplotlib required) from qiskit.visualization import : visualize_transition(qc, trace=True) if contains no barriers (and measures and all) then gives a nice bloch sphere rotaion plot_histogram(takes in the result of getcounts) and plot them in a planar bar graph plot_state_city(takes the density mat or state vetor but displays ina 3d buildings) plot_state_qsphere() takes in statevector or denistymatrixy plot_bloch_multivector(same) [by sendinig the coorindates you can do plot_bloch_vector([x-,y-,z-)] special visual that makes your plot_gate_map(backend, plot_directed=True), needs actual backends tho plot_error_map() is also there just like that
SOMETHING ABOUT QIS PART OF QISKIT: there are two important classes in qiskit.quantum_info: Statevector and DensityMatrix; they are live numpy arrray probably inherited from them Statevector (essentially the hilbert vector of the sate) to create the state vector 1) you send in the circuit like sv = Statevector(qc) another way is to send in the numpy arrays just like that. Now this statevectors could be send to the visualisation gods and others The state vectorclass got .draw(‘latex’, ‘city’, ‘bloch’) to check whether norm is one is_valid()
One another way to do is by sv = Statevector.from_label(‘00’) and then sv.evolve(somecircuit with two wire) This creates a sv with 00 and then evolves (and returns) it with the given circuit another way is also Statevector.from_int(0,dimesnion of hilbertspace)
DensityMatrix Class (the actual densiyt matrix) another is hte desnity matrix that can be derived fromthe same ways like dm = DensityMatrix(qc) and also through numpy array same drawing abilities and isualisatsions to check if valid do is_valid nice (this was not available in numpy) to return a statevector do to_statevector()
Operator Class (the actual unitary matrix) can make them using the circuit or just the mattix method as usual addiitonal way to pass the instruction or gate class to the operation constructor methods like is_unitary() check whether its a unitary or not
Functions from quantum_info purity() return sthe puring of a state (takes in staetvector or DM) entropy() returns von neumann entropy of the sates entanglement_of_formation()SSS returns the entanglement of formation of given state state_fidelity() returns the state fideltiy between two states takes sv or dms process_fidelity() takes in the operator or the instruction class average_gate_fidelity() idk says aerage over all the states, both take one and two parameters
OpenQASM
qasm_str = qc.qasm() gives you the openqasm code for the given circuit lol circ = QuantumCircuit.from_qasm_str(qasm_str) makes the circuit out of given circuit or you can also give the path