Quanlse/Utils/ODESolver.py
def solverAdaptive(ham: 'QHamiltonian', state0: ndarray = None, shot=None, tolerance: float = 0.01, accelerate=False):
    """
    Run the program calculating the unitary evolution operator for Hamiltonian.
    This is the adaptive algorithm for piecewise-constant, using the pulse sequences given in `hamiltonian`.
    In this algorithm, it applies the strategy of adaptive-step to accelerate the calculation.

    :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 shot: return the population of the eigenstates when ``shot`` is provided
    :param tolerance: the greatest error for approximation
    :param accelerate: use numba expm if true
    :return: Return a dictionary containing the result.
    """

    # Import expm
    if accelerate:
        try:
            from Quanlse.Utils.NumbaSupport import expm
        except ImportError:
            raise Error.Error("You should install Numba to activate the acceleration; "
                              "Please visit https://numba.pydata.org/ for more information.")
    else:
        from scipy.linalg import expm

    sysLevelLen = 1 if isinstance(ham.sysLevel, int) else len(ham.sysLevel)
    sysLevel = [ham.sysLevel] if isinstance(ham.sysLevel, int) else ham.sysLevel
    subSysNum = ham.subSysNum
    maxDt = ham.job.endTimeDt

    if state0 is not None:
        # Initialize stateOrUnitary
        stateOrUnitary = copy.deepcopy(state0)
    else:
        # If the sysLevel is an integer to indicate the same energy level for each subsystem
        if sysLevelLen == 1:
            stateOrUnitary = identity(sysLevel[0] ** subSysNum, dtype=complex)
        else:
            # If the sysLevel is a list of energy levels for different subsystem
            dim = 1
            for subSysLvl in sysLevel:
                dim = dim * subSysLvl
            stateOrUnitary = identity(dim, dtype=complex)

    # Start time
    startTime = time.time()

    # Start calculation
    calcCount = 0
    nowDt = 0
    while nowDt < maxDt:
        totalHam = ham.driftCache.copy()
        # Decide the step of adaptive algorithm
        maxChange = 0
        forwardStep = 1
        while nowDt < maxDt - forwardStep and maxChange < tolerance:
            for key in ham.ctrlCache:
                currentSeq = ham.waveCache[key][nowDt]
                nextSeq = ham.waveCache[key][nowDt + forwardStep]
                change = abs(nextSeq - currentSeq)
                if change > maxChange:
                    maxChange = change
            forwardStep += 1
        forwardStep -= 1
        forwardStep = max(1, forwardStep)
        # Calculate the total Hamiltonian
        for key in ham.ctrlCache:
            averageSequence = 0
            for innerDt in range(nowDt, nowDt + forwardStep):
                # Obtain the sequence
                currentSequence = ham.waveCache[key][innerDt]
                averageSequence += currentSequence
            totalHam += ham.ctrlCache[key] * averageSequence / forwardStep

        calcCount += 1
        tUnitary = expm(- 1j * totalHam * ham.dt * forwardStep)

        nowDt += forwardStep
        stateOrUnitary = dot(tUnitary, stateOrUnitary)

    if state0 is not None:
        _state = stateOrUnitary
        _unitary = None
        if shot is not None:
            _population = list(map(int, round(square(abs(_state)) * shot)))
        else:
            _population = None
    else:
        _unitary = stateOrUnitary
        _state = None
        _population = None

    ret = {
        "unitary": _unitary,
        "state": _state,
        "population": _population,
        "dt": ham.dt,
        "dts": ham.job.endTimeDt,
        "ns": ham.job.endTimeDt * ham.dt,
        "time_consuming": time.time() - startTime,
        "evolution_history": None,
        "numba-simulator": "local-built-in-adaptive"
    }
    return ret

    Run the program calculating the unitary evolution operator for Hamiltonian.
    This is the adaptive algorithm for piecewise-constant, using the pulse sequences given in `hamiltonian`.
    In this algorithm, it applies the strategy of adaptive-step to accelerate the calculation.

    :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 shot: return the population of the eigenstates when ``shot`` is provided
    :param tolerance: the greatest error for approximation
    :param accelerate: use numba expm if true
    :return: Return a dictionary containing the result.
    
