def test_opservables_spin():
    def onsite(site, B):
        return 2 * np.eye(2) + B * sigmaz

    L = 20
    lat = kwant.lattice.chain(norbs=2)
    syst = kwant.Builder()
    syst[(lat(i) for i in range(L))] = onsite
    syst[lat.neighbors()] = -1 * np.eye(2)
    lead = kwant.Builder(kwant.TranslationalSymmetry((-1, )))
    lead[lat(0)] = onsite
    lead[lat.neighbors()] = -1 * np.eye(2)
    syst.attach_lead(lead)
    syst.attach_lead(lead.reversed())
    fsyst = syst.finalized()
    args = (0.1, )
    down, up = kwant.wave_function(fsyst, energy=1., args=args)(0)

    x_hoppings = kwant.builder.HoppingKind((1, ), lat)
    spin_current_z = ops.Current(fsyst, sigmaz, where=x_hoppings(syst))
    _test(spin_current_z, up, args=args, per_el_val=1)
    _test(spin_current_z, down, args=args, per_el_val=-1)

    # calculate spin_x torque
    spin_torque_x = ops.Source(fsyst, sigmax, where=[lat(L // 2)])
    i = fsyst.id_by_site[lat(L // 2)]
    psi = up[2 * i:2 * (i + 1)] + down[2 * i:2 * (i + 1)]
    H_ii = onsite(None, *args)
    K = np.dot(H_ii, sigmax) - np.dot(sigmax, H_ii)
    expect = 1j * ft.reduce(np.dot, (psi.conj(), K, psi))
    _test(spin_torque_x, up + down, args=args, reduced_val=expect)
def test_opservables_finite():
    lat, syst = _random_square_system(3)
    fsyst = syst.finalized()
    ev, wfs = la.eigh(fsyst.hamiltonian_submatrix())

    Q = ops.Density(fsyst)
    Qtot = ops.Density(fsyst, sum=True)
    J = ops.Current(fsyst)
    K = ops.Source(fsyst)

    for i, wf in enumerate(wfs.T):  # wfs[:, i] is i'th eigenvector
        assert np.allclose(Q.act(wf), wf)  # this operation is identity
        _test(Q, wf, reduced_val=1)  # eigenvectors are normalized
        _test(Qtot, wf, per_el_val=1)  # eigenvectors are normalized
        _test(J, wf, per_el_val=0)  # time-reversal symmetry: no current
        _test(K, wf, per_el_val=0)  # onsite commutes with hamiltonian

    # check that we get correct (complex) output
    for bra, ket in zip(wfs.T, wfs.T):
        _test(Q, bra, ket, per_el_val=(bra * ket))

    # check with get_hermiticity=False
    Qi = ops.Density(fsyst, 1j, check_hermiticity=False)
    for wf in wfs.T:  # wfs[:, i] is i'th eigenvector
        assert np.allclose(Qi.act(wf), 1j * wf)

    # test with different numbers of orbitals
    lat2 = kwant.lattice.chain(norbs=2)
    extra_sites = [lat2(i) for i in range(len(fsyst.sites))]
    syst[extra_sites] = np.eye(2)
    syst[zip(fsyst.sites, extra_sites)] = ta.matrix([1, 1])
    fsyst = syst.finalized()
    ev, wfs = la.eigh(fsyst.hamiltonian_submatrix())

    Q = ops.Density(fsyst)
    Qtot = ops.Density(fsyst, sum=True)
    J = ops.Current(fsyst)
    K = ops.Source(fsyst)

    for wf in wfs.T:  # wfs[:, i] is i'th eigenvector
        assert np.allclose(Q.act(wf), wf)  # this operation is identity
        _test(Q, wf, reduced_val=1)  # eigenvectors are normalized
        _test(Qtot, wf, per_el_val=1)  # eigenvectors are normalized
        _test(J, wf, per_el_val=0)  # time-reversal symmetry: no current
        _test(K, wf, per_el_val=0)  # onsite commutes with hamiltonian