Beispiel #1
0
def g1(setup, chlsi, k0, q0, i):

    (i1, i2) = chlsi
    E1 = setup.eigenenergies(1)

    _, Sk1 = smatrix.one_particle(setup, i1, i, np.array([k0 + q0]))
    _, Sk2 = smatrix.one_particle(setup, i2, i, np.array([k0 - q0]))

    fij_sqrd = np.abs(Sk1)**2 + np.abs(Sk2)**2

    fij2_sqrd = 0
    # EE = E1[None, :].conj() - E1[:, None]

    pp, pm = [], []
    nchan = len(setup.channels)
    for j in xrange(nchan):
        pp.append(phi(setup, k0, q0, i, j, i1, i2))
        pm.append(phi(setup, k0, q0, j, i, i1, i2))

        # fij2_sqrd += np.sum((pp[j].conj().T*pp[j] + pm[j].conj().T*pm[j])/EE)

        for ll in xrange(len(E1)):
            for lp in xrange(len(E1)):
                fij2_sqrd += (pp[j][lp].conj() * pp[j][ll] + pm[j][lp].conj() *
                              pm[j][ll]) / (E1[lp].conj() - E1[ll])

    # add a prefactor
    fij2_sqrd *= 2 * np.pi * 1j

    croff = 0
    for j in xrange(len(setup.channels)):
        croff += fijm(setup, k0, q0, i, j, i1, i2).conj() * fij2(k0 + q0, k0 - q0, pp[j], pm[j], E1) \
            + fijp(setup, k0, q0, i, j, i1, i2).conj() * fij2(k0 - q0, k0 + q0, pp[j], pm[j], E1)

    return fij_sqrd + fij2_sqrd + 2 * np.real(croff)
Beispiel #2
0
def coherent_state_tau0_quasilocal(setup, chlsi, chlso, E=0):
    """
    g2 from Mikhails formula

    Parameters
    ----------
    se : Setup
        Scattering setup object
    chlsi : list
        list of incoming channels (must be identical!)
    chlso : list
        list of outgoing channels
    E : float or list
        Incoming two photon state energ(y/ies)
    """
    (i1, i2) = chlsi
    (o1, o2) = chlso

    assert i1 == i2, 'Photons in an incoming coherent state **must** all belong to the same channel.'

    # convert to numpy array
    k0s = np.atleast_1d(E) / 2
    # k0s = E / 2 if util.isarray(E) else np.array([E / 2])

    _, S00 = smatrix.one_particle(setup, i1, o1, k0s)
    _, S11 = smatrix.one_particle(setup, i2, o2, k0s)

    g2a = 1 - (S11 - (i2 == o2)) * (S00 - (i1 == o1)) / (S11 * S00)
    g2b = np.zeros(k0s.shape, np.complex128)

    for i, k0 in enumerate(k0s):
        setup.reset()  # remove cache

        # eigen-energies
        E1 = setup.eigenenergies(1, phi=k0)
        E2 = setup.eigenenergies(2, phi=k0)

        # creation operator in n = 0-1-2 eigenbasis representation
        A01 = setup.transition(1, o1, 0, k0)
        A12 = setup.transition(2, o2, 1, k0)
        A21 = setup.transition(1, i1, 2, k0)
        A10 = setup.transition(0, i2, 1, k0)

        # g2
        g2b[i] = A01 \
            .dot(A12) \
            .dot(np.diag(1 / (2 * k0 - E2))) \
            .dot(A21) \
            .dot(A10 / (k0 - E1[:, None]))[0][0]

    prefactor = 4 * np.pi**2  # * np.prod([setup.gs[ch] for ch in chlsi + chlso])

    return {
        'g2': np.abs(g2a - prefactor / (S11 * S00) * g2b)**2,
        'phi2': np.abs(g2a * S11 * S00 - prefactor * g2b)**2,
        'normalization': S11 * S00,
        'phi2_reducible': g2a * S11 * S00,
        'phi2_irreducible': -prefactor * g2b
    }
