§
    º³Ùgy  ã                  ó²   — d Z ddlmZ ddlZddlmZ ddlmZ ddlmZ ddl	Z
ddlmZ dd	lmZmZ ej        rddlZ G d
„ de¦  «        Z G d„ d¦  «        ZdS )z9A generic implementation of Approximate Quantum Compiler.é    )ÚannotationsN)Úpartial)ÚCallable)ÚProtocol)ÚOperatoré   )ÚApproximateCircuitÚApproximatingObjectivec                  ó    — e Zd ZdZ	 	 ddd„ZdS )Ú	MinimizeraŒ  Callable Protocol for minimizer.

    This interface is based on `SciPy's optimize module
    <https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html>`__.

     This protocol defines a callable taking the following parameters:

         fun
             The objective function to minimize.
         x0
             The initial point for the optimization.
         jac
             The gradient of the objective function.
         bounds
             Parameters bounds for the optimization. Note that these might not be supported
             by all optimizers.

     and which returns a SciPy minimization result object.
    NÚfunúCallable[[np.ndarray], float]Úx0ú
np.ndarrayÚjacú)Callable[[np.ndarray], np.ndarray] | NoneÚboundsú list[tuple[float, float]] | NoneÚreturnúscipy.optimize.OptimizeResultc                ó   — dS )aG  Minimize the objective function.

        This interface is based on `SciPy's optimize module <https://docs.scipy.org/doc
        /scipy/reference/generated/scipy.optimize.minimize.html>`__.

        Args:
            fun: The objective function to minimize.
            x0: The initial point for the optimization.
            jac: The gradient of the objective function.
            bounds: Parameters bounds for the optimization. Note that these might not be supported
                by all optimizers.

        Returns:
             The SciPy minimization result object.
        N© )Úselfr   r   r   r   s        úV/granary/edev/quantum/lib/python3.11/site-packages/qiskit/synthesis/unitary/aqc/aqc.pyÚ__call__zMinimizer.__call__4   s	   € ð, 	ˆó    ©NN)
r   r   r   r   r   r   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s?   € € € € € ðð ð0 :>Ø37ðð ð ð ð ð ð r   r   c                  ó6   ‡ — e Zd ZdZ	 	 ddˆ fd„Z	 ddd„Zˆ xZS )ÚAQCa¡  
    A generic implementation of the Approximate Quantum Compiler. This implementation is agnostic of
    the underlying implementation of the approximate circuit, objective, and optimizer. Users may
    pass corresponding implementations of the abstract classes:

    * The *optimizer* is an implementation of the :class:`~.Minimizer` protocol, a callable used to run
      the optimization process. The choice of optimizer may affect overall convergence, required time
      for the optimization process and achieved objective value.

    * The *approximate circuit* represents a template which parameters we want to optimize.  Currently,
      there's only one implementation based on 4-rotations CNOT unit blocks:
      :class:`.CNOTUnitCircuit`. See the paper for more details.

    * The *approximate objective* is tightly coupled with the approximate circuit implementation and
      provides two methods for computing objective function and gradient with respect to approximate
      circuit parameters. This objective is passed to the optimizer. Currently, there are two
      implementations based on 4-rotations CNOT unit blocks: :class:`.DefaultCNOTUnitObjective` and
      its accelerated version :class:`.FastCNOTUnitObjective`. Both implementations share the same
      idea of maximization the Hilbert-Schmidt product between the target matrix and its
      approximation. The former implementation approach should be considered as a baseline one. It
      may suffer from performance issues, and is mostly suitable for a small number of qubits
      (up to 5 or 6), whereas the latter, accelerated one, can be applied to larger problems.

    * One should take into consideration the exponential growth of matrix size with the number of
      qubits because the implementation not only creates a potentially large target matrix, but
      also allocates a number of temporary memory buffers comparable in size to the target matrix.
    NÚ	optimizerúMinimizer | NoneÚseedú
int | Nonec                óª   •— ddl }t          ¦   «                              ¦   «          |pt          |j        j        ddddi¬¦  «        | _        || _        dS )ab  
        Args:
            optimizer: an optimizer to be used in the optimization procedure of the search for
                the best approximate circuit. By default, the scipy minimizer with the
                ``L-BFGS-B`` method is used with max iterations set to 1000.
            seed: a seed value to be used by a random number generator.
        r   Nr   zL-BFGS-BÚmaxiteriè  )ÚargsÚmethodÚoptions)Úscipy.optimizeÚsuperÚ__init__r   ÚoptimizeÚminimizeÚ
