示例#1
0
def adjacent_open_to_shut_range_mean(u1, u2, QAA, QAF, QFF, QFA, phiA):
    """
    Calculate mean (ideal- no missed events) open times adjacent to a 
    specified shut time range.

    Parameters
    ----------
    u1, u2 : floats
        Shut time range.
    QAA, QAF, QFF, QFA : array_like
        Submatrices of Q.
    phiA : array_like, shape (1, kA)
        Initial vector for openings

    Returns
    -------
    m : float
        Mean open time.
    """
    
    kA = QAA.shape[0]
    uA = np.ones((kA))[:,np.newaxis]
    invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF)
    expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1)
    col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA)
    row1 = np.dot(phiA, qml.Qpow(invQAA, 2))
    row2 = np.dot(phiA, invQAA)
    m = np.dot(row1, col)[0, 0] / np.dot(row2, col)[0, 0]
    return m
示例#2
0
def asymptotic_areas(tres, roots, QAA, QFF, QAF, QFA, kA, kF, GAF, GFA):
    """
    Find the areas of the asymptotic pdf (Eq. 58, HJC92).

    Parameters
    ----------
    tres : float
        Time resolution (dead time).
    roots : array_like, shape (1,kA)
        Roots of the asymptotic pdf.
    QAA : array_like, shape (kA, kA)
    QFF : array_like, shape (kF, kF)
    QAF : array_like, shape (kA, kF)
    QFA : array_like, shape (kF, kA)
        QAA, QFF, QAF, QFA - submatrices of Q.
    kA : int
        A number of open states in kinetic scheme.
    kF : int
        A number of shut states in kinetic scheme.
    GAF : array_like, shape (kA, kB)
    GFA : array_like, shape (kB, kA)
        GAF, GFA- transition probabilities

    Returns
    -------
    areas : ndarray, shape (1, kA)
    """

    expQFF = qml.expQt(QFF, tres)
    expQAA = qml.expQt(QAA, tres)
    eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA)
    phiA = qml.phiHJC(eGAF, eGFA, kA)
    R = qml.AR(roots, tres, QAA, QFF, QAF, QFA, kA, kF)
    uF = np.ones((kF,1))
    areas = np.zeros(kA)
    for i in range(kA):
        areas[i] = ((-1 / roots[i]) *
            np.dot(phiA, np.dot(np.dot(R[i], np.dot(QAF, expQFF)), uF)))

#    rowA = np.zeros((kA,kA))
#    colA = np.zeros((kA,kA))
#    for i in range(kA):
#        WA = qml.W(roots[i], tres,
#            QAA, QFF, QAF, QFA, kA, kF)
#        rowA[i] = qml.pinf(WA)
#        AW = np.transpose(WA)
#        colA[i] = qml.pinf(AW)
#
#    for i in range(kA):
#        uF = np.ones((kF,1))
#        nom = np.dot(np.dot(np.dot(np.dot(np.dot(phiA, colA[i]), rowA[i]),
#            QAF), expQFF), uF)
#        W1A = qml.dW(roots[i], tres, QAF, QFF, QFA, kA, kF)
#        denom = -roots[i] * np.dot(np.dot(rowA[i], W1A), colA[i])
#        areas[i] = nom / denom

    return areas