Beispiel #3
0
def test_smatrix_oneparticle2():
    m = scattering.Model([0] * 2, [[0, 1, 1]], [0] * 2)
    channels = [
        scattering.Channel(site=0, strength=1),
        scattering.Channel(site=0, strength=1),
    ]
    s = scattering.Setup(m, channels)
    E = 0
    _, S1 = smatrix.one_particle(s, 0, 0, np.array([E]))
    assert (np.isclose(np.abs(S1[0])**2, 1, 1e-3))

    _, S1 = smatrix.one_particle(s, 0, 1, np.array([E]))
    assert np.isclose(np.abs(S1[0]) ** 2, 0, 1e-3), \
        'S(1) fails for two sites which are sidecoupled. S(1) = {0} != 0.'.format(np.abs(S1[0]) ** 2)
Beispiel #4
0
def g2(s, chlsi, chlso, E, dE):
    """
    Calculate the intensity-intensity correlation function as a function of total energy,
    E, and energy discrepancy, dE.

    Parameters
    ----------
    s : Setup
        Scattering setup object.
    chlsi : list
        Input state channel indices.
    chlso : list
        Output state channel indices.
    E : float
        Total energy of input photonic state.
    dE : float
        Energy difference between the two photons in the input state.
    """
    qs, D2, S2, S2in = smatrix.two_particle(s,
                                            chlsi=chlsi,
                                            chlso=chlso,
                                            E=E,
                                            dE=dE)

    Ee = np.array([.5 * (E - dE), .5 * (E + dE)])
    _, S10 = smatrix.one_particle(s, chlsi[0], chlso[0], Ee)
    _, S11 = smatrix.one_particle(s, chlsi[1], chlso[1], Ee)

    # denominator
    dFS2 = np.sum(np.abs(S10)**2 * np.abs(S11)**2)

    # Fourier transform
    FS2 = np.fft.fft(S2) * (qs[1] - qs[0])

    # frequencies
    freqs = np.fft.fftfreq(len(qs), d=qs[1] - qs[0])

    # add delta function contribution
    FS2 += np.exp(np.pi * 1j * E * freqs) * D2[0] + np.exp(
        np.pi * 1j * E * freqs) * D2[1]

    return FS2, dFS2
Beispiel #5
0
def g2_coherent_s(s, chlsi, chlso, E, qs=None):
    """
    g2 for a coherent state (or partially coherent)

    Parameters
    ----------
    s : Setup
        Scattering setup
    chlsi : list
        List of incoming channel indices
    chlso : list
        List of outgoing channel indices
    E : float
        Energy of the two-particle state
    """
    qs, D2, S2, _ = smatrix.two_particle(s,
                                         chlsi=chlsi,
                                         chlso=chlso,
                                         E=E,
                                         dE=0,
                                         qs=qs)

    # Single particle scattering
    Ee = np.array([.5 * E])
    _, S10 = smatrix.one_particle(s, chlsi[0], chlso[0], Ee)
    _, S11 = smatrix.one_particle(s, chlsi[1], chlso[1], Ee)

    dFS2 = np.abs(S10[0])**2 * np.abs(S11[0])**2

    # Fourier transform
    FS2 = np.fft.fft(S2) * (qs[1] - qs[0])

    # times
    times = np.fft.fftfreq(len(qs), d=qs[1] - qs[0])

    # add delta function contribution
    FS2 += np.exp(2 * np.pi * 1j * E / 2 * times) * np.sum(D2)

    return np.abs(FS2[0])**2, dFS2
