
    z	ij                    *   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
rSSKJr  SSKJr  SSKJrJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJrJ r J!r!J"r"  SSKJ#r#  SSK$J%r%  \RL                  " \'5      r( " S S\5      r)g)a  Contains a (slow) Python simulator.

It simulates a quantum circuit (an experiment) that has been compiled
to run on the simulator. It is exponential in the number of qubits.

The simulator is run using

.. plot::
   :include-source:
   :nofigs:

   BasicSimulator().run(run_input)

Where the input is a :class:`.QuantumCircuit` object and the output is a
:class:`.BasicProviderJob` object,
which can later be queried for the Result object. The result will contain a 'memory' data
field, which is a result of measurements for each shot.
    )annotationsN)Counter)QuantumCircuit)UnitaryGate)get_standard_gate_name_mappingGlobalPhaseGate)	BackendV2Options)Result)Target   )BasicProviderJob)single_gate_matrix)SINGLE_QUBIT_GATESTWO_QUBIT_GATESTWO_QUBIT_GATES_WITH_PARAMETERSTHREE_QUBIT_GATES)einsum_vecmul_index)BasicProviderErrorc                  "  ^  \ rS rSrSrSr  S   SU 4S jjjr\SS j5       r\SS j5       r	SS jr
\SS j5       rSS	 jrSS
 jr      SS jrSS jrS S jrSS jrS!S"S jjrSS jrS#S jr    S$S jrS%S jrS&S jrS'S jrSrU =r$ )(BasicSimulatorA   zCPython implementation of a basic (non-efficient) quantum simulator.   c                  > [         TU ]  " SUSSSS.UD6  X l        SU l        SU l        SU l        SU l        SU l        SU l        U R                  R                  S5      U l        U R                  R                  S	5      U l        U R                  R                  S
5      U l        U R                  R                  S5      U l        g)a^  
Args:
    provider: An optional backwards reference to the provider object that the backend
        is from.
    target: An optional target to configure the simulator.
    fields: kwargs for the values to use to override the default
        options.

Raises:
    AttributeError: If a field is specified that's outside the backend's
        options.
basic_simulatorz0A Python simulator for basic quantum experimentsz0.1)providernamedescriptionbackend_versionr   NFshotsmemoryinitial_statevectorseed_simulator )super__init___target_classical_memory_statevector_number_of_cmembits_number_of_qubits
_local_rng_sample_measureoptionsget_shots_memory_initial_statevector_seed_simulator)selfr   targetfields	__class__s       i/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/providers/basic_provider/basic_simulator.pyr'   BasicSimulator.__init__I   s    & 	 	
"J!		

 	
  "##$ !"$ll&&w/||''1$(LL$4$45J$K!#||//0@A    c                    g Nr%   r5   s    r9   max_circuitsBasicSimulator.max_circuitsr   s    r;   c                f    U R                   (       d  U R                  5       U l         U R                   $ r=   )r(   _build_basic_targetr>   s    r9   r6   BasicSimulator.targetv   s#    ||335DL||r;   c                    [        SSS9n/ SQn[        5       nU HG  nXC;   a  X4   nUR                  USUS9  M  US:X  a  UR                  [        SS9  M;  [	        SU 35      e   U$ )	zHelper method that returns a minimal target with a basis gate set but
no coupling map or instruction properties.

Returns:
    The configured target.
zBasic TargetN)r   
num_qubits)5ccxcczchcpcrxcrycrzcscsdgcswapcsxcucu1cu3cxcyczdcxdelayecrglobal_phasehidiswapmeasureprrccxresetrxrxxryryyrzrzxrzzssdgswapsxsxdgttdguu1u2u3unitaryxxx_minus_yy
xx_plus_yyyz)
propertiesr   ru   )r   z3Gate is not a valid basis gate for this simulator: )r   r   add_instructionr   r   )r5   r6   basis_gatesinst_mappingr   instructions         r9   rB   "BasicSimulator._build_basic_target|   s     &
6
n 67D#*0&&{t$&O" &&{&C(I$P    r;   c                    [        SSS S S9$ )Ni   T)r!   r"   r#   r$   r
   )clss    r9   _default_optionsBasicSimulator._default_options   s     $	
 	
