Deutsch-Jozsa

 1import typing
 2
 3import qblaze
 4
 5
 6ORACLE_N = 4
 7
 8
 9def deutsch_jozsa(oracle: typing.Callable[[qblaze.Simulator], None]) -> None:
10    sim = qblaze.Simulator()
11
12    sim.x(ORACLE_N)
13
14    for i in range(ORACLE_N + 1):
15        sim.h(i)
16
17    oracle(sim)
18
19    for i in range(ORACLE_N):
20        sim.h(i)
21
22    prob = 1.0
23    num_ones = 0
24    for i in range(ORACLE_N):
25        (r, p0, p1) = sim.measure_ext(i)
26        if r:
27            prob *= p1
28            num_ones += 1
29        else:
30            prob *= p0
31
32    meaning = f'balanced' if num_ones else 'constant'
33    print(f'Measured {num_ones} ones ({meaning}), likelihood {prob:f}')
34
35
36def constant_oracle(sim: qblaze.Simulator) -> None:
37    sim.x(ORACLE_N)
38
39
40def balanced_oracle(sim: qblaze.Simulator) -> None:
41    sim.ccx(0, 1, 2)
42    sim.cx(2, ORACLE_N)
43    sim.ccx(0, 1, 2)
44    sim.cx(3, ORACLE_N)
45
46
47print('Constant oracle')
48deutsch_jozsa(constant_oracle)
49print('Balanced oracle')
50deutsch_jozsa(balanced_oracle)
 1import random
 2import typing
 3from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit, ClassicalRegister
 4
 5import qblaze.qiskit
 6
 7
 8def deutsch_jozsa(
 9    n: int,
10    oracle: typing.Callable[[QuantumCircuit, QuantumRegister, Qubit], None],
11) -> None:
12    x = QuantumRegister(n)
13    y = QuantumRegister(1)
14    r = ClassicalRegister(n)
15    circ = QuantumCircuit(x, y, r)
16
17    circ.x(y)
18    circ.h(x)
19    circ.h(y)
20    oracle(circ, x, y[0])
21    circ.h(x)
22    circ.measure(x, r)
23
24    backend = qblaze.qiskit.Backend()
25
26    shots = 128
27    result = backend.run(circ, shots=shots).result()
28
29    zero_prob = result.data()['counts'].get('0x0', 0) / shots
30    print(f'Measured probability for constant: {zero_prob}')
31
32
33def constant_oracle(circ: QuantumCircuit, x: QuantumRegister, y: Qubit) -> None:
34    circ.x(y)
35
36
37def balanced_oracle(circ: QuantumCircuit, x: QuantumRegister, y: Qubit) -> None:
38    circ.ccx(x[0], x[1], x[2])
39    circ.cx(x[2], y)
40    circ.ccx(x[0], x[1], x[2])
41    circ.cx(x[3], y)
42
43
44print('Constant oracle')
45deutsch_jozsa(4, constant_oracle)
46print('Balanced oracle')
47deutsch_jozsa(4, balanced_oracle)
 1#define _GNU_SOURCE
 2#define _USE_MATH_DEFINES
 3#include <qblaze.h>
 4#include <math.h>
 5#include <stdio.h>
 6#include <stdlib.h>
 7#include <unistd.h>
 8
 9#define ORACLE_N 4
10
11static uint64_t rand64(void) {
12    uint64_t val;
13    int r = getentropy(&val, sizeof(val));
14    if (r < 0) {
15        perror("getentropy");
16        abort();
17    }
18    return val;
19}
20
21int deutsch_jozsa(int (*oracle)(QBlazeSimulator*)) {
22    QBlazeSimulator *sim = qblaze_new(NULL);
23    if (!sim) return QBLAZE_ERR_MEMORY;
24
25    int r = qblaze_apply_u3(sim, ORACLE_N, M_PI, M_PI, 0); // X
26    if (r < 0) goto fail;
27
28    for (size_t i = 0; i <= ORACLE_N; i++) {
29        r = qblaze_apply_u3(sim, i, M_PI_2, 0, M_PI); // H
30        if (r < 0) goto fail;
31    }
32
33    r = oracle(sim);
34    if (r < 0) goto fail;
35
36    for (size_t i = 0; i < ORACLE_N; i++) {
37        r = qblaze_apply_u3(sim, i, M_PI_2, 0, M_PI); // H
38        if (r < 0) goto fail;
39    }
40
41    double prob = 1.0;
42    size_t num_ones = 0;
43
44    for (size_t i = 0; i < ORACLE_N; i++) {
45        double p0, p1;
46        int r = qblaze_measure(sim, i, rand64(), &p0, &p1);
47        if (r < 0) goto fail;
48        if (r) {
49            num_ones++;
50            prob *= p1;
51        } else {
52            prob *= p0;
53        }
54    }
55
56    qblaze_del(sim);
57
58    const char *meaning = num_ones ? "balanced" : "constant";
59
60    printf("Measured %zu ones (%s), likelihood %lf\n", num_ones, meaning, prob);
61    return 0;
62
63fail:
64    qblaze_del(sim);
65    return r;
66}
67
68static int constant_oracle(QBlazeSimulator *sim) {
69    return qblaze_apply_u3(sim, ORACLE_N, M_PI, M_PI, 0); // X
70}
71
72static int balanced_oracle(QBlazeSimulator *sim) {
73    int r;
74    r = qblaze_apply_mcx(sim, (struct QBlazeControl[]){{0, true}, {1, false}}, 2, 2);
75    if (r < 0) return r;
76    r = qblaze_apply_mcx(sim, (struct QBlazeControl[]){{2, true}}, 1, ORACLE_N);
77    if (r < 0) return r;
78    r = qblaze_apply_mcx(sim, (struct QBlazeControl[]){{0, true}, {1, false}}, 2, 2);
79    if (r < 0) return r;
80
81    return qblaze_apply_mcx(sim, (struct QBlazeControl[]){{3, true}}, 1, ORACLE_N);
82}
83
84int main() {
85    int r;
86
87    printf("Constant oracle\n");
88    r = deutsch_jozsa(constant_oracle);
89    if (r < 0) goto fail;
90
91    printf("Balanced oracle\n");
92    r = deutsch_jozsa(balanced_oracle);
93    if (r < 0) goto fail;
94
95    return 0;
96fail:
97    fprintf(stderr, "Error %d\n", r);
98    return -1;
99}