示例#3
0
def HJC_adjacent_mean_open_to_shut_time_pdf(sht, tres, Q, QAA, QAF, QFF, QFA):
    """
    Calculate theoretical HJC (with missed events correction) mean open time
    given previous/next gap length (continuous function; CHS96 Eq.3.5). 

    Parameters
    ----------
    sht : array of floats
        Shut time interval.
    tres : float
        Time resolution.
    Q : array, shape (k,k)
        Q matrix.
    QAA, QAF, QFF, QFA : array_like
        Submatrices of Q.

    Returns
    -------
    mp : ndarray of floats
        Mean open time given previous gap length.
    mn : ndarray of floats
        Mean open time given next gap length.
    """
    
    kA, kF = QAA.shape[0], QFF.shape[0]
    uA = np.ones((kA))[:,np.newaxis]
    uF = np.ones((kF))[:,np.newaxis]
    expQFF = qml.expQt(QFF, tres)
    expQAA = qml.expQt(QAA, tres)
    GAF, GFA = qml.iGs(Q, kA, kF)
    eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA)
    phiA = qml.phiHJC(eGAF, eGFA, kA)
    phiF = qml.phiHJC(eGFA, eGAF, kF)
    DARS = qml.dARSdS(tres, QAA, QFF, GAF, GFA, expQFF, kA, kF)
    eigs, A = qml.eigs(-Q)
    Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False)
    Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA)
    FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA)
    Q1 = np.dot(np.dot(DARS, QAF), expQFF)
    col1 = np.dot(Q1, uF)
    row1 = np.dot(phiA, Q1)
    
    mp = []
    mn = []
    for t in sht:
        eGFAt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots,
                    FR, QFA, expQAA)
        denom = np.dot(np.dot(phiF, eGFAt), uA)[0]
        nom1 = np.dot(np.dot(phiF, eGFAt), col1)[0]
        nom2 = np.dot(np.dot(row1, eGFAt), uA)[0]
        mp.append(nom1 / denom)
        mn.append(nom2 / denom)
    
    return np.array(mp), np.array(mn)
示例#4
0
def HJC_dependency(top, tsh, tres, Q, QAA, QAF, QFF, QFA):
    """
    Calculate normalised joint distribution (CHS96, Eq. 3.22) of an open time
    and the following shut time as proposed by Magleby & Song 1992. 
    
    Parameters
    ----------
    top, tsh : array_like of floats
        Open and shut tims.
    tres : float
        Time resolution.
    Q : array, shape (k,k)
        Q matrix. 
    QAA, QAF, QFF, QFA : array_like
        Submatrices of Q.

    Returns
    -------
    dependency : ndarray
    """
    
    kA, kF = QAA.shape[0], QFF.shape[0]
    uA = np.ones((kA))[:,np.newaxis]
    uF = np.ones((kF))[:,np.newaxis]
    expQFF = qml.expQt(QFF, tres)
    expQAA = qml.expQt(QAA, tres)
    GAF, GFA = qml.iGs(Q, kA, kF)
    eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA)
    phiA = qml.phiHJC(eGAF, eGFA, kA)
    phiF = qml.phiHJC(eGFA, eGAF, kF)
    eigs, A = qml.eigs(-Q)
    Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False)
    Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA)
    FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA)
    Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(Q, eigs, A, kA, QFF, QAF, QFA, expQFF, True)
    Aroots = asymptotic_roots(tres, QAA, QFF, QAF, QFA, kA, kF)
    AR = qml.AR(Aroots, tres, QAA, QFF, QAF, QFA, kA, kF)

    dependency = np.zeros((top.shape[0], tsh.shape[0]))
    
    for i in range(top.shape[0]):
        eGAFt = qml.eGAF(top[i], tres, Aeigvals, AZ00, AZ10, AZ11, Aroots,
                AR, QAF, expQFF)
        fo = np.dot(np.dot(phiA, eGAFt), uF)[0]
        
        for j in range(tsh.shape[0]):
            eGFAt = qml.eGAF(tsh[j], tres, Feigvals, FZ00, FZ10, FZ11, Froots,
                FR, QFA, expQAA)
            fs = np.dot(np.dot(phiF, eGFAt), uA)[0]
            fos = np.dot(np.dot(np.dot(phiA, eGAFt), eGFAt), uA)[0]
            dependency[i, j] = (fos - (fo * fs)) / (fo * fs)
    return dependency
示例#5
0
def ideal_dwell_time_pdf(t, QAA, phiA):
    """
    Probability density function of the open time.
    f(t) = phiOp * exp(-QAA * t) * (-QAA) * uA
    For shut time pdf A by F in function call.

    Parameters
    ----------
    t : float
        Time (sec).
    QAA : array_like, shape (kA, kA)
        Submatrix of Q.
    phiA : array_like, shape (1, kA)
        Initial vector for openings

    Returns
    -------
    f : float
    """

    kA = QAA.shape[0]
    uA = np.ones((kA, 1))
    expQAA = qml.expQt(QAA, t)
    f = np.dot(np.dot(np.dot(phiA, expQAA), -QAA), uA)
    return f
