14 #include "catch2/catch.hpp" 27 TEST_CASE(
"Intel-QS simulator creation",
"[simulator]"){
29 DYNAMIC_SECTION(
"Register creation with " << std::to_string(
num_qubits) <<
" qubits"){
43 auto& reg =
sim.getQubitRegister();
46 SECTION(
"Initial state as |0>"){
47 REQUIRE(reg[0] == std::complex<double>(1.,0.) );
48 REQUIRE(reg[1] == std::complex<double>(0.,0.) );
50 SECTION(
"Pauli X |0>"){
52 REQUIRE(reg[0].real() == std::complex<double>(0.,0.));
53 REQUIRE(reg[1].real() == std::complex<double>(1.,0.));
55 SECTION(
"Pauli Y |0>"){
57 REQUIRE(reg[0] == std::complex<double>(0.,0.));
58 REQUIRE(reg[1] == std::complex<double>(0.,1.));
60 SECTION(
"Pauli Z |0>"){
62 REQUIRE(reg[0] == std::complex<double>(1.,0.) );
63 REQUIRE(reg[1] == std::complex<double>(0.,0.) );
68 SECTION(
"Pauli X |1>"){
70 REQUIRE(reg[0] == std::complex<double>(1.,0.));
71 REQUIRE(reg[1] == std::complex<double>(0.,0.));
73 SECTION(
"Pauli Y |1>"){
75 REQUIRE(reg[0] == std::complex<double>(0.,-1.));
76 REQUIRE(reg[1] == std::complex<double>(0.,0.));
78 SECTION(
"Pauli Z |1>"){
80 REQUIRE(reg[0] == std::complex<double>(0.,0.));
81 REQUIRE(reg[1] == std::complex<double>(-1.,0.));
96 SECTION(
"ISimulator virtual base pointer"){
98 REQUIRE(
s1->getNumQubits() == 8);
101 SECTION(
"SimulatorGeneral<IntelSimulator> pointer"){
106 SECTION(
"unique_ptr<ISimulator> to IntelSimulator object"){
110 SECTION(
"unique_ptr<ISimulator> to IntelSimulator object"){
111 std::unique_ptr<SimulatorGeneral<IntelSimulator> > s4(
new IntelSimulator(8));
112 REQUIRE(s4->getNumQubits() == 8);
114 SECTION(
"Create multiple simulator objects"){
116 std::unique_ptr<SimulatorGeneral<IntelSimulator>> s6(
new IntelSimulator(8));
130 SECTION(
"Measure single qubit"){
134 SECTION(
"State |0>"){
135 REQUIRE(
sim->applyMeasurement(0) == 0 );
137 SECTION(
"State |1>"){
139 REQUIRE(
sim->applyMeasurement(0) == 1 );
145 SECTION(
"Measure multiple qubits"){
147 std::size_t test_val = 0;
153 for(std::size_t i = 0; i <
num_qubits + 1; i++){
154 DYNAMIC_SECTION(
"Encoded " << i){
157 for(std::size_t j = 0; j < i; j++){
158 sim->applyGateX(reg[j]);
160 test_val = (test_val << 1) | 1;
163 REQUIRE(
sim->applyMeasurementToRegister(reg) == test_val);
175 TEST_CASE(
"Encoding even distribution: Unique Binary Patterns"){
176 SECTION(
"Check encoding works correctly without throws and with expected distribution"){
177 std::size_t max_num_qubits_mem = 6;
178 std::size_t num_exp = 500;
184 for( std::size_t num_qubits_mem = 3; num_qubits_mem < max_num_qubits_mem; num_qubits_mem++){
185 DYNAMIC_SECTION(
"Encoding " << num_qubits_mem <<
" qubits"){
187 std::vector<std::size_t> reg_mem(num_qubits_mem);
188 for(std::size_t i = 0; i < num_qubits_mem; i++){
192 for(std::size_t i = 0; i < num_qubits_mem + 2; i++){
196 std::size_t num_bin_patterns = 4;
198 std::vector<std::size_t> bin_patterns(num_bin_patterns);
199 bin_patterns[0] = pow(2,num_qubits_mem)-1;
201 bin_patterns[2] = (std::size_t)pow(2,num_qubits_mem)-1 >> (num_qubits_mem / 2);
202 bin_patterns[3] = ((std::size_t)pow(2,num_qubits_mem)-1 >> (num_qubits_mem / 2)) << (num_qubits_mem / 2);
204 std::map<std::size_t, std::size_t> count_bin_pattern;
205 for(std::size_t i = 0; i < num_bin_patterns; i++){
206 count_bin_pattern.insert(std::pair<std::size_t,std::size_t>(bin_patterns[i],0));
211 for(std::size_t exp = 0; exp < num_exp; exp++){
214 sim->encodeBinToSuperpos_unique(reg_mem,
reg_auxiliary, bin_patterns,num_qubits_mem);
215 result =
sim->applyMeasurementToRegister(reg_mem);
218 CHECK_THAT(bin_patterns, Catch::Matchers::VectorContains(result));
221 count_bin_pattern[result]++;
226 Approx
target = Approx(num_exp / num_bin_patterns).epsilon(0.30);
227 for(std::map<std::size_t,std::size_t>::iterator it = count_bin_pattern.begin(); it != count_bin_pattern.end(); it++){
228 CHECK(
target == (
double) it->second);
242 SECTION(
"Check encoding works correctly without throws and with expected distribution"){
243 std::size_t max_num_qubits_mem = 6;
244 std::size_t num_exp = 500;
249 for( std::size_t num_qubits_mem = 3; num_qubits_mem < max_num_qubits_mem; num_qubits_mem++){
250 DYNAMIC_SECTION(
"Encoding " << num_qubits_mem <<
" qubits"){
252 std::vector<std::size_t> reg_mem(num_qubits_mem);
253 for(std::size_t i = 0; i < num_qubits_mem; i++){
257 for(std::size_t i = 0; i < num_qubits_mem + 2; i++){
261 std::size_t num_bin_patterns = 4;
263 std::vector<std::size_t> bin_patterns(num_bin_patterns);
264 bin_patterns[0] = pow(2,num_qubits_mem)-1;
266 bin_patterns[2] = (std::size_t)pow(2,num_qubits_mem)-1 >> (num_qubits_mem / 2);
267 bin_patterns[3] = ((std::size_t)pow(2,num_qubits_mem)-1 >> (num_qubits_mem / 2)) << (num_qubits_mem / 2);
269 std::map<std::size_t, std::size_t> count_bin_pattern;
270 for(std::size_t i = 0; i < num_bin_patterns; i++){
271 count_bin_pattern.insert(std::pair<std::size_t,std::size_t>(bin_patterns[i],0));
276 for(std::size_t exp = 0; exp < num_exp; exp++){
279 sim->encodeBinToSuperpos_unique(reg_mem,
reg_auxiliary, bin_patterns,num_qubits_mem);
280 result =
sim->applyMeasurementToRegister(reg_mem);
283 count_bin_pattern[result]++;
288 Approx
target = Approx(num_exp / num_bin_patterns).epsilon(0.30);
289 for(std::map<std::size_t,std::size_t>::iterator it = count_bin_pattern.begin(); it != count_bin_pattern.end(); it++){
290 CHECK(
target == (
double) it->second);
QubitRegister< ComplexDP > & getQubitRegister()
Get the Qubit Register object.
Class definition for IntelSimulator. The purpose of this class is to map the functionality of the und...
std::size_t getNumQubits()
Get the number of Qubits.
std::size_t getNumQubits()
Get the number of Qubits.
TEST_CASE("Intel-QS simulator creation","[simulator]")
Tests creating a simulator (in this case, the Intel-QS), for a variety of different qubit counts,...
virtual std::size_t getNumQubits()=0
Get the Number of qubits in the simulator.