Commit 5ce5507e authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Tidy-up the VQE example script



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 90f18cd9
Loading
Loading
Loading
Loading
+30 −39
Original line number Diff line number Diff line
@@ -8,38 +8,46 @@ open QCOR.Intrinsic;
operation DeuteronVqe(shots: Int, stepper : ((Double, Double[]) => Double[])) : Double {
    // Deuteron Hamiltonian:
    // H = "5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1");
    // Stopping conditions:
    let max_iters = 10;
    let f_tol = 0.01;
    // Initial parameters
    let initial_params = [1.23];
        
    mutable opt_params = initial_params;
    mutable energy_val = 0.0;
    use qubits = Qubit[2]
    {
        for iter_id in 1..max_iters {
        // Use repeat-until-success pattern:
        // when the optimization loop converges,
        // the stepper will return an empty param array.
        repeat {
            let xxExp = DeuteronXX(qubits, shots, opt_params[0]);
            let yyExp = DeuteronYY(qubits, shots, opt_params[0]);
            let z0Exp = DeuteronZ0(qubits, shots, opt_params[0]);
            let z1Exp = DeuteronZ1(qubits, shots, opt_params[0]);
            let z0_z1_exps = DeuteronZ0_Z1(qubits, shots, opt_params[0]);
            let z0Exp = z0_z1_exps[0];
            let z1Exp = z0_z1_exps[1];
            set energy_val = 5.907 - 2.1433 * xxExp - 2.1433 * yyExp + 0.21829 * z0Exp - 6.125 * z1Exp;
            // Stepping...
            set opt_params = stepper(energy_val, opt_params);
        }
        until (Length(opt_params) == 0);
    }
    // Final energy:
    return energy_val;
}

// Base ansatz:
operation ansatz(qubits: Qubit[], theta: Double) : Unit {
    X(qubits[0]);
    Ry(theta, qubits[1]);
    CNOT(qubits[1], qubits[0]);
}

// This is for testing only:
// We should use a nicer implementation...
// XX term
operation DeuteronXX(qubits: Qubit[], shots: Int, theta: Double) : Double {
    mutable numParityOnes = 0;
    for shot in 1..shots {
        X(qubits[0]);
        Ry(theta, qubits[1]);
        CNOT(qubits[1], qubits[0]);
        ansatz(qubits, theta);
        // Let's measure <X0X1>
        H(qubits[0]);
        H(qubits[1]);
@@ -59,9 +67,7 @@ operation DeuteronXX(qubits: Qubit[], shots: Int, theta: Double) : Double {
operation DeuteronYY(qubits: Qubit[], shots: Int, theta: Double) : Double {
    mutable numParityOnes = 0;
    for shot in 1..shots {
        X(qubits[0]);
        Ry(theta, qubits[1]);
        CNOT(qubits[1], qubits[0]);
        ansatz(qubits, theta);
        // Let's measure <Y0Y1>
        Rx(1.57079632679, qubits[0]);
        Rx(1.57079632679, qubits[1]);
@@ -77,42 +83,27 @@ operation DeuteronYY(qubits: Qubit[], shots: Int, theta: Double) : Double {
    return exp_val;
}

// Z0 term
operation DeuteronZ0(qubits: Qubit[], shots: Int, theta: Double) : Double {
    mutable numParityOnes = 0;
// Z0 and Z1 terms
operation DeuteronZ0_Z1(qubits: Qubit[], shots: Int, theta: Double) : Double[] {
    mutable numParityOnesZ0 = 0;
    mutable numParityOnesZ1 = 0;

    for shot in 1..shots {
        X(qubits[0]);
        Ry(theta, qubits[1]);
        CNOT(qubits[1], qubits[0]);
        ansatz(qubits, theta);
        if M(qubits[0]) == One
        {
            set numParityOnes += 1;
            set numParityOnesZ0 += 1;
        }
        Reset(qubits[0]);
        Reset(qubits[1]);
    }
    
    let exp_val =  IntAsDouble(shots - numParityOnes)/IntAsDouble(shots) - IntAsDouble(numParityOnes)/IntAsDouble(shots);
    return exp_val;
}


// Z1 term
operation DeuteronZ1(qubits: Qubit[], shots: Int, theta: Double) : Double {
    mutable numParityOnes = 0;
    for shot in 1..shots {
        X(qubits[0]);
        Ry(theta, qubits[1]);
        CNOT(qubits[1], qubits[0]);
        if M(qubits[1]) == One
        {
            set numParityOnes += 1;
            set numParityOnesZ1 += 1;
        }
        Reset(qubits[0]);
        Reset(qubits[1]);
    }
    
    let exp_val =  IntAsDouble(shots - numParityOnes)/IntAsDouble(shots) - IntAsDouble(numParityOnes)/IntAsDouble(shots);
    return exp_val;
    let exp_val_z0 =  IntAsDouble(shots - numParityOnesZ0)/IntAsDouble(shots) - IntAsDouble(numParityOnesZ0)/IntAsDouble(shots);
    let exp_val_z1 =  IntAsDouble(shots - numParityOnesZ1)/IntAsDouble(shots) - IntAsDouble(numParityOnesZ1)/IntAsDouble(shots);
    return [exp_val_z0, exp_val_z1];
}
}
 No newline at end of file