r;   c                    [        U5      n[        X R                  5      n[        R                  " [        R
                  " U[        S9USS/-  5      n[        R                  " XEU R                  [        SS9U l        g)zApply an N-qubit unitary matrix.

Args:
    gate (matrix_like): an N-qubit unitary matrix
    qubits (list): the list of N-qubits.
dtype   no)r   castingN)	lenr   r,   npreshapearraycomplexeinsumr*   )r5   gatequbitsrE   indexesgate_tensors         r9   _add_unitaryBasicSimulator._add_unitary   sb     [
%f.D.DEjj$g!>
aQRV@STII$"3"37D
r;   c                ^   [        [        U R                  5      5      nUR                  U R                  S-
  U-
  5        [        R
                  " [        R                  " U R                  5      S-  [        U5      S9nU R                  R                  5       nXCS   :  a  SUS   4$ SUS   4$ )zSimulate the outcome of measurement of a qubit.

Args:
    qubit: index indicating the qubit to measure

Return:
    pair (outcome, probability) where outcome is '0' or '1' and
    probability is the probability of the returned outcome.
r   r   axisr   01)listranger,   remover   sumabsr*   tupler-   random)r5   qubitr   probabilitiesrandom_numbers        r9   _get_measure_outcome#BasicSimulator._get_measure_outcome   s     E$0012D**Q.67rvvd&7&78A=E$KP..0++a(((M!$$$r;   c           	        [        U VVs1 s H  u  p4UiM	     snn5      n[        U5      n[        [        U R                  5      5      n[        U5       H$  nUR                  U R                  S-
  U-
  5        M&     [        R                  " [        R                  " [        R                  " U R                  5      S-  [        U5      S9SU-  5      nU R                  R                  [        SU-  5      X(S9n	/ n
U	 H  nU R                  nU H:  u  p=UR!                  U5      n[#        USU-  -  U-	  5      nSU-  nUU) -  X-  -  nM<     [%        U5      SS nU
R'                  [)        [#        US5      5      5        M     U
$ s  snnf )a  Generate memory samples from current statevector.

Args:
    measure_params: List of (qubit, cmembit) values for
                           measure instructions to sample.
    num_samples: The number of memory samples to generate.

Returns:
    A list of memory values in hex format.
r   r   r   )r_   N)sortedr   r   r   r,   reversedr   r   r   r   r   r*   r   r-   choicer)   indexintbinappendhex)r5   measure_paramsnum_samplesr   _measured_qubitsnum_measuredr   r   samplesr"   sampleclassical_memorycmembitposqubit_outcomemembitvalues                     r9   _add_sample_measure"BasicSimulator._add_sample_measure  sr    !!GHE%!GH?+ E$0012o.E KK..2U:; / 

FF266$++,1dDao
 //((q,)?(^F#55"0%++E2 #VqCx%8S$@ Ag$4$@]E]#^ 	 #1
 ()!"-EMM#c%m,-  9 "Hs   F