Run the program calculating the unitary evolution operator for Hamiltonian.
This is the adaptive algorithm for piecewise-constant, using the pulse sequences given in `hamiltonian`.
In this algorithm, it applies the strategy of adaptive-step to accelerate the calculation.
Run the program calculating the unitary evolution operator for Hamiltonian . This is the adaptive algorithm for piecewise - constant using the pulse sequences given in ` hamiltonian ` . In this algorithm it applies the strategy of adaptive - step to accelerate the calculation .
def solverAdaptive(ham: 'QHamiltonian', state0: ndarray = None, shot=None, tolerance: float = 0.01, accelerate=False):
    if accelerate:
        try:
            from Quanlse.Utils.NumbaSupport import expm
        except ImportError:
            raise Error.Error("You should install Numba to activate the acceleration; "
                              "Please visit https://numba.pydata.org/ for more information.")
    else:
        from scipy.linalg import expm
    sysLevelLen = 1 if isinstance(ham.sysLevel, int) else len(ham.sysLevel)
    sysLevel = [ham.sysLevel] if isinstance(ham.sysLevel, int) else ham.sysLevel
    subSysNum = ham.subSysNum
    maxDt = ham.job.endTimeDt
    if state0 is not None:
        stateOrUnitary = copy.deepcopy(state0)
    else:
        if sysLevelLen == 1:
            stateOrUnitary = identity(sysLevel[0] ** subSysNum, dtype=complex)
        else:
            dim = 1
            for subSysLvl in sysLevel:
                dim = dim * subSysLvl
            stateOrUnitary = identity(dim, dtype=complex)
    startTime = time.time()
    calcCount = 0
    nowDt = 0
    while nowDt < maxDt:
        totalHam = ham.driftCache.copy()
        maxChange = 0
        forwardStep = 1
        while nowDt < maxDt - forwardStep and maxChange < tolerance:
            for key in ham.ctrlCache:
                currentSeq = ham.waveCache[key][nowDt]
                nextSeq = ham.waveCache[key][nowDt + forwardStep]
                change = abs(nextSeq - currentSeq)
                if change > maxChange:
                    maxChange = change
            forwardStep += 1
        forwardStep -= 1
        forwardStep = max(1, forwardStep)
        for key in ham.ctrlCache:
            averageSequence = 0
            for innerDt in range(nowDt, nowDt + forwardStep):
                currentSequence = ham.waveCache[key][innerDt]
                averageSequence += currentSequence
            totalHam += ham.ctrlCache[key] * averageSequence / forwardStep
        calcCount += 1
        tUnitary = expm(- 1j * totalHam * ham.dt * forwardStep)
        nowDt += forwardStep
        stateOrUnitary = dot(tUnitary, stateOrUnitary)
    if state0 is not None:
        _state = stateOrUnitary
        _unitary = None
        if shot is not None:
            _population = list(map(int, round(square(abs(_state)) * shot)))
        else:
            _population = None
    else:
        _unitary = stateOrUnitary
        _state = None
        _population = None
    ret = {
        "unitary": _unitary,
        "state": _state,
        "population": _population,
        "dt": ham.dt,
        "dts": ham.job.endTimeDt,
        "ns": ham.job.endTimeDt * ham.dt,
        "time_consuming": time.time() - startTime,
        "evolution_history": None,
        "numba-simulator": "local-built-in-adaptive"
    }
    return ret