Beispiel #6
0
def nonlinear(se, chli, chlo, Es, p=0.1):
    """
    Non-linear correction to the transmittance.

    Parameters
    ----------
    se : scattering.Setup object
        Scattering setup object.
    chli : int
        Incoming channel index.
    chlo : int
        Outgoing channel index.
    Es : ndarray
        Single particle energies.
    p : float
        The power = alpha**2/L (number of photons per time/pulse length)
    """
    tr = np.zeros((len(Es), ), dtype=np.complex128)
    t2 = np.zeros((len(Es), ), dtype=np.complex128)
    for chl in xrange(len(se.channels)):
        #  single particle contribution
        s1ij = smatrix.one_particle(se, chli, chl, Es)[1]

        # The t2 contribution
        for i, E in enumerate(Es):
            t2[i] = tmatrix.two_particle(se, (chli, chli), (chlo, chl),
                                         E=2 * E,
                                         dE=0,
                                         qs=np.array([E]))[1][0, 0]

        # result
        tr += 8 * 1j * (np.pi**2) * p * np.conjugate(s1ij) * t2

    s1 = smatrix.one_particle(se, chli, chlo, Es)[1]

    return np.abs(s1 - tr)**2, s1, tr
Beispiel #7
0
def linear(se, chli, chlo, Es):
    """
    Linear component of the single particle transmittance.

    Parameters
    ----------
    se : scattering.Setup object
        Scattering setup object.
    chli : int
        Incoming channel.
    chlo : int
        Outgoing channel.
    Es : ndarray
        Single particle energies.
    """
    return np.abs(smatrix.one_particle(se, chli, chlo, Es)[1])**2
Beispiel #8
0
def g1(se, chli, chlo, Es):
    """
    Plots g1-correlation function.

    Parameters
    ----------
    se : scattering.Setup object
        The scattering setup
    chli : int
        Incoming channel
    chlo : int
        Outgoing channel
    Es : array-like
        List of single-photon energies
    """
    return np.abs(smatrix.one_particle(se, chli, chlo, Es)[1])**2
Beispiel #9
0
def test_smatrix_oneparticle():
    """
    Test the S(1) matrix for one example system
    """
    m = scattering.Model([0] * 2, [[0, 1, 1]], [0] * 2)
    channels = [
        scattering.Channel(site=0, strength=1),
        scattering.Channel(site=1, strength=1),
    ]
    s = scattering.Setup(m, channels)
    E = 0
    _, S1 = smatrix.one_particle(s, 0, 1, np.array([E]))

    S10num = np.abs(S1[0])**2
    S10ana = (2 * np.pi / (1 + (np.pi)**2))**2

    assert np.isclose(S10num, S10ana, 1e-3), \
        'S(1) fails for two-sites coupled in series. S(1) = {0} != {1}.'.format(S10num, S01ana)
Beispiel #10
0
def fijp(setup, k0, q0, i, j, i1, i2):
    _, Si = smatrix.one_particle(setup, i1, j, np.array([k0 + q0]))
    _, Sj = smatrix.one_particle(setup, i2, i, np.array([k0 - q0]))

    return Si * Sj
Beispiel #11
0
def fock_state_local(setup, chlsi, chlso, E, dE, tau=0):
    """
    Compute g^2 correlation function for a general two-photon state.

    Parameters
    ----------
    se : scattering.Model
        A given scattering model
    chlsi : list
        List of incoming two-photon state channel indices.
    chlso : list
        List of outgoing two-photon state channel indices.
    E : float
        Total two-photon energy
    dE : float
        Energy difference between the two photons.
    tau : float
        Time
    """
    # channel indices
    (i1, i2) = chlsi
    (o1, o2) = chlso

    # single photon energies
    k0, q0 = .5 * E, .5 * dE
    k1, k2 = k0 + q0, k0 - q0

    # times
    taus = np.atleast_1d(tau)

    _, S11 = smatrix.one_particle(setup, i1, o1, np.array([k1]))
    _, S22 = smatrix.one_particle(setup, i2, o2, np.array([k2]))

    _, S12 = smatrix.one_particle(setup, i1, o2, np.array([k1]))
    _, S21 = smatrix.one_particle(setup, i2, o1, np.array([k2]))

    g2a = S11 * S22 * np.exp(-1j * q0 * taus) + S21 * S12 * np.exp(
        1j * q0 * taus)

    # eigen energies
    E1, E2 = [setup.eigenenergies(nb) for nb in (1, 2)]

    # creation operator in n = 0-1 eigenbasis representation
    A10, A01, A21, A12 = transitions(setup)

    prefactor = (2 * np.pi)**2 * np.prod([setup.gs[c] for c in chlsi + chlso])

    At = A01[o1] * np.exp(-1j * (E1[None, :] - k0) * taus[:, None])

    g2b = At.dot(A12[o2]).dot(np.diag(1 / (E - E2))).dot(A21[i2]).dot(A10[i1] / (k1 - E1[:, None])) \
        + At.dot(A12[o2]).dot(np.diag(1 / (E - E2))).dot(A21[i1]).dot(A10[i2] / (k2 - E1[:, None])) \
        - (At / (k2 - E1)).dot(A10[i2]).dot(A01[o2]).dot(A10[i1] / (k1 - E1[:, None])) \
        - (At / (k1 - E1)).dot(A10[i1]).dot(A01[o2]).dot(A10[i2] / (k2 - E1[:, None]))

    g2 = np.abs(g2a - prefactor * g2b.T)[:][0]**2
    # normalization
    if o2 == o1:
        g1ig1j = g1(setup, chlsi, k0, q0, o1)**2
    else:
        g1ig1j = g1(setup, chlsi, k0, q0, o1) * g1(setup, chlsi, k0, q0, o2)

    # return
    return g2 / np.abs(g1ig1j[0]), g2, g1ig1j[0]
