|
1 | 1 | import numpy as np |
2 | | - |
| 2 | +import matplotlib.pyplot as plt |
| 3 | +#import matplotlib as plt |
3 | 4 | class QuantumFourierTransform: |
4 | 5 | def __init__(self, n_qubits): |
5 | 6 | self.n_qubits = n_qubits |
@@ -82,86 +83,61 @@ def print_amplitudes(self, title="Quantum State"): |
82 | 83 | for i, amp in enumerate(self.state): |
83 | 84 | print(f"|{i:0{self.n_qubits}b}>: {amp:.4f}") |
84 | 85 |
|
| 86 | + def plot_amplitudes(self, title="State Vector Amplitudes", save_path=None): |
| 87 | + labels = [format(i, f'0{self.n_qubits}b') for i in range(self.N)] |
| 88 | + reals = [self.state[i].real for i in range(self.N)] |
| 89 | + imags = [self.state[i].imag for i in range(self.N)] |
| 90 | + x = np.arange(self.N) |
| 91 | + width = 0.35 |
| 92 | + fig, ax = plt.subplots() |
| 93 | + ax.bar(x - width/2, reals, width, label='Real') |
| 94 | + ax.bar(x + width/2, imags, width, label='Imaginary') |
| 95 | + ax.set_xticks(x) |
| 96 | + ax.set_xticklabels(labels, rotation=45) |
| 97 | + ax.set_ylabel('Amplitude') |
| 98 | + ax.set_title(title) |
| 99 | + ax.legend() |
| 100 | + plt.tight_layout() |
| 101 | + |
| 102 | + if save_path: |
| 103 | + plt.savefig(save_path) |
| 104 | + print(f"Plot saved to: {save_path}") |
| 105 | + else: |
| 106 | + plt.show() |
| 107 | + |
| 108 | + def plot_probabilities(self, shots=1024, title="Measurement Probabilities", save_path=None): |
| 109 | + results = self.measure(shots=shots) |
| 110 | + bitstrings = sorted(results.keys()) |
| 111 | + counts = [results[b] for b in bitstrings] |
| 112 | + fig, ax = plt.subplots() |
| 113 | + ax.bar(bitstrings, counts) |
| 114 | + ax.set_xlabel("Bitstring") |
| 115 | + ax.set_ylabel("Counts") |
| 116 | + ax.set_title(title) |
| 117 | + ax.set_xticklabels(bitstrings, rotation=45) |
| 118 | + plt.tight_layout() |
| 119 | + |
| 120 | + if save_path: |
| 121 | + plt.savefig(save_path) |
| 122 | + print(f"Histogram saved to: {save_path}") |
| 123 | + else: |
| 124 | + plt.show() |
| 125 | + |
| 126 | + |
85 | 127 | # --------------------------- |
86 | 128 | # Example usage |
87 | 129 | # --------------------------- |
88 | 130 | if __name__ == "__main__": |
89 | | - qft = QuantumFourierTransform(n_qubits=3) |
90 | | - |
91 | | - # Try different initializations |
92 | | - qft.initialize_superposition() |
93 | | - # qft.initialize_basis_state(5) |
94 | | - # qft.initialize_custom_state(np.random.randn(8) + 1j*np.random.randn(8)) # normalize first |
95 | | - # qft.initialize_ghz_state() |
96 | | - |
97 | | - qft.print_amplitudes("Initial State") |
98 | | - |
99 | | - qft.apply_qft() |
100 | | - qft.print_amplitudes("After QFT") |
101 | | - |
102 | | - results = qft.measure(shots=1024) |
103 | | - print("\nMeasurement Results:") |
104 | | - for b, c in sorted(results.items()): |
105 | | - print(f"{b}: {c}") |
106 | | - |
107 | | - qft.apply_qft(inverse=True) |
108 | | - qft.print_amplitudes("After Inverse QFT") |
109 | | - |
110 | | - |
111 | | - |
112 | | -def plot_amplitudes(self, title="State Vector Amplitudes", save_path=None): |
113 | | - labels = [format(i, f'0{self.n_qubits}b') for i in range(self.N)] |
114 | | - reals = [self.state[i].real for i in range(self.N)] |
115 | | - imags = [self.state[i].imag for i in range(self.N)] |
116 | | - |
117 | | - x = np.arange(self.N) |
118 | | - width = 0.35 |
119 | | - |
120 | | - fig, ax = plt.subplots() |
121 | | - ax.bar(x - width/2, reals, width, label='Real') |
122 | | - ax.bar(x + width/2, imags, width, label='Imaginary') |
123 | | - ax.set_xticks(x) |
124 | | - ax.set_xticklabels(labels, rotation=45) |
125 | | - ax.set_ylabel('Amplitude') |
126 | | - ax.set_title(title) |
127 | | - ax.legend() |
128 | | - plt.tight_layout() |
129 | | - |
130 | | - if save_path: |
131 | | - plt.savefig(save_path) |
132 | | - print(f"Plot saved to: {save_path}") |
133 | | - else: |
134 | | - plt.show() |
135 | | - |
136 | | -def plot_probabilities(self, shots=1024, title="Measurement Probabilities", save_path=None): |
137 | | - results = self.measure(shots=shots) |
138 | | - bitstrings = sorted(results.keys()) |
139 | | - counts = [results[b] for b in bitstrings] |
140 | | - |
141 | | - fig, ax = plt.subplots() |
142 | | - ax.bar(bitstrings, counts) |
143 | | - ax.set_xlabel("Bitstring") |
144 | | - ax.set_ylabel("Counts") |
145 | | - ax.set_title(title) |
146 | | - ax.set_xticklabels(bitstrings, rotation=45) |
147 | | - plt.tight_layout() |
148 | | - |
149 | | - if save_path: |
150 | | - plt.savefig(save_path) |
151 | | - print(f"Histogram saved to: {save_path}") |
152 | | - else: |
153 | | - plt.show() |
154 | | - |
155 | | -qft = QuantumFourierTransform(3) |
156 | | -qft.initialize_basis_state(5) |
| 131 | + qft = QuantumFourierTransform(3) |
| 132 | + qft.initialize_basis_state(5) |
157 | 133 |
|
158 | | -qft.apply_qft() |
| 134 | + qft.apply_qft() |
159 | 135 |
|
160 | 136 | # Save amplitude plot |
161 | | -qft.plot_amplitudes("QFT Amplitudes", save_path="qft_amplitudes.png") |
| 137 | + qft.plot_amplitudes("QFT Amplitudes", save_path="qft_amplitudes.png") |
162 | 138 |
|
163 | 139 | # Save measurement histogram |
164 | | -qft.plot_probabilities(shots=1024, title="QFT Output Distribution", save_path="qft_histogram.png") |
| 140 | + qft.plot_probabilities(shots=1024, title="QFT Output Distribution", save_path="qft_histogram.png") |
165 | 141 |
|
166 | 142 | """ |
167 | 143 | Quick Tips on Usage |
|
0 commit comments