Esempio n. 1
0
        static void MakeSpinOrbital()
        {
            // First, we assign an orbital index, say `5`. Note that we use 0-indexing,
            // so this is the 6th orbital.
            var orbitalIdx = 5;

            // Second, we assign a spin index, say `Spin.u` for spin up or `Spin.d` for spin down.
            var spin = Spin.d;

            // The spin-orbital (5, ↓) is then
            var spinOrbital0 = new SpinOrbital(orbitalIdx, spin);

            // A tuple `(int, Spin)` is also implicitly recognized as a spin-orbital.
            (int, Spin)tuple = (orbitalIdx, spin);

            // We explicitly specify the type of `spinOrbital1` to demonstrate
            // the implicit cast to `SpinOrbital`.
            SpinOrbital spinOrbital1 = tuple;

            Assert.True(spinOrbital1 == spinOrbital0);
        }
Esempio n. 2
0
        static void LadderOperator()
        {
            // Let us use the spin orbital created in the previous snippet.
            var spinOrbitalInteger = new SpinOrbital(5, Spin.d).ToInt();

            // We specify either a creation or annihilation operator using
            // the enumerable type `RaisingLowering.u` or `RaisingLowering.d`
            // respectively;
            var creationEnum = RaisingLowering.u;

            // The type representing a creation operator is then initialized
            // as follows. Here, we index these operators with integers.
            // Hence we initialize the generic ladder operator with an
            // integer index type.
            var ladderOperator0 = new LadderOperator <int>(creationEnum, spinOrbitalInteger);

            // An alternate constructor for a LadderOperator instead uses
            // a tuple.
            var ladderOperator1 = new LadderOperator <int>((creationEnum, spinOrbitalInteger));

            Assert.Equal(ladderOperator0, ladderOperator1);
        }
Esempio n. 3
0
        static void SpinOrbitalToInt()
        {
            // Let us use the spin orbital created in the previous snippet.
            var spinOrbital = new SpinOrbital(5, Spin.d);

            // Let us set the total number of orbitals to be say, `7`.
            var nOrbitals = 7;

            // This converts a spin-orbital index to a unique integer, in this case `12`,
            // using the formula `g(j,σ)`.
            var integerIndexHalfUp = spinOrbital.ToInt(IndexConvention.HalfUp, nOrbitals);

            // This converts a spin-orbital index to a unique integer, in this case `11`,
            // using the formula `h(j,σ)`.
            var integerIndexUpDown = spinOrbital.ToInt(IndexConvention.UpDown);

            // The default conversion uses the formula `h(j,σ)`, in this case `11`.
            var integerIndexDefault = spinOrbital.ToInt();

            Assert.Equal(11, integerIndexDefault);

            Assert.Equal(12, integerIndexHalfUp);
        }
        static void CreateHubbardHamiltonianTest()
        {
            //////////////////////////////////////////////////////////////////////////
            // Introduction //////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////

            // In this example, we will create a representation of a
            // 1D Hubbard Hamiltonian using the quantum chemistry library.
            // This representation allows one to easily simulate Hamiltonian
            // time-evolution and obtain the cost of simulation.


            // The 1D Hubbard model has `n` sites. Let `i` be the site index,
            // `s` = 1,0 be the spin index, where 0 is up and 1 is down, `t` be the
            // hopping coefficient, `u` the repulsion coefficient, and aᵢₛ the fermionic
            // annihilation operator on the fermion indexed by `(i,s)`. The Hamiltonian
            // of this model is
            //
            //     H ≔ - t/2 Σᵢ (a†ᵢₛ aᵢ₊₁ₛ + a†ᵢ₊₁ₛ aᵢₛ) + u Σᵢ a†ᵢ₀ a†ᵢ₁ aᵢ₁ aᵢ₀
            //
            // Note that we use closed boundary conditions.

            // Contents:
            // - Spin-orbital representation
            // - Hamiltonian term representation
            // - Hamiltonian representation
            // - Building the Hubbard Hamiltonian
            // - Building the Hubbard Hamiltonian through orbital integrals
            // - Jordan–Wigner representation

            #region Spin-orbital representation

            // In the vocabulary of chemistry, the site index is also called the
            // orbital index. Thus a complete description of a fermion index is
            // as spin-orbital. Let us build an example.

            // First, we assign an orbital index, say `5`.
            var orbitalIdx = 5;

            // Second, we assign a spin index. In addition to
            // assigning them up and down integer indices, a good memonic is to
            // label then with a `Spin` enumeration type, say `u` for up and `d`
            // for down.
            var spin = Spin.d;

            // A spin-orbital index is then
            var spinOrbital0 = new SpinOrbital(orbitalIdx, spin);

            // We may also map the composite spin-orbital index into a single integer `x`
            // using the default formula `x = 2 * orbitalIdx + spin`;
            var spinOrbital0Int = spinOrbital0.ToInt();

            // Other indexing schemes are possible. For example, we may use the formula
            // `x = orbitalIdx + nOrbitals * spin`
            var spinOrbital0HalfUpInt = spinOrbital0.ToInt(IndexConvention.HalfUp, 6);

            // Let us print these spin-orbitals to verify they contain the
            // expected information.
            Console.WriteLine($"Spin-orbital representation:");
            Console.WriteLine($"spinOrbital0: (Orbital, Spin) index: ({spinOrbital0.Orbital},{spinOrbital0.Spin}).");
            Console.WriteLine($"spinOrbital0Int: (2 * Orbital + Spin) index: ({spinOrbital0Int}).");
            Console.WriteLine($"spinOrbital0HalfUpInt: (Orbital + nOrbitals * Spin) index: ({spinOrbital0HalfUpInt}).");
            Console.WriteLine($"");
            #endregion

            #region Hamiltonian term representation
            // Each term in the Hamiltonian is then labelled by an ordered sequence of
            // spin-orbtal indices, and a coefficient. By default, normal-ordering is
            // assumed, meaning that all creation operators are left of all annihilation
            // operators. By default, the number of creation and annihilation operators
            // are also assumed to be equal as chemistry Hamiltonian often conserve
            // particle number.

            // Let us represent the Hermitian fermion term 0.5 (a†ᵢₛ aᵢ₊₁ₛ + a†ᵢ₊₁ₛ aᵢₛ), where `i` is 5 and `s`
            // is spin up. As mentioned, we require a coefficient

            var coefficient = 0.5;

            // We also require a sequence of spin-orbital indices.
            var spinOrbitalIndices = new[] { (5, Spin.u), (6, Spin.u) };