Beispiel #12
0
def coherent_state_quasilocal(setup, chlsi, chlso, E=0, tau=0):
    """
    g2(E, tau) correlation as a function of incoming energy, E, and
    delay time, tau. Here specifically for quasi-local systems.

    Parameters
    ----------
    se : Setup
        Scattering setup object
    chlsi : list
        list of incoming channels (must be identical!)
    chlso : list
        list of outgoing channels
    E : float or list
        Two photon state energ(y/ies)
    """
    # channels
    # two incoming photons from same channel
    assert chlsi[0] == chlsi[
        1], 'Photons in an incoming coherent state must all belong to the same channel.'

    (i1, _) = chlsi
    (o1, o2) = chlso

    # numpy arraify
    k0s, taus = np.atleast_1d(E / 2, tau)

    # smatrix single photon
    _, S00 = smatrix.one_particle(setup, i1, o1, k0s)
    _, S11 = smatrix.one_particle(setup, i1, o2, k0s)

    g2 = np.zeros((len(k0s), len(taus)), dtype=np.float64)
    S2 = np.zeros((len(k0s), len(taus)), dtype=np.complex128)

    for i, k0 in enumerate(k0s):

        # eigen energies
        E1 = setup.eigenenergies(1, phi=k0)
        E2 = setup.eigenenergies(2, phi=k0)

        # creation operator in n = 0-1 eigenbasis representation
        A01_i = setup.transition(1, o1, 0, k0)
        A12_j = setup.transition(2, o2, 1, k0)
        A01_j = setup.transition(1, o2, 0, k0)

        A21_0 = setup.transition(1, i1, 2, k0)
        A10_0 = setup.transition(0, i1, 1, k0)

        prefactor = 4 * np.pi**2 * np.prod(
            [setup.gs[c] for c in chlsi + chlso])

        op = (A12_j.dot(np.diag(1 / (2 * k0 - E2))).dot(A21_0)
              - np.diag(1 / (k0 - E1)).dot(A10_0).dot(A01_j)) \
            .dot(A10_0 / (k0 - E1[:, None]))

        S2[i, :] = prefactor * np.dot(
            A01_i * np.exp(-1j * (E1[None, :] - k0) * taus[:, None]), op)[:, 0]
        g2[i, :] = np.abs(1 - S2[i, :] / (S00[i] * S11[i]))**2

        # np.abs(1 - (prefactor/(S00[i]*S11[i])
        # * np.dot(A01_i*np.exp(-1j*(E1[None, :] - k0)*taus[:, None]), op))
        # )[:, 0]**2

    return {
        'g2': g2,
        'phi2': np.abs(np.tile(S00 * S11, (len(taus), 1)) - S2)**2,
        'normalization': S11 * S00,
        'phi2_irreducible': S2
    }