Quanlse/Utils/ODESolver.py
def solverOpenSystem(ham: 'QHamiltonian', state0=None, recordEvolution=False, accelerate=False):
    """
    Calculate the unitary evolution operator with a given Hamiltonian. This function supports
    both single-job and batch-job processing.

    :param ham: QHamiltonian object
    :param state0: the initial state vector. If None is given, this function will return the time-ordered
                   evolution operator, otherwise returns the final state vector.
    :param recordEvolution: the detailed procedure will be recorded if True
    :param accelerate: use numba expm if true
    :return: result dictionary (or a list of result dictionaries when ``jobList`` is provided)
    """
    if state0.shape[1] == 1:
        rho0 = state0 @ dagger(state0)
    else:
        if isRho(state0):
            rho0 = state0
        else:
            raise Error.ArgumentError('The input state is neither a density matrix nor a state vector')

    # Import expm
    if accelerate:
        from Quanlse.Utils.NumbaSupport import expm
    else:
        from scipy.linalg import expm

    ctrlList, waveList = _cacheDictToList(ham.ctrlCache, ham.waveCache)

    startTime = time.time()
    dt = ham.dt
    qubitsNum = ham.subSysNum

    # Cache information
    ld = ham.dissipationSuperCache
    maxDt = ham.job.endTimeDt
    maxNs = ham.job.endTime
    sysLevel = ham.sysLevel

    # Initialization
    evolutionHistory = []
    propHistotry = []
    dim = None

    # 计算维度
    if isinstance(sysLevel, int):
        dim = sysLevel ** qubitsNum
    elif isinstance(sysLevel, list):
        dim = 1
        for i in sysLevel:
            dim = dim * i

    idn = identity(dim, dtype=complex)
    rhoDim = shape(rho0)[0]

    if rhoDim != dim:
        raise Error.ArgumentError(
            f'The dimension of the input density matrix {rhoDim} is not matched with system level {dim}.')

    _rho = copy.deepcopy(rho0)
    evolutionHistory.append(_rho)
    propt = identity(dim * dim, dtype=complex)

    for nowDt in range(0, maxDt):
        # Initialization
        _ham = ham.driftCache.copy()
        for key in range(len(ctrlList)):
            _ham += ctrlList[key] * waveList[key][nowDt]
        lh = kron(_ham, idn) - kron(idn, _ham.T)
        lind = -1j * lh + ld
        # calculate the propagator
        prop = expm(lind * dt)
        # convert the density matrix to a state vector
        _rhoVec = reshape(_rho, (-1, 1))
        # update the state vector using propagator
        _rhoVec = prop @ _rhoVec
        # convert the state vector back to the density matrix
        _rho = reshape(_rhoVec.T, (dim, dim))
        propt = prop @ propt
        if recordEvolution:
            evolutionHistory.append(_rho)
            propHistotry.append(prop)

    ret = {
        "propagator": propt,
        "state": _rho,
        "dt": ham.dt,
        "dts": maxDt,
        "ns": maxNs,
        "time_consuming": time.time() - startTime,
        "propagator_history": propHistotry,
        "evolution_history": evolutionHistory,
        "numba-simulator": "local-built-in-open-sys"
    }
    return ret

    Calculate the unitary evolution operator with a given Hamiltonian. This function supports
    both single-job and batch-job processing.

    :param ham: QHamiltonian object
    :param state0: the initial state vector. If None is given, this function will return the time-ordered
                   evolution operator, otherwise returns the final state vector.
    :param recordEvolution: the detailed procedure will be recorded if True
    :param accelerate: use numba expm if true
    :return: result dictionary (or a list of result dictionaries when ``jobList`` is provided)
    
Calculate the unitary evolution operator with a given Hamiltonian. This function supports
both single-job and batch-job processing.
Calculate the unitary evolution operator with a given Hamiltonian . This function supports both single - job and batch - job processing .
def solverOpenSystem(ham: 'QHamiltonian', state0=None, recordEvolution=False, accelerate=False):
    if state0.shape[1] == 1:
        rho0 = state0 @ dagger(state0)
    else:
        if isRho(state0):
            rho0 = state0
        else:
            raise Error.ArgumentError('The input state is neither a density matrix nor a state vector')
    if accelerate:
        from Quanlse.Utils.NumbaSupport import expm
    else:
        from scipy.linalg import expm
    ctrlList, waveList = _cacheDictToList(ham.ctrlCache, ham.waveCache)
    startTime = time.time()
    dt = ham.dt
    qubitsNum = ham.subSysNum
    ld = ham.dissipationSuperCache
    maxDt = ham.job.endTimeDt
    maxNs = ham.job.endTime
    sysLevel = ham.sysLevel
    evolutionHistory = []
    propHistotry = []
    dim = None
    if isinstance(sysLevel, int):
        dim = sysLevel ** qubitsNum
    elif isinstance(sysLevel, list):
        dim = 1
        for i in sysLevel:
            dim = dim * i
    idn = identity(dim, dtype=complex)
    rhoDim = shape(rho0)[0]
    if rhoDim != dim:
        raise Error.ArgumentError(
            f'The dimension of the input density matrix {rhoDim} is not matched with system level {dim}.')
    _rho = copy.deepcopy(rho0)
    evolutionHistory.append(_rho)
    propt = identity(dim * dim, dtype=complex)
    for nowDt in range(0, maxDt):
        _ham = ham.driftCache.copy()
        for key in range(len(ctrlList)):
            _ham += ctrlList[key] * waveList[key][nowDt]
        lh = kron(_ham, idn) - kron(idn, _ham.T)
        lind = -1j * lh + ld
        prop = expm(lind * dt)
        _rhoVec = reshape(_rho, (-1, 1))
        _rhoVec = prop @ _rhoVec
        _rho = reshape(_rhoVec.T, (dim, dim))
        propt = prop @ propt
        if recordEvolution:
            evolutionHistory.append(_rho)
            propHistotry.append(prop)
    ret = {
        "propagator": propt,
        "state": _rho,
        "dt": ham.dt,
        "dts": maxDt,
        "ns": maxNs,
        "time_consuming": time.time() - startTime,
        "propagator_history": propHistotry,
        "evolution_history": evolutionHistory,
        "numba-simulator": "local-built-in-open-sys"
    }
    return ret