_optimizerÚ_seed)r   r$   r&   ÚscipyÚ	__class__s       €r   r/   zAQC.__init__j   se   ø€ ð 	ÐÐÐå‰Œ×ÒÑÔÐØ#ð 
¥wØŒNÔ#¨"°ZÈ)ÐUYÐIZð(
ñ (
ô (
ˆŒð ˆŒ
ˆ
ˆ
r   Útarget_matrixr   Úapproximate_circuitr	   Úapproximating_objectiver
   Úinitial_pointúnp.ndarray | Noner   ÚNonec                óð  — |j         d         }t          j                             |¦  «        }t          j        |d¦  «        s%|t          j        |d|z  t          ¬¦  «        z  }d}n|}d}||_        |€Wt          j         	                    | j
        ¦  «         t          j                             ddt          j        z  |j        ¦  «        }|                      |j        ||j        ¬¦  «        }	|                     |	j        ¦  «         t'          |¦  «        j        }
|rYt          j        t          j        t          j        |
                     ¦   «         j        |¦  «        ¦  «        ¦  «        }||_        dS dS )	aˆ  
        Approximately compiles a circuit represented as a unitary matrix by solving an optimization
        problem defined by ``approximating_objective`` and using ``approximate_circuit`` as a
        template for the approximate circuit.

        Args:
            target_matrix: a unitary matrix to approximate.
            approximate_circuit: a template circuit that will be filled with the parameter values
                obtained in the optimization procedure.
            approximating_objective: a definition of the optimization problem.
            initial_point: initial values of angles/parameters to start optimization from.
        r   r   )ÚdtypeTFNé   )r   r   r   )ÚshapeÚnpÚlinalgÚdetÚiscloseÚpowerÚcomplexr6   Úrandomr&   r3   ÚuniformÚpiÚ
num_thetasr2   Ú	objectiveÚgradientÚbuildÚxr   ÚdataÚangleÚtraceÚdotÚconjÚTÚglobal_phase)r   r6   r7   r8   r9   Ú
matrix_dimÚ
target_detÚ	su_matrixÚglobal_phase_requiredÚ
opt_resultÚapprox_matrixÚalphas               r   Úcompile_unitaryzAQC.compile_unitary   s[  € ð& #Ô(¨Ô+ˆ
å”Y—]’] =Ñ1Ô1ˆ
ÝŒz˜* aÑ(Ô(ð 	*Ø%­¬°¸aÀ*¹nÕU\Ð(]Ñ(]Ô(]Ñ]ˆIØ$(Ð!Ð!à%ˆIØ$)Ð!ð 1:ÐÔ-àÐ ÝŒI�NŠN˜4œ:Ñ&Ô&Ð&ÝœI×-Ò-¨a°µR´U±Ð<SÔ<^Ñ_Ô_ˆMà—_’_Ø'Ô1ØØ'Ô0ð %ñ 
ô 
ˆ
ð 	×!Ò! *¤,Ñ/Ô/Ð/å Ð!4Ñ5Ô5Ô:ˆà ð 	5Ý”H�RœX¥b¤f¨]×-?Ò-?Ñ-AÔ-AÔ-CÀ]Ñ&SÔ&SÑTÔTÑUÔUˆEØ/4ÐÔ,Ð,Ð,ð	5ð 	5r   r   )r$   r%   r&   r'   )N)
r6   r   r7   r	   r8   r
   r9   r:   r   r;   )r   r   r    r!   r/   r\   Ú__classcell__)r5   s   @r   r#   r#   M   sr   ø€ € € € € ðð ð< '+Øðð ð ð ð ð ð ð4 ,0ð05ð 05ð 05ð 05ð 05ð 05ð 05ð 05ð 05r   r#   )r!   Ú
__future__r   ÚtypingÚ	functoolsr   Úcollections.abcr   r   Únumpyr@   Úqiskit.quantum_infor   Úapproximater	   r
   ÚTYPE_CHECKINGr-   r4   r   r#   r   r   r   ú<module>rf      s  ðð @Ð ?Ø "Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ð Ð à $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð à Ð Ð Ð à (Ð (Ð (Ð (Ð (Ð (à CÐ CÐ CÐ CÐ CÐ CÐ CÐ Cà	Ôð ØÐÐÐð+ð +ð +ð +ð +�ñ +ô +ð +ð\b5ð b5ð b5ð b5ð b5ñ b5ô b5ð b5ð b5ð b5r   