Obter estimativas do nível de energiaObtaining energy level estimates

Estimar os valores dos níveis de energia é uma das principais aplicações da química quântica.Estimating the values of energy levels is one of the principal applications of quantum chemistry. Este artigo descreve como pode fazer isto para o exemplo canónico do hidrogénio molecular.This article outlines how you can perform this for the canonical example of molecular hydrogen. A amostra referenciada nesta secção está MolecularHydrogen no repositório de amostras de química.The sample referenced in this section is MolecularHydrogen in the chemistry samples repository. Um exemplo mais visual que traça a saída é a MolecularHydrogenGUI demonstração.A more visual example that plots the output is the MolecularHydrogenGUI demo.

Estimando os valores energéticos do hidrogénio molecularEstimating the energy values of molecular hydrogen

O primeiro passo é construir o Hamiltonian representando o hidrogénio molecular.The first step is to construct the Hamiltonian representing molecular hydrogen. Embora possa construir isto usando a ferramenta NWChem, para a brevidade, esta amostra adiciona os termos Hamiltonian manualmente.Although you can construct this using the NWChem tool, for brevity, this sample adds the Hamiltonian terms manually.

    // These orbital integrals are represented using the OrbitalIntegral
    // data structure.
    var energyOffset = 0.713776188; // This is the coulomb repulsion
    var nElectrons = 2; // Molecular hydrogen has two electrons
    var orbitalIntegrals = new OrbitalIntegral[]
    {
        new OrbitalIntegral(new[] { 0,0 }, -1.252477495),
        new OrbitalIntegral(new[] { 1,1 }, -0.475934275),
        new OrbitalIntegral(new[] { 0,0,0,0 }, 0.674493166),
        new OrbitalIntegral(new[] { 0,1,0,1 }, 0.181287518),
        new OrbitalIntegral(new[] { 0,1,1,0 }, 0.663472101),
        new OrbitalIntegral(new[] { 1,1,1,1 }, 0.697398010),
        // This line adds the identity term.
        new OrbitalIntegral(new int[] { }, energyOffset)
    };

    // Initialize a fermion Hamiltonian data structure and add terms to it.
    var fermionHamiltonian = new OrbitalIntegralHamiltonian(orbitalIntegrals).ToFermionHamiltonian();

Simular o Hamiltonian requer a conversão dos operadores de fermião para operadores qubit.Simulating the Hamiltonian requires converting the fermion operators to qubit operators. Esta conversão é realizada através da codificação Jordan-Wigner da seguinte forma:This conversion is performed through the Jordan-Wigner encoding as follows:

    // The Jordan-Wigner encoding converts the fermion Hamiltonian, 
    // expressed in terms of fermionic operators, to a qubit Hamiltonian,
    // expressed in terms of Pauli matrices. This is an essential step
    // for simulating our constructed Hamiltonians on a qubit quantum
    // computer.
    var jordanWignerEncoding = fermionHamiltonian.ToPauliHamiltonian(Pauli.QubitEncoding.JordanWigner);

    // You also need to create an input quantum state to this Hamiltonian.
    // Use the Hartree-Fock state.
    var fermionWavefunction = fermionHamiltonian.CreateHartreeFockState(nElectrons);

    // This Jordan-Wigner data structure also contains a representation 
    // of the Hamiltonian and wavefunction made for consumption by the Q# operations.
    var qSharpHamiltonianData = jordanWignerEncoding.ToQSharpFormat();
    var qSharpWavefunctionData = fermionWavefunction.ToQSharpFormat();
    var qSharpData = QSharpFormat.Convert.ToQSharpFormat(qSharpHamiltonianData, qSharpWavefunctionData);

Em seguida, passe qSharpData , que representa o Hamiltonian, para a TrotterStepOracle função.Next, pass qSharpData, which represents the Hamiltonian, to the TrotterStepOracle function. TrotterStepOracle retorna uma operação quântica que aproxima a evolução em tempo real do Hamiltonian.TrotterStepOracle returns a quantum operation that approximates the real-time evolution of the Hamiltonian. Para obter mais informações, consulte a dinâmica de Simulação de Hamiltonian.For more information, see Simulating Hamiltonian dynamics.

// qSharpData passed from driver
let qSharpData = ... 

// Choose the integrator step size
let stepSize = 1.0;

// Choose the order of the Trotter—Suzuki integrator.
let integratorOrder = 4;

// `oracle` is an operation that applies a single time-step of evolution for duration `stepSize`.
// `rescale` is just `1.0/stepSize` -- the number of steps required to simulate unit-time evolution.
// `nQubits` is the number of qubits that must be allocated to run the `oracle` operation.
let (nQubits, (rescale, oracle)) =  TrotterStepOracle (qSharpData, stepSize, integratorOrder);