def solverOpenSystem ( ham : 'QHamiltonian' , state0 = None , recordEvolution = False , accelerate = False ) : if state0 . shape [ 1 ] == 1 : rho0 = state0 @ dagger ( state0 ) else : if isRho ( state0 ) : rho0 = state0 else : raise Error . ArgumentError ( 'The input state is neither a density matrix nor a state vector' ) if accelerate : from Quanlse . Utils . NumbaSupport import expm else : from scipy . linalg import expm ctrlList , waveList = _cacheDictToList ( ham . ctrlCache , ham . waveCache ) startTime = time . time ( ) dt = ham . dt qubitsNum = ham . subSysNum ld = ham . dissipationSuperCache maxDt = ham . job . endTimeDt maxNs = ham . job . endTime sysLevel = ham . sysLevel evolutionHistory = [ ] propHistotry = [ ] dim = None if isinstance ( sysLevel , int ) : dim = sysLevel ** qubitsNum elif isinstance ( sysLevel , list ) : dim = 1 for i in sysLevel : dim = dim * i idn = identity ( dim , dtype = complex ) rhoDim = shape ( rho0 ) [ 0 ] if rhoDim != dim : raise Error . ArgumentError ( f'The dimension of the input density matrix {rhoDim} is not matched with system level {dim}.' ) _rho = copy . deepcopy ( rho0 ) evolutionHistory . append ( _rho ) propt = identity ( dim * dim , dtype = complex ) for nowDt in range ( 0 , maxDt ) : _ham = ham . driftCache . copy ( ) for key in range ( len ( ctrlList ) ) : _ham += ctrlList [ key ] * waveList [ key ] [ nowDt ] lh = kron ( _ham , idn ) - kron ( idn , _ham . T ) lind = - 1j * lh + ld prop = expm ( lind * dt ) _rhoVec = reshape ( _rho , ( - 1 , 1 ) ) _rhoVec = prop @ _rhoVec _rho = reshape ( _rhoVec . T , ( dim , dim ) ) propt = prop @ propt if recordEvolution : evolutionHistory . append ( _rho ) propHistotry . append ( prop ) ret = { "propagator" : propt , "state" : _rho , "dt" : ham . dt , "dts" : maxDt , "ns" : maxNs , "time_consuming" : time . time ( ) - startTime , "propagator_history" : propHistotry , "evolution_history" : evolutionHistory , "numba-simulator" : "local-built-in-open-sys" } return ret
Calculate the unitary evolution operator with a given Hamiltonian.
Calculate the unitary evolution operator with a given Hamiltonian .
"""
    Calculate the unitary evolution operator with a given Hamiltonian. This function supports
    both single-job and batch-job processing.

    :param ham: QHamiltonian object
    :param state0: the initial state vector. If None is given, this function will return the time-ordered
                   evolution operator, otherwise returns the final state vector.
    :param recordEvolution: the detailed procedure will be recorded if True
    :param accelerate: use numba expm if true
    :return: result dictionary (or a list of result dictionaries when ``jobList`` is provided)
    """ # Import expm # Cache information # Initialization # 计算维度 # Initialization # calculate the propagator # convert the density matrix to a state vector # update the state vector using propagator # convert the state vector back to the density matrix
result dictionary (or a list of result dictionaries when ``jobList`` is provided)
result dictionary ( or a list of result dictionaries when ` ` jobList ` ` is provided )
ham
'QHamiltonian'
None
state0
the initial state vector. If None is given, this function will return the time-ordered
evolution operator, otherwise returns the final state vector.
the initial state vector . If None is given this function will return the time - ordered evolution operator otherwise returns the final state vector .
recordEvolution
the detailed procedure will be recorded if True
the detailed procedure will be recorded if True
accelerate
use numba expm if true
use numba expm if true