def magnus_m6(a, dt, time): """ Construct a magnus expasion of `a` of order six. References: [1] https://arxiv.org/abs/1709.06483 Arguments: a :: (time :: float) -> ndarray (a_shape) - the matrix to expand dt :: float - the time step time :: float - the current time Returns: m6 :: ndarray (a_shape) - magnus expansion """ t1 = time + dt * _M6_C1 t2 = time + dt * _M6_C2 t3 = time + dt * _M6_C3 a1 = a(t1) a2 = a(t2) a3 = a(t3) b1 = dt * a2 b2 = _M6_F0 * dt * (a3 - a1) b3 = _M6_F1 * dt * (a3 - 2 * a2 + a1) b1_b2_commutator = commutator(b1, b2) m6 = (b1 + _M6_F2 * b3 + _M6_F3 * commutator(-20 * b1 - b3 + b1_b2_commutator, b2 - _M6_F4 * commutator(b1, 2 * b3 + b1_b2_commutator))) return m6
def get_lindbladian( densities, dissipators=None, hamiltonian=None, operators=None, ): """ Compute the action of the lindblad equation on a single (set of) density matrix (matrices). This implementation uses the definiton: https://en.wikipedia.org/wiki/Lindbladian. Args: densities :: ndarray - the probability density matrices dissipators :: ndarray - the lindblad dissipators hamiltonian :: ndarray operators :: ndarray - the lindblad operators operation_policy :: qoc.OperationPolicy - how computations should be performed, e.g. CPU, GPU, sparse, etc. Returns: lindbladian :: ndarray - the lindbladian operator acting on the densities """ if hamiltonian is not None: lindbladian = -1j * commutator( hamiltonian, densities, ) else: lindbladian = 0 if dissipators is not None and operators is not None: operators_dagger = conjugate_transpose(operators, ) operators_product = matmuls( operators_dagger, operators, ) for i, operator in enumerate(operators): dissipator = dissipators[i] operator_dagger = operators_dagger[i] operator_product = operators_product[i] lindbladian = (lindbladian + (dissipator * (matmuls( operator, densities, operator_dagger, ) - 0.5 * matmuls( operator_product, densities, ) - 0.5 * matmuls( densities, operator_product, )))) #ENDFOR #ENDIF return lindbladian
def magnus_m6(a1, a2, a3, dt, operation_policy=OperationPolicy.CPU): """ a magnus expansion method of order six as seen in https://arxiv.org/abs/1709.06483 Args: a1 :: numpy.ndarray - see paper a2 :: numpy.ndarray - see paper a3 :: numpy.ndarray - see paper dt :: float - see paper Returns: m6 :: numpy.ndarray - magnus expansion """ b1 = dt * a2 b2 = _M6_C0 * dt * (a3 - a1) b3 = _M6_C1 * dt * (a3 - 2 * a2 + a1) b1_b2_commutator = commutator(b1, b2, operation_policy=operation_policy) return (b1 + _M6_C2 * b3 + _M6_C3 * commutator( -20 * b1 - b3 + b1_b2_commutator, b2 - _M6_C4 * commutator( b1, 2 * b3 + b1_b2_commutator, operation_policy=operation_policy), operation_policy=operation_policy))
def magnus_m4(a1, a2, dt, operation_policy=OperationPolicy.CPU): """ a magnus expansion method of order four as seen in https://arxiv.org/abs/1709.06483 Args: a1 :: numpy.ndarray - see paper a2 :: numpy.ndarray - see paper dt :: float - see paper operation_policy Returns: m4 :: numpy.ndarray - magnus expansion """ return ((dt / 2) * (a1 + a2) + _M4_C0 * np.power(dt, 2) * commutator(a2, a1, operation_policy=operation_policy))
def magnus_m4(a, dt, time): """ Construct a magnus expasion of `a` of order four. References: [1] https://arxiv.org/abs/1709.06483 Arguments: a :: (time :: float) -> ndarray (a_shape) - the matrix to expand dt :: float - the time step time :: float - the current time Returns: m4 :: ndarray (a_shape) - magnus expansion """ t1 = time + dt * _M4_C1 t2 = time + dt * _M4_C2 a1 = a(t1) a2 = a(t2) m4 = ((dt / 2) * (a1 + a2) + _M4_F0 * (dt**2) * commutator(a2, a1)) return m4