Neste ponto, você pode usar os algoritmos de estimativa de fase da biblioteca padrão para aprender a energia do estado do solo usando a simulação anterior.At this point, you can use the standard library's phase estimation algorithms to learn the ground state energy using the previous simulation. Isto requer a preparação de uma boa aproximação ao estado quântico.This requires preparing a good approximation to the quantum ground state. No esquema são fornecidas sugestões para tais Broombridge aproximações.Suggestions for such approximations are provided in the Broombridge schema. No entanto, sem estas sugestões, a abordagem padrão adiciona uma série de hamiltonian.NElectrons eletrões para minimizar gananciosamente as energias diagonais de um eletrão.However, absent these suggestions, the default approach adds a number of hamiltonian.NElectrons electrons to greedily minimize the diagonal one-electron term energies. As funções e operações de estimativa de fase são fornecidas na notação DocFX no espaço de nomes Microsoft.Quantum.Characterization.The phase estimation functions and operations are provided in DocFX notation in the Microsoft.Quantum.Characterization namespace.

O seguinte corte mostra como a evolução em tempo real da biblioteca de simulação de química se integra com a estimativa da fase quântica.The following snippet shows how the real-time evolution output by the chemistry simulation library integrates with quantum phase estimation.

operation GetEnergyByTrotterization (
    qSharpData : JordanWignerEncodingData, 
    nBitsPrecision : Int, 
    trotterStepSize : Double, 
    trotterOrder : Int) : (Double, Double) {
    
    // The data describing the Hamiltonian for all these steps is contained in
    // `qSharpData`
    let (nSpinOrbitals, fermionTermData, statePrepData, energyOffset) = qSharpData!;
    
    // Using a Product formula, also known as `Trotterization`, to
    // simulate the Hamiltonian.
    let (nQubits, (rescaleFactor, oracle)) = 
        TrotterStepOracle(qSharpData, trotterStepSize, trotterOrder);
    
    // The operation that creates the trial state is defined here.
    // By default, greedy filling of spin-orbitals is used.
    let statePrep = PrepareTrialState(statePrepData, _);
    
    // Using the Robust Phase Estimation algorithm
    // of Kimmel, Low and Yoder.
    let phaseEstAlgorithm = RobustPhaseEstimation(nBitsPrecision, _, _);
    
    // This runs the quantum algorithm and returns a phase estimate.
    let estPhase = EstimateEnergy(nQubits, statePrep, oracle, phaseEstAlgorithm);
    
    // Now, obtain the energy estimate by rescaling the phase estimate
    // with the trotterStepSize. We also add the constant energy offset
    // to the estimated energy.
    let estEnergy = estPhase * rescaleFactor + energyOffset;
    
    // Return both the estimated phase and the estimated energy.
    return (estPhase, estEnergy);
}

Pode agora invocar o Q# código do programa anfitrião.You can now invoke the Q# code from the host program. O seguinte código C# cria um simulador de estado completo e corre GetEnergyByTrotterization para obter a energia do estado do solo.The following C# code creates a full-state simulator and runs GetEnergyByTrotterization to obtain the ground state energy.

using (var qsim = new QuantumSimulator())
{
    // Specify the bits of precision desired in the phase estimation 
    // algorithm
    var bits = 7;

    // Specify the step size of the simulated time evolution. The step size needs to
    // be small enough to avoid aliasing of phases, and also to control the
    // error of simulation.
    var trotterStep = 0.4;

    // Choose the Trotter integrator order
    Int64 trotterOrder = 1;

    // As the quantum algorithm is probabilistic, run a few trials.

    // This may be compared to true value of
    Console.WriteLine("Exact molecular hydrogen ground state energy: -1.137260278.\n");
    Console.WriteLine("----- Performing quantum energy estimation by Trotter simulation algorithm");
    for (int i = 0; i < 5; i++)
    {
        // EstimateEnergyByTrotterization
        var (phaseEst, energyEst) = GetEnergyByTrotterization.Run(qsim, qSharpData, bits, trotterStep, trotterOrder).Result;
    }
}

A operação devolve dois parâmetros:The operation returns two parameters:

  • energyEst é a estimativa da energia do estado do solo e deve ser -1.137 próximo, em média.energyEst is the estimate of the ground state energy and should be close to -1.137 on average.
  • phaseEst é a fase bruta devolvida pelo algoritmo de estimativa de fase.phaseEst is the raw phase returned by the phase estimation algorithm. Isto é útil para diagnosticar o pseudónimo quando ocorre devido a um trotterStep valor que é muito grande.This useful for diagnosing aliasing when it occurs due to a trotterStep value that is too large.