[docs] 7defget_unitary_evolver(drift_hamiltonian:ArrayLike, 8control_hamiltonians:ArrayLike, 9sparse:bool=False, 10force_dynamic:bool=False 11)->evolvers.UnitaryEvolver: 12""" 13 Initialises a class to store the diagonalised drift and control 14 Hamiltonians. On initialisation the Hamiltonians are diagonalised and the 15 eigenvectors and values stored. This initial diagonalisation may be slow and 16 takes 17 $O(\\textrm{dim}^3)$ 18 time for a 19 $\\textrm{dim}\\times \\textrm{dim}$ 20 Hamiltonian. However, it allows each step of the Suzuki-Trotter expansion 21 to be implimented in 22 $O(\\textrm{dim}^2)$ 23 time with matrix multiplication and only scalar exponentiation opposed to 24 matrix exponentiation which takes 25 $O(\\textrm{dim}^3)$ 26 time. 27 28 Parameters 29 ---------- 30 drift_hamiltonian : ArrayLike 31 The drift Hamiltonian. Must be a square matrix of dimension ``dim``. 32 control_hamiltonians : ArrayLike 33 The control Hamiltonians. Can either by a 3D array with shape 34 ``(n_ctrl, dim, dim)`` representing a stack of control Hamiltonians 35 indexed by the first axis. Alternatively a 3D array with shape 36 ``(n_ctrl * dim, dim)`` can be passed with the control Hamiltonians 37 being concatenated along the first axis. 38 sparse : bool, optional 39 Whether to use sparse matrices for the evolution. The default is False. 40 force_dynamic : bool, optional 41 Whether to force the use of dynamically sized matrices for the 42 evolution. The default is False. 43 44 Returns 45 ------- 46 evolvers.UnitaryEvolver 47 An instance of a child class of 48 :class:`evolvers.UnitaryEvolver <py_ste.evolvers.UnitaryEvolver>`. 49 If ``sparse == False`` then the returned instance will be a child class 50 of 51 :class:`evolvers.DenseUnitaryEvolver <py_ste.evolvers.DenseUnitaryEvolver>` 52 else 53 :class:`evolvers.SparseUnitaryEvolver <py_ste.evolvers.SparseUnitaryEvolver>` 54 is returned. Both 55 :class:`evolvers.DenseUnitaryEvolver <py_ste.evolvers.DenseUnitaryEvolver>` 56 and 57 :class:`evolvers.SparseUnitaryEvolver <py_ste.evolvers.SparseUnitaryEvolver>` 58 are dynamic evolvers: evolvers for which the number of control 59 Hamiltonians and the vector space dimension are determined at runtime 60 based on the shapes of ``drift_hamiltonian`` and ``control_hamiltonians``. If possible 61 ``get_unitary_evolver()`` will return an instance of 62 :class:`evolvers.DenseUnitaryEvolver_nctrl_dim <py_ste.evolvers.DenseUnitaryEvolver_nctrl_dim>` 63 or 64 :class:`evolvers.SparseUnitaryEvolver_nctrl_dim <py_ste.evolvers.SparseUnitaryEvolver_nctrl_dim>`, 65 where ``nctrl`` and ``dim`` are substituted for their corresponding 66 values. 67 These are fixed evolvers where the number of controls (``nctrl``) and 68 the vector space dimension (``dim``) are know at the C++ compile time 69 allowing for more efficient C++ methods to be compiled. 70 71 Note 72 ---- 73 An instance of 74 :class:`evolvers.UnitaryEvolver <py_ste.evolvers.UnitaryEvolver>` 75 itself will never be returned. 76 :class:`evolvers.UnitaryEvolver <py_ste.evolvers.UnitaryEvolver>` 77 is simply a base class for all evolvers allowing for checks such as:: 78 79 isinstance(evolver, evolvers.UnitaryEvolver) 80 81 Raises 82 ------ 83 ValueError 84 ``drift_hamiltonian`` must be 2D. 85 ValueError 86 ``drift_hamiltonian`` must be square. 87 ValueError 88 The control Hamiltonians (``control_hamiltonians``) must have the same number of columns as 89 ``drift_hamiltonian``. 90 ValueError 91 ``control_hamiltonians`` must be 2D or 3D. 92 ValueError 93 Each control Hamiltonian in ``control_hamiltonians`` must have the same dimension as ``drift_hamiltonian``. 94 """ 95drift_hamiltonian=np.array(drift_hamiltonian,dtype=np.complex128) 96control_hamiltonians=np.array(control_hamiltonians,dtype=np.complex128) 97 98ifdrift_hamiltonian.ndim!=2: 99raiseValueError("``drift_hamiltonian`` must be 2D.")100101dim:int=drift_hamiltonian.shape[0]102ifdrift_hamiltonian.shape[1]!=dim:103raiseValueError("``drift_hamiltonian`` must be square.")104105ifcontrol_hamiltonians.ndim==3:106control_hamiltonians=control_hamiltonians.reshape((-1,dim))107elifcontrol_hamiltonians.ndim==2:108ifcontrol_hamiltonians.shape[1]!=dim:109raiseValueError("The control Hamiltonians (``control_hamiltonians``) must have the same number of columns as ``drift_hamiltonian``.")110elifcontrol_hamiltonians.size==0:111control_hamiltonians=np.zeros((0,dim),dtype=np.complex128)112else:113raiseValueError("``control_hamiltonians`` must be 2D or 3D.")114115ifcontrol_hamiltonians.shape[0]%dim!=0:116raiseValueError("Each control Hamiltonian in control_hamiltonians must have the same dimension as ``drift_hamiltonian``.")117118n_ctrl:int=control_hamiltonians.shape[0]//dim119name:str=("Sparse"ifsparseelse"Dense")+"UnitaryEvolver"120ifforce_dynamic:121Evolver=getattr(evolvers,name)122else:123try:124Evolver=getattr(evolvers,name+f"_{n_ctrl}_{dim}")125exceptAttributeError:126try:127Evolver=getattr(evolvers,name+f"_Dynamic_{dim}")128exceptAttributeError:129try:130Evolver=getattr(evolvers,name+f"_{n_ctrl}_Dynamic")131exceptAttributeError:132Evolver=getattr(evolvers,name)133returnEvolver(drift_hamiltonian,control_hamiltonians)