def solverAdaptive ( ham : 'QHamiltonian' , state0 : ndarray = None , shot = None , tolerance : float = 0.01 , accelerate = False ) : if accelerate : try : from Quanlse . Utils . NumbaSupport import expm except ImportError : raise Error . Error ( "You should install Numba to activate the acceleration; " "Please visit https://numba.pydata.org/ for more information." ) else : from scipy . linalg import expm sysLevelLen = 1 if isinstance ( ham . sysLevel , int ) else len ( ham . sysLevel ) sysLevel = [ ham . sysLevel ] if isinstance ( ham . sysLevel , int ) else ham . sysLevel subSysNum = ham . subSysNum maxDt = ham . job . endTimeDt if state0 is not None : stateOrUnitary = copy . deepcopy ( state0 ) else : if sysLevelLen == 1 : stateOrUnitary = identity ( sysLevel [ 0 ] ** subSysNum , dtype = complex ) else : dim = 1 for subSysLvl in sysLevel : dim = dim * subSysLvl stateOrUnitary = identity ( dim , dtype = complex ) startTime = time . time ( ) calcCount = 0 nowDt = 0 while nowDt < maxDt : totalHam = ham . driftCache . copy ( ) maxChange = 0 forwardStep = 1 while nowDt < maxDt - forwardStep and maxChange < tolerance : for key in ham . ctrlCache : currentSeq = ham . waveCache [ key ] [ nowDt ] nextSeq = ham . waveCache [ key ] [ nowDt + forwardStep ] change = abs ( nextSeq - currentSeq ) if change > maxChange : maxChange = change forwardStep += 1 forwardStep -= 1 forwardStep = max ( 1 , forwardStep ) for key in ham . ctrlCache : averageSequence = 0 for innerDt in range ( nowDt , nowDt + forwardStep ) : currentSequence = ham . waveCache [ key ] [ innerDt ] averageSequence += currentSequence totalHam += ham . ctrlCache [ key ] * averageSequence / forwardStep calcCount += 1 tUnitary = expm ( - 1j * totalHam * ham . dt * forwardStep ) nowDt += forwardStep stateOrUnitary = dot ( tUnitary , stateOrUnitary ) if state0 is not None : _state = stateOrUnitary _unitary = None if shot is not None : _population = list ( map ( int , round ( square ( abs ( _state ) ) * shot ) ) ) else : _population = None else : _unitary = stateOrUnitary _state = None _population = None ret = { "unitary" : _unitary , "state" : _state , "population" : _population , "dt" : ham . dt , "dts" : ham . job . endTimeDt , "ns" : ham . job . endTimeDt * ham . dt , "time_consuming" : time . time ( ) - startTime , "evolution_history" : None , "numba-simulator" : "local-built-in-adaptive" } return ret
Run the program calculating the unitary evolution operator for Hamiltonian.
Run the program calculating the unitary evolution operator for Hamiltonian .
"""
    Run the program calculating the unitary evolution operator for Hamiltonian.
    This is the adaptive algorithm for piecewise-constant, using the pulse sequences given in `hamiltonian`.
    In this algorithm, it applies the strategy of adaptive-step to accelerate the calculation.

    :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 shot: return the population of the eigenstates when ``shot`` is provided
    :param tolerance: the greatest error for approximation
    :param accelerate: use numba expm if true
    :return: Return a dictionary containing the result.
    """ # Import expm # Initialize stateOrUnitary # If the sysLevel is an integer to indicate the same energy level for each subsystem # If the sysLevel is a list of energy levels for different subsystem # Start time # Start calculation # Decide the step of adaptive algorithm # Calculate the total Hamiltonian # Obtain the sequence
Return a dictionary containing the result.
Return a dictionary containing the result .
ham
'QHamiltonian'
None
state0
ndarray
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 .
shot
return the population of the eigenstates when ``shot`` is provided
return the population of the eigenstates when ` ` shot ` ` is provided
tolerance
float
the greatest error for approximation
the greatest error for approximation
accelerate
use numba expm if true
use numba expm if true