c                *   U R                  U5      u  p4SU-  nU R                  U) -  [        U5      U-  -  U l        US:X  a   S[        R                  " U5      -  S/SS//nOSS/SS[        R                  " U5      -  //nU R                  Xa/5        g)zApply a measure instruction to a qubit.

Args:
    qubit: index of the qubit measured.
    cmembit: index of the classical memory bit to store outcome in.
r   r   r   N)r   r)   r   mathsqrtr   )r5   r   r   outcomeprobabilityr   update_diags          r9   _add_measureBasicSimulator._add_measure/  s      $88?g"&"8"8VG"DWY`I`!a c>		+ 66:QFCKq6Aq499[+A'A#BCK+w/r;   c                    U R                  U5      u  p#US:X  a2  S[        R                  " U5      -  S/SS//nU R                  XA/5        gSS[        R                  " U5      -  /SS//nU R                  XA/5        g)zApply a reset instruction to a qubit.

Args:
    qubit: the qubit being rest

This is done by doing a simulating a measurement
outcome and projecting onto the outcome state while
renormalizing.
r   r   r   N)r   r   r   r   )r5   r   r   r   updates        r9   
_add_resetBasicSimulator._add_resetD  s      $88?c>499[11151v>Ffg.!dii4451v>Ffg.r;   c                    U R                   c  g[        U R                   5      nSU R                  -  nX:w  a  [        SU SU 35      eg)zValidate an initial statevectorNr   z)initial statevector is incorrect length: z != )r3   r   r,   r   )r5   lengthrequired_dims      r9   _validate_initial_statevector,BasicSimulator._validate_initial_statevectorX  s[     $$,T../$000!$;F84~V  "r;   c                0   U R                   R                  S5      U l        U R                   R                  S5      U l        U R                   R                  S5      U l        U R                   R                  S5      U l        UR                  SS5      b!  [        R                  " US   [        S9U l        U R                  bH  [        R                  R                  U R                  5      n[        US5      S:w  a  [        S	U S
35      eSU;   a
  US   U l        SU;   a  US   U l        O0U R
                  c#  [        R                  R                  SSS9U l        SU;   a
  US   U l        [        R                  R                  U R
                  S9U l        g)z,Set the backend run options for all circuitsr!   r"   r#   r$   Nr      r   z,Initial statevector is not normalized: norm z != 1iint32)seed)r/   r0   r1   r2   r3   r4   r   r   r   linalgnormroundr   r   randintdefault_rngr-   )r5   run_optionsr   s      r9   _set_run_optionsBasicSimulator._set_run_optionse  s_    ll&&w/||''1$(LL$4$45J$K!#||//0@A ??0$7C(*=R1S[b(cD%$$099>>$";";<DT2!#(+WX\W]]b)cddk!%g.DK{*#./?#@D !!) $&99#4#4Zw#4#OD {"&x0DL))//T5I5I/Jr;   c                :   U R                   c;  [        R                  " SU R                  -  [        S9U l        SU R
                  S'   OU R                   R                  5       U l        [        R                  " U R
                  U R                  S/-  5      U l        g)z*Set the initial statevector for simulationNr   r   r   r   )r3   r   zerosr,   r   r*   copyr   r>   s    r9   _initialize_statevector&BasicSimulator._initialize_statevector  s{    $$, "D,B,B)B' RD#$Da  $ 9 9 > > @DJJt'8'8$:P:PTUSV:VWr;   c                    SnU R                   S:  ab  UR                   HR  nUR                  S:X  a	  SU l          gU(       a  UR                  S;  a	  SU l          gM>  UR                  S:X  d  MP  SnMT     X l        g)z:Determine if measure sampling is allowed for an experimentFr   rb   N)r^   barrierr\   u0r^   T)r1   datar   r.   )r5   circuitmeasure_flagr   s       r9   _validate_measure_sampling)BasicSimulator._validate_measure_sampling  s     ;;?&||##w.+0D(   #''/QQ/4, R !%%2#'L  ,  ,r;   c                J   0 nUR                  5        HD  u  pE[        U R                  U5      (       d   [        R                  " SU S3[
        SS9  M@  XSU'   MF     U R                  US9  [        [        R                  " 5       5      n[        XU R                  Xa5      5      nU$ )aq  Run on the backend.

Args:
    run_input (QuantumCircuit or list): the QuantumCircuit (or list
        of QuantumCircuit objects) to run
    run_options (kwargs): additional runtime backend options

Returns:
    BasicProviderJob: derived from BaseJob

Additional Information:
    * kwarg options specified in ``run_options`` will temporarily override
      any set options of the same name for the current run. These may include:

        * "initial_statevector": vector-like. The "initial_statevector"
          option specifies a custom initial statevector to be used instead
          of the all-zero state. The size of this vector must correspond to
          the number of qubits in the ``run_input`` argument.

        * "seed_simulator": int. This is the internal seed for sample
          generation.

        * "shots": int. Number of shots used in the simulation.

        * "memory": bool. If True, the result will contain the results
          of every individual shot simulation.

    Example::

        backend.run(
            circuit_2q,
            initial_statevector = np.array([1, 0, 0, 1j]) / math.sqrt(2)
        )
zOption z is not used by this backendr   )
stacklevel)r   )itemshasattrr/   warningswarnUserWarningr   struuiduuid4r   _run_job)r5   	run_inputr   out_optionskeyr   job_idjobs           r9   runBasicSimulator.run  s    J %++-JC4<<--cU">?YZ $)C  . 	+6TZZ\"tT]]6-MN
r;   c                j   [        U[        5      (       a  U/nU R                  U5        / n[        R                  " 5       nU H#  nUR	                  U R                  U5      5        M%     [        R                  " 5       nU R                  U R                  UUSSXd-
  S.n[        R                  " U5      $ )zRun circuits in run_input.

Args:
    job_id: unique id for the job.
    run_input: circuits to be run.

Returns:
    Result object
	COMPLETEDT)backend_namer    r   resultsstatussuccess
time_taken)

isinstancer   	_validatetimer   _run_circuitr   r    r   	from_dict)r5   r   r   result_liststartr   endresults           r9   r   BasicSimulator._run_job  s     i00"Iy!		 Gt009: !iik II#33"!;
 ''r;   c                l   [         R                   " 5       nUR                  U l        UR                  U l        SU l        SU l        U R                  5         U R                  U5        / nU R                  (       a  Sn/ nOU R                  n[        U5       GH5  nU R                  5         U =R
                  [        R                  " SUR                  -  5      -  sl        SU l        UR                    GHT  nUR"                  S:X  a`  UR$                   Vs/ s H  oR'                  U5      R(                  PM     n	nUR*                  R,                  S   n
U R/                  X5        Mt  UR"                  S;   a  M  UR"                  S:X  a7  [1        USS5      n[3        U6 R5                  5       n
U R/                  U
/ 5        M  UR"                  [6        ;   ap  [1        USS5      nUR$                   Vs/ s H  oR'                  U5      R(                  PM     snS   n[9        UR"                  U5      n
U R/                  X/5        GMQ  UR"                  [:        ;   a  [1        USS5      nUR$                   Vs/ s H  oR'                  U5      R(                  PM     n	nU	S   nU	S   n[:        UR"                     " U6 R5                  5       n
U R/                  XU/5        GM  UR"                  S	;   a  GM  UR"                  [<        ;   ag  UR$                   Vs/ s H  oR'                  U5      R(                  PM     n	nU	S   nU	S   n[<        UR"                     n
U R/                  XU/5        GMx  UR"                  [>        ;   al  UR$                   Vs/ s H  oR'                  U5      R(                  PM     n	nU	S   nU	S   nU	S
   n[>        UR"                     n
U R/                  XX/5        GM  UR"                  S:X  aM  UR$                   Vs/ s H  oR'                  U5      R(                  PM     n	nU	S   nU RA                  U5        GMU  UR"                  S:X  a  GMh  UR"                  S:X  a  UR$                   Vs/ s H  oR'                  U5      R(                  PM     snS   nURB                   Vs/ s H  oR'                  U5      R(                  PM     snS   nU R                  (       a  WRE                  UU45        GM  U RG                  UU5        GM$  U R"                  nSn[I        URK                  UUR"                  5      5      e   U R                  S:  d  GM  U R                  (       a  U RM                  WU R                  5      nGM  [O        U R                  5      S
S nURE                  [Q        [S        US
5      5      5        GM8     S[U        [W        U5      5      0nU RX                  (       a  UUS'   [         R                   " 5       nUR"                  UR                  URZ                   Vs/ s H  nUR"                  UR\                  /PM     snUR^                   Vs/ s H  nUR"                  UR\                  /PM     snURZ                   VVs/ s H.  n[        UR\                  5        H  nUR"                  U/PM     M0     snnUR^                   VVs/ s H.  n[        UR\                  5        H  nUR"                  U/PM     M0     snnUR                  UR                  UR`                  b  UR`                  O0 S.	nUR"                  U Rb                  U R                  USSUUU-
  S.$ s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snf s  snnf s  snnf )a  Simulate a single circuit run.

Args:
    circuit: circuit to be run.

Returns:
     A result dictionary which looks something like::
        {
        "name": name of this experiment
        "seed": random seed used for simulation
        "shots": number of shots used in the simulation
        "header": {
            "name": "circuit-206",
            "n_qubits": 3,
            "qreg_sizes": [['qr', 3]],
            "creg_sizes": [['cr', 3]],
            "qubit_labels": [['qr', 0], ['qr', 1], ['qr', 2]],
            "clbit_labels": [['cr', 0], ['cr', 1], ['cr', 2]],
            "memory_slots": 3,
            "global_phase": 0.0,
            "metadata": {},
            }
        "data":
            {
            "counts": {'0x9: 5, ...},
            "memory": ['0x9', '0xF', '0x1D', ..., '0x9']
            },
        "status": status string for the simulation
        "success": boolean
        "time_taken": simulation time of this single experiment
        }
Raises:
    BasicProviderError: if an error occurred.
r   r   y              ?ru   )r\   r   rX   rZ   paramsN)r\   r   r   rb   r   r^   z,{0} encountered unrecognized operation "{1}"countsr"   )	r   n_qubits
qreg_sizes
creg_sizesqubit_labelsclbit_labelsmemory_slotsrZ   metadataDONET)r   r$   r!   r   r   r  headerr  )2r  rE   r,   
num_clbitsr+   r*   r)   r   r   r.   r1   r   r   r   exprZ   r   r   r   find_bitr   	operationr  r   getattrr   	to_matrixr   r   r   r   r   r   clbitsr   r   r   formatr   r   r   r   dictr   r2   qregssizecregsr  r4   )r5   r   r	  r"   r!   measure_sample_opsr   r  bitr   r   r  r   qubit0qubit1qubit2r   backenderr_msgr   r   r
  qregcregjr  s                             r9   r  BasicSimulator._run_circuit  su   F 		!(!3!3#*#5#5 !" 	**, 	''0  E "$KKEuA((*W-A-A(A!BB%&D"$\\	>>Y.ENEUEUVEUc..s399EUFV$..55a8D%%d3^^'<<^^~5$Y$?F*F3==?D%%dB/^^'99$Y$?FDMDTDTUDTS--c288DTUVWXE-innfED%%dG4^^'FF$Y$?FENEUEUVEUc..s399EUFV#AYF#AYF:9>>JFS]]_D%%dV,<=^^|3^^6ENEUEUVEUc..s399EUFV#AYF#AYF*9>>:D%%dV,<=^^'88ENEUEUVEUc..s399EUFV#AYF#AYF#AYF,Y^^<D%%dV,DE^^w.ENEUEUVEUc..s399EUFV"1IEOOE*^^y0^^y0DMDTDTUDTS--c288DTUVWXEFOFVFVWFVs//4::FVWXYZG++ +115'2BC ))%9"iiGLG,W^^GY^^-TUU{ *@ ''!+''!556H$++VF "$"8"89!"=GMM#c'1o"67] b $wv/0<<#DNiik LL**>EmmLmdDIItyy1mL>EmmLmdDIItyy1mL8?`uUYU^U^O_!dii^O_^`8?`uUYU^U^O_!dii^O_^`#..#00,3,<,<,H((b

 LL"22[[;	
 		
w W V
 W W W W VWD ML``sH   $]8/$]=3$^$^$^	$^9$^1$^5"^ '"^%
5^*!5^0c           
        U R                   nU H  nUR                  U:  a)  [        SUR                   SU SU R                   S35      eUR                  n[	        UR
                  5      S:X  a  [        R                  SU5        My  SUR                   Vs/ s H  oUR                  PM     sn;  d  M  [        R                  SU5        M     g	s  snf )
z"Semantic validations of the input.zNumber of qubits z is greater than maximum (z) for "z".r   z=No classical registers in circuit "%s", counts will be empty.r^   zJNo measurements in circuit "%s", classical register will remain all zeros.N)	MAX_QUBITS_MEMORYrE   r   r   r   r$  loggerwarningr   )r5   r   
max_qubitsr   r   ops         r9   r  BasicSimulator._validate  s    ++
 G!!J.('(:(:';;UV`Ua b II;b*  <<D7==!Q&SUY W\\"B\r77\"BB` ! #Cs   C)r)   r3   r-   r2   r+   r,   r.   r4   r1   r*   r(   )NN)r6   zTarget | NonereturnNone)r7  r8  )r7  r   )r7  r   )r   z
np.ndarrayr   z	list[int]r7  r8  )r   r   r7  ztuple[str, int])r   zlist[tuple[int, int]]r   r   r7  z	list[hex])r   r   r   r   r7  r8  )r   r   r7  r8  r=   )r   zdict | Noner7  r8  )r   r   r7  r8  )r   z%QuantumCircuit | list[QuantumCircuit]r7  r   )r   r   r7  r   )r7  r!  )r   zlist[QuantumCircuit]r7  r8  )__name__
__module____qualname____firstlineno____doc__r1  r'   propertyr?   r6   rB   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r  r  __static_attributes____classcell__)r8   s   @r9   r   r   A   s    M
   $'B 'B
 
'B 'BR    
Tl 
 

$%*+3+BE+	+Z0*/(K<	X,00>0	0d(>i
V r;   r   )*r=  
__future__r   r   r   r  loggingr   collectionsr   numpyr   qiskit.circuitr   qiskit.circuit.libraryr   %qiskit.circuit.library.standard_gatesr   r   qiskit.providers.backendr	   qiskit.providers.optionsr   qiskit.resultr   qiskit.transpilerr   basic_provider_jobr   basic_provider_toolsr   r   r   r   r   r   
exceptionsr   	getLoggerr9  r2  r   r%   r;   r9   <module>rQ     so   & #        ) . a . ,   $ 0 4  6 *			8	$t	Y t	r;   