示例#6
0
def exact_mean_open_shut_time(mec, tres):
    """
    Calculate exact mean open or shut time from HJC probability density
    function.

    Parameters
    ----------
    tres : float
        Time resolution (dead time).
    QAA : array_like, shape (kA, kA)
    QFF : array_like, shape (kF, kF)
    QAF : array_like, shape (kA, kF)
        QAA, QFF, QAF - submatrices of Q.
    kA : int
        A number of open states in kinetic scheme.
    kF : int
        A number of shut states in kinetic scheme.
    GAF : array_like, shape (kA, kB)
    GFA : array_like, shape (kB, kA)
        GAF, GFA- transition probabilities

    Returns
    -------
    mean : float
        Apparent mean open/shut time.
    """
    GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF)
    expQFF = qml.expQt(mec.QFF, tres)
    expQAA = qml.expQt(mec.QAA, tres)
    eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA)

    phiA = qml.phiHJC(eGAF, eGFA, mec.kA)
    phiF = qml.phiHJC(eGFA, eGAF, mec.kF)
    QexpQF = np.dot(mec.QAF, expQFF)
    QexpQA = np.dot(mec.QFA, expQAA)
    DARS = qml.dARSdS(tres, mec.QAA, mec.QFF, GAF, GFA, expQFF, mec.kA, mec.kF)
    DFRS = qml.dARSdS(tres, mec.QFF, mec.QAA, GFA, GAF, expQAA, mec.kF, mec.kA)
    uF, uA = np.ones((mec.kF, 1)), np.ones((mec.kA, 1))
    # meanOpenTime = tres + phiA * DARS * QexpQF * uF
    meanA = tres + np.dot(phiA, np.dot(np.dot(DARS, QexpQF), uF))[0]
    meanF = tres + np.dot(phiF, np.dot(np.dot(DFRS, QexpQA), uA))[0]

    return meanA, meanF
示例#7
0
def exact_GAMAxx(mec, tres, open):
    """
    Calculate gama coeficients for the exact open time pdf (Eq. 3.22, HJC90).

    Parameters
    ----------
    tres : float
    mec : dcpyps.Mechanism
        The mechanism to be analysed.
    open : bool
        True for open time pdf and False for shut time pdf.

    Returns
    -------
    eigen : ndarray, shape (k,)
        Eigenvalues of -Q matrix.
    gama00, gama10, gama11 : ndarrays
        Constants for the exact open/shut time pdf.
    """

    expQFF = qml.expQt(mec.QII, tres)
    expQAA = qml.expQt(mec.QAA, tres)
    GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kI)
    eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kI, expQFF)
    eGFA = qml.eGs(GFA, GAF, mec.kI, mec.kA, expQAA)
    eigs, A = qml.eigs_sorted(-mec.Q)

    if open:
        phi = qml.phiHJC(eGAF, eGFA, mec.kA)
        eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA,
            mec.QII, mec.QAI, mec.QIA, expQFF, open)
        u = np.ones((mec.kI,1))
    else:
        phi = qml.phiHJC(eGFA, eGAF, mec.kI)
        eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA,
            mec.QAA, mec.QIA, mec.QAI, expQAA, open)
        u = np.ones((mec.kA, 1))

    gama00 = (np.dot(np.dot(phi, Z00), u)).T[0]
    gama10 = (np.dot(np.dot(phi, Z10), u)).T[0]
    gama11 = (np.dot(np.dot(phi, Z11), u)).T[0]

    return eigen, gama00, gama10, gama11
示例#8
0
def ideal_subset_time_pdf(Q, k1, k2, t):
    """
    
    """
    
    u = np.ones((k2 - k1 + 1, 1))
    phi, QSub = qml.phiSub(Q, k1, k2)
    expQSub = qml.expQt(QSub, t)
    f = np.dot(np.dot(np.dot(phi, expQSub), -QSub), u)
    return f
示例#9
0
def adjacent_open_to_shut_range_pdf_components(u1, u2, QAA, QAF, QFF, QFA, phiA):
    """
    Calculate time constants and areas for an ideal (no missed events)
    exponential probability density function of open times adjacent to a 
    specified shut time range.

    Parameters
    ----------
    t : float
        Time (sec).
    QAA : array_like, shape (kA, kA)
        Submatrix of Q.
    phiA : array_like, shape (1, kA)
        Initial vector for openings

    Returns
    -------
    taus : ndarray, shape(k, 1)
        Time constants.
    areas : ndarray, shape(k, 1)
        Component relative areas.
    """

    kA = QAA.shape[0]
    uA = np.ones((kA))[:,np.newaxis]
    invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF)
    expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1)
    col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA)
    w = np.zeros(kA)
    eigs, A = qml.eigs(-QAA)
    row = np.dot(phiA, invQAA)
    den = np.dot(row, col)[0, 0]
    #TODO: remove 'for'
    for i in range(kA):
        w[i] = np.dot(np.dot(phiA, A[i]), col) / den
    return eigs, w
示例#10
0
def length_pdf(mec, t):
    """
    Probability density function of the burst length (Eq. 3.17, CH82).
    f(t) = phiB * [PEE(t)]AA * (-QAA) * eB, where PEE(t) = exp(QEE * t)

    Parameters
    ----------
    mec : dcpyps.Mechanism
        The mechanism to be analysed.

    Returns
    -------
    f : float
    """

    expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA]
    f = np.dot(np.dot(np.dot(phiBurst(mec), expQEEA), -mec.QAA),
        endBurst(mec))
    return f
示例#11
0
def length_cond_pdf(mec, t):
    """
    The distribution of burst length coditional on starting state.

    Parameters
    ----------
    mec : dcpyps.Mechanism
        The mechanism to be analysed.
    t : float
        Length.

    Returns
    -------
    vec : array_like, shape (kA, 1)
        Probability of seeing burst length t depending on starting state.
    """

    expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA]
    vec = np.dot(np.dot(expQEEA, -mec.QAA), endBurst(mec))
    vec = vec.transpose()
    return vec
示例#12
0
def HJClik(theta, opts):
    """
    Calculate likelihood for a series of open and shut times using HJC missed
    events probability density functions (first two dead time intervals- exact
    solution, then- asymptotic).

    Lik = phi * eGAF(t1) * eGFA(t2) * eGAF(t3) * ... * eGAF(tn) * uF
    where t1, t3,..., tn are open times; t2, t4,..., t(n-1) are shut times.

    Gaps > tcrit are treated as unusable (e.g. contain double or bad bit of
    record, or desens gaps that are not in the model, or gaps so long that
    next opening may not be from the same channel). However this calculation
    DOES assume that all the shut times predicted by the model are present
    within each group. The series of multiplied likelihoods is terminated at
    the end of the opening before an unusable gap. A new series is then
    started, using appropriate initial vector to give Lik(2), ... At end
    these are multiplied to give final likelihood.

    Parameters
    ----------
    theta : array_like
        Guesses.
    bursts : dictionary
        A dictionary containing lists of open and shut intervals.
    opts : dictionary
        opts['mec'] : instance of type Mechanism
        opts['tres'] : float
            Time resolution (dead time).
        opts['tcrit'] : float
            Ctritical time interval.
        opts['isCHS'] : bool
            True if CHS vectors should be used (Eq. 5.7, CHS96).

    Returns
    -------
    loglik : float
        Log-likelihood.
    newrates : array_like
        Updated rates/guesses.
    """
    # TODO: Errors.

    mec = opts['mec']
    conc = opts['conc']
    tres = opts['tres']
    tcrit = opts['tcrit']
    is_chsvec = opts['isCHS']
    bursts = opts['data']

    mec.theta_unsqueeze(np.exp(theta))
    mec.set_eff('c', conc)

    GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF)
    expQFF = qml.expQt(mec.QFF, tres)
    expQAA = qml.expQt(mec.QAA, tres)
    eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA)
    phiF = qml.phiHJC(eGFA, eGAF, mec.kF)
    startB = qml.phiHJC(eGAF, eGFA, mec.kA)
    endB = np.ones((mec.kF, 1))

    eigen, A = qml.eigs(-mec.Q)
    Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QFF,
        mec.QAF, mec.QFA, expQFF, True)
    Aroots = asymptotic_roots(tres,
        mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF)
    AR = qml.AR(Aroots, tres, mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF)
    Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QAA,
        mec.QFA, mec.QAF, expQAA, False)
    Froots = asymptotic_roots(tres,
        mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA)
    FR = qml.AR(Froots, tres, mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA)

    if is_chsvec:
        startB, endB = qml.CHSvec(Froots, tres, tcrit,
            mec.QFA, mec.kA, expQAA, phiF, FR)

    loglik = 0
    for ind in range(len(bursts)):
        burst = bursts[ind]
        grouplik = startB
        for i in range(len(burst)):
            t = burst[i]
            if i % 2 == 0: # open time
                eGAFt = qml.eGAF(t, tres, Aeigvals, AZ00, AZ10, AZ11, Aroots,
                AR, mec.QAF, expQFF)
            else: # shut
                eGAFt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots,
                FR, mec.QFA, expQAA)
            grouplik = np.dot(grouplik, eGAFt)
            if grouplik.max() > 1e50:
                grouplik = grouplik * 1e-100
                #print 'grouplik was scaled down'
        grouplik = np.dot(grouplik, endB)
        try:
            loglik += log(grouplik[0])
        except:
            print ('HJClik: Warning: likelihood has been set to 0')
            print ('likelihood=', grouplik[0])
            print ('rates=', mec.unit_rates())
            loglik = 0
            break

    newrates = np.log(mec.theta())
    return -loglik, newrates
示例#13
0
def printout_occupancies(mec, tres):
    """
    """

    str = ('\n\n\n*******************************************\n\n' +
        'Open\tEquilibrium\tMean life\tMean latency (ms)\n' +
        'state\toccupancy\t(ms)\tto next shutting\n' +
        '\t\t\tgiven start in this state\n')

    pinf = qml.pinf(mec.Q)

    for i in range(mec.k):
        if i == 0:
            mean_life_A = ideal_subset_mean_life_time(mec.Q, 1, mec.kA)
            str += ('Subset A ' +
                '\t{0:.5g}'.format(np.sum(pinf[:mec.kA])) +
                '\t{0:.5g}\n'.format(mean_life_A * 1000))
        if i == mec.kA:
            mean_life_B = ideal_subset_mean_life_time(mec.Q, mec.kA + 1, mec.kE)
            str += ('\nShut\tEquilibrium\tMean life\tMean latency (ms)\n' +
                'state\toccupancy\t(ms)\tto next opening\n' +
                '\t\t\tgiven start in this state\n' +
                'Subset B ' +
                '\t{0:.5g}'.format(np.sum(pinf[mec.kA : mec.kE])) +
                '\t{0:.5g}\n'.format(mean_life_B * 1000))
        if i == mec.kE:
            mean_life_C = ideal_subset_mean_life_time(mec.Q, mec.kE + 1, mec.kG)
            str += ('\nSubset C ' +
                '\t{0:.5g}'.format(np.sum(pinf[mec.kE : mec.kG])) +
                '\t{0:.5g}\n'.format(mean_life_C * 1000))
        if i == mec.kG:
            mean_life_D = ideal_subset_mean_life_time(mec.Q, mec.kG + 1, mec.k)
            str += ('\nSubset D ' +
                '\t{0:.5g}'.format(np.sum(pinf[mec.kG : mec.k])) +
                '\t{0:.5g}\n'.format(mean_life_D * 1000))

        mean = ideal_mean_latency_given_start_state(mec, i+1)
        str += ('{0:d}'.format(i+1) +
            '\t{0:.5g}'.format(pinf[i]) +
            '\t{0:.5g}'.format(-1 / mec.Q[i,i] * 1000) +
            '\t{0:.5g}\n'.format(mean * 1000))

    expQFF = qml.expQt(mec.QFF, tres)
    expQAA = qml.expQt(mec.QAA, tres)
    GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF)
    eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF)
    eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA)
    phiA = qml.phiHJC(eGAF, eGFA, mec.kA)
    phiF = qml.phiHJC(eGFA, eGAF, mec.kF)

    str += ('\n\nInitial vector for HJC openings phiOp =\n')
    for i in range(phiA.shape[0]):
        str += ('\t{0:.5g}'.format(phiA[i]))
    str += ('\nInitial vector for ideal openings phiOp =\n')
    phiAi = qml.phiA(mec)
    for i in range(phiA.shape[0]):
        str += ('\t{0:.5g}'.format(phiAi[i]))
    str += ('\nInitial vector for HJC shuttings phiSh =\n')
    for i in range(phiF.shape[0]):
        str += ('\t{0:.5g}'.format(phiF[i]))
    str += ('\nInitial vector for ideal shuttings phiSh =\n')
    phiFi = qml.phiF(mec)
    for i in range(phiF.shape[0]):
        str += ('\t{0:.5g}'.format(phiFi[i]))
    str += '\n'
    
    return str
示例#14
0
    def test_openshut(self):

        # # # Initial HJC vectors.
        expQFF = qml.expQt(self.mec.QFF, self.tres)
        expQAA = qml.expQt(self.mec.QAA, self.tres)
        GAF, GFA = qml.iGs(self.mec.Q, self.mec.kA, self.mec.kF)
        eGAF = qml.eGs(GAF, GFA, self.mec.kA, self.mec.kF, expQFF)
        eGFA = qml.eGs(GFA, GAF, self.mec.kF, self.mec.kA, expQAA)
        phiA = qml.phiHJC(eGAF, eGFA, self.mec.kA)
        phiF = qml.phiHJC(eGFA, eGAF, self.mec.kF)

        self.assertAlmostEqual(phiA[0], 0.153966, 6)
        self.assertAlmostEqual(phiA[1], 0.846034, 6)
        self.assertAlmostEqual(phiF[0], 0.530369, 6)
        self.assertAlmostEqual(phiF[1], 0.386116, 6)
        self.assertAlmostEqual(phiF[2], 0.0835153, 6)
        
        # Ideal shut time pdf
        eigs, w = scl.ideal_dwell_time_pdf_components(self.mec.QFF,
            qml.phiF(self.mec))
        self.assertAlmostEqual(eigs[0], 0.263895, 6)
        self.assertAlmostEqual(eigs[1], 2062.93, 2)
        self.assertAlmostEqual(eigs[2], 19011.8, 1)
        self.assertAlmostEqual(w[0], 0.0691263, 6)
        self.assertAlmostEqual(w[1], 17.2607, 4)
        self.assertAlmostEqual(w[2], 13872.7, 1)

        # Asymptotic shut time pdf
        roots = scl.asymptotic_roots(self.tres,
            self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.QAF,
            self.mec.kF, self.mec.kA)
        areas = scl.asymptotic_areas(self.tres, roots,
            self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.QAF,
            self.mec.kF, self.mec.kA, GFA, GAF)
        mean = scl.exact_mean_time(self.tres,
                self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.kF,
                self.mec.kA, GFA, GAF)
        self.assertAlmostEqual(-roots[0], 17090.2, 1)
        self.assertAlmostEqual(-roots[1], 2058.08, 2)
        self.assertAlmostEqual(-roots[2], 0.243565, 6)
        self.assertAlmostEqual(areas[0] * 100, 28.5815, 4)
        self.assertAlmostEqual(areas[1] * 100, 1.67311, 5)
        self.assertAlmostEqual(areas[2] * 100, 68.3542, 4)

        # Exact pdf
        eigvals, gamma00, gamma10, gamma11 = scl.exact_GAMAxx(self.mec,
            self.tres, False)
        self.assertAlmostEqual(gamma00[0], 0.940819, 6)
        self.assertAlmostEqual(gamma00[1], 117.816, 3)
        self.assertAlmostEqual(gamma00[2], 24.8962, 4)
        self.assertAlmostEqual(gamma00[3], 1.28843, 5)
        self.assertAlmostEqual(gamma00[4], 5370.18, 2)
        self.assertAlmostEqual(gamma10[0], 4.57792, 5)
        self.assertAlmostEqual(gamma10[1], 100.211, 3)
        self.assertAlmostEqual(gamma10[2], -5.49855, 4)
        self.assertAlmostEqual(gamma10[3], 0.671548, 6)
        self.assertAlmostEqual(gamma10[4], -99.9617, 4)
        self.assertAlmostEqual(gamma11[0], 0.885141, 6)
        self.assertAlmostEqual(gamma11[1], 43634.99, 1)
        self.assertAlmostEqual(gamma11[2], 718.068, 3)
        self.assertAlmostEqual(gamma11[3], -39.7437, 3)
        self.assertAlmostEqual(gamma11[4], -1.9832288e+06, 0)