From: miha-q <> Date: Wed, 7 Feb 2024 05:13:38 +0000 (-0500) Subject: Wed Feb 7 12:13:38 AM EST 2024 X-Git-Url: http://www.foleosoft.com/?a=commitdiff_plain;h=0e544b801b54e472b445941fde415a1f4f1efaa3;p=QAnsel.git Wed Feb 7 12:13:38 AM EST 2024 --- diff --git a/src/QAnsel.c b/src/QAnsel.c index 4684b6d..84dd4e0 100644 --- a/src/QAnsel.c +++ b/src/QAnsel.c @@ -11,1167 +11,1176 @@ double HIDDEN_VARIABLE; typedef struct { - char n[128]; - uint8_t q0, q1, q2; - double arg0, arg1, arg2; + char n[128]; + uint8_t q0, q1, q2; + double arg0, arg1, arg2; } QInstr; double qansel_rand() { - static uint32_t blockNumber = 0; - uint8_t key[32]; - uint8_t nonce[12]; - uint64_t tmpVariable; - for (uint8_t i = 0; i < 32; i++) - { - if (i % 8 == 0) memcpy(&tmpVariable, &HIDDEN_VARIABLE, sizeof(uint64_t)); - key[i] = tmpVariable & 0xFF; - tmpVariable = tmpVariable >> 8; - } - for (uint8_t i = 0; i < 12; i++) - { - nonce[i] = 0; - } - uint8_t* block = foleo_chacha20(key, nonce, blockNumber++, 4); - uint32_t num = 0; - for (uint8_t i = 0; i < 4; i++) - { - num = (num << 8) | block[i]; - } - free(block); - return ((double)num) / ((double)UINT32_MAX); + /* + static uint32_t blockNumber = 0; + uint8_t key[32]; + uint8_t nonce[12]; + uint64_t tmpVariable; + for (uint8_t i = 0; i < 32; i++) + { + if (i % 8 == 0) memcpy(&tmpVariable, &HIDDEN_VARIABLE, sizeof(uint64_t)); + key[i] = tmpVariable & 0xFF; + tmpVariable = tmpVariable >> 8; + } + for (uint8_t i = 0; i < 12; i++) + { + nonce[i] = 0; + } + uint8_t* block = foleo_chacha20(key, nonce, blockNumber++, 4); + uint32_t num = 0; + for (uint8_t i = 0; i < 4; i++) + { + num = (num << 8) | block[i]; + } + free(block); + */ + FILE* f = fopen("/dev/TrueRNG0", "r"); + uint32_t num = 0; + for (uint8_t i = 0; i < 4; i++) + { + num = (num << 8) | fgetc(f); + } + fclose(f); + return ((double)num) / ((double)UINT32_MAX); } void qansel_cnot(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB) { - uint32_t retLen = (uint32_t)pow(2, qubitCount); - cpx_mtx_t ret; - cpx_mtx_init(&ret, 1, retLen); - cpx_t n; - for (uint32_t i = 0; i < retLen; i++) - { - uint8_t bitAVal = (i >> bitA) & 1; - uint8_t bitBVal = (i >> bitB) & 1; - uint8_t bitBNew = bitAVal ? !bitBVal : bitBVal; - uint32_t j = (i & ~(1 << bitB)) | (bitBNew << bitB); - cpx_mtx_get(stateVector, 0, i, &n); - cpx_mtx_set(&ret, 0, j, &n); - } - cpx_mtx_free(stateVector); - stateVector->ptr = ret.ptr; - stateVector->rows = ret.rows; - stateVector->cols = ret.cols; + uint32_t retLen = (uint32_t)pow(2, qubitCount); + cpx_mtx_t ret; + cpx_mtx_init(&ret, 1, retLen); + cpx_t n; + for (uint32_t i = 0; i < retLen; i++) + { + uint8_t bitAVal = (i >> bitA) & 1; + uint8_t bitBVal = (i >> bitB) & 1; + uint8_t bitBNew = bitAVal ? !bitBVal : bitBVal; + uint32_t j = (i & ~(1 << bitB)) | (bitBNew << bitB); + cpx_mtx_get(stateVector, 0, i, &n); + cpx_mtx_set(&ret, 0, j, &n); + } + cpx_mtx_free(stateVector); + stateVector->ptr = ret.ptr; + stateVector->rows = ret.rows; + stateVector->cols = ret.cols; } void qansel_swap(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB) { - uint32_t retLen = (uint32_t)pow(2, qubitCount); - cpx_mtx_t ret; - cpx_mtx_init(&ret, 1, retLen); - cpx_t n; - for (uint32_t i = 0; i < retLen; i++) - { - uint8_t bitAVal = (i >> bitA) & 1; - uint8_t bitBVal = (i >> bitB) & 1; - uint8_t bitANew = bitBVal; - uint8_t bitBNew = bitAVal; - uint32_t j = (i & ~((1 << bitA) | (1 << bitB))) | ((bitANew << bitA) | (bitBNew << bitB)); - cpx_mtx_get(stateVector, 0, i, &n); - cpx_mtx_set(&ret, 0, j, &n); - } - cpx_mtx_free(stateVector); - stateVector->ptr = ret.ptr; - stateVector->rows = ret.rows; - stateVector->cols = ret.cols; + uint32_t retLen = (uint32_t)pow(2, qubitCount); + cpx_mtx_t ret; + cpx_mtx_init(&ret, 1, retLen); + cpx_t n; + for (uint32_t i = 0; i < retLen; i++) + { + uint8_t bitAVal = (i >> bitA) & 1; + uint8_t bitBVal = (i >> bitB) & 1; + uint8_t bitANew = bitBVal; + uint8_t bitBNew = bitAVal; + uint32_t j = (i & ~((1 << bitA) | (1 << bitB))) | ((bitANew << bitA) | (bitBNew << bitB)); + cpx_mtx_get(stateVector, 0, i, &n); + cpx_mtx_set(&ret, 0, j, &n); + } + cpx_mtx_free(stateVector); + stateVector->ptr = ret.ptr; + stateVector->rows = ret.rows; + stateVector->cols = ret.cols; } void qansel_fredkin(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB, uint8_t bitC) { - uint32_t retLen = (uint32_t)pow(2, qubitCount); - cpx_mtx_t ret; - cpx_mtx_init(&ret, 1, retLen); - cpx_t n; - for (uint32_t i = 0; i < retLen; i++) - { - uint8_t bitAVal = (i >> bitA) & 1; - uint8_t bitBVal = (i >> bitB) & 1; - uint8_t bitCVal = (i >> bitC) & 1; - uint8_t bitBNew = bitAVal ? bitCVal : bitBVal; - uint8_t bitCNew = bitAVal ? bitBVal : bitCVal; - uint32_t j = (i & ~((1 << bitB) | (1 << bitC))) | ((bitBNew << bitB) | (bitCNew << bitC)); - cpx_mtx_get(stateVector, 0, i, &n); - cpx_mtx_set(&ret, 0, j, &n); - } - cpx_mtx_free(stateVector); - stateVector->ptr = ret.ptr; - stateVector->rows = ret.rows; - stateVector->cols = ret.cols; + uint32_t retLen = (uint32_t)pow(2, qubitCount); + cpx_mtx_t ret; + cpx_mtx_init(&ret, 1, retLen); + cpx_t n; + for (uint32_t i = 0; i < retLen; i++) + { + uint8_t bitAVal = (i >> bitA) & 1; + uint8_t bitBVal = (i >> bitB) & 1; + uint8_t bitCVal = (i >> bitC) & 1; + uint8_t bitBNew = bitAVal ? bitCVal : bitBVal; + uint8_t bitCNew = bitAVal ? bitBVal : bitCVal; + uint32_t j = (i & ~((1 << bitB) | (1 << bitC))) | ((bitBNew << bitB) | (bitCNew << bitC)); + cpx_mtx_get(stateVector, 0, i, &n); + cpx_mtx_set(&ret, 0, j, &n); + } + cpx_mtx_free(stateVector); + stateVector->ptr = ret.ptr; + stateVector->rows = ret.rows; + stateVector->cols = ret.cols; } void qansel_toffoli(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB, uint8_t bitC) { - uint32_t retLen = (uint32_t)pow(2, qubitCount); - cpx_mtx_t ret; - cpx_mtx_init(&ret, 1, retLen); - cpx_t n; - for (uint32_t i = 0; i < retLen; i++) - { - uint8_t bitAVal = (i >> bitA) & 1; - uint8_t bitBVal = (i >> bitB) & 1; - uint8_t bitCVal = (i >> bitC) & 1; - uint8_t bitCNew = (bitAVal && bitBVal) ? !bitCVal : bitCVal; - uint32_t j = (i & ~(1 << bitC)) | (bitCNew << bitC); - cpx_mtx_get(stateVector, 0, i, &n); - cpx_mtx_set(&ret, 0, j, &n); - } - cpx_mtx_free(stateVector); - stateVector->ptr = ret.ptr; - stateVector->rows = ret.rows; - stateVector->cols = ret.cols; + uint32_t retLen = (uint32_t)pow(2, qubitCount); + cpx_mtx_t ret; + cpx_mtx_init(&ret, 1, retLen); + cpx_t n; + for (uint32_t i = 0; i < retLen; i++) + { + uint8_t bitAVal = (i >> bitA) & 1; + uint8_t bitBVal = (i >> bitB) & 1; + uint8_t bitCVal = (i >> bitC) & 1; + uint8_t bitCNew = (bitAVal && bitBVal) ? !bitCVal : bitCVal; + uint32_t j = (i & ~(1 << bitC)) | (bitCNew << bitC); + cpx_mtx_get(stateVector, 0, i, &n); + cpx_mtx_set(&ret, 0, j, &n); + } + cpx_mtx_free(stateVector); + stateVector->ptr = ret.ptr; + stateVector->rows = ret.rows; + stateVector->cols = ret.cols; } double* qansel_unitary(double theta, double phi, double lambda) { - cpx_mtx_t m; - cpx_t a, b, c, d; - a.real = cos(theta/2.0); - a.imaginary = 0; - b.real = -cos(lambda) * sin(theta/2.0); - b.imaginary = sin(lambda) * sin(theta/2.0); - c.real = cos(phi) * sin(theta/2.0); - c.imaginary = sin(phi) * sin(theta/2.0); - d.real = cos(phi + lambda) * cos(theta/2.0); - d.imaginary = sin(phi + lambda) * cos(theta/2.0); - cpx_mtx_init(&m, 2, 2); - cpx_mtx_set(&m, 0, 0, &a); - cpx_mtx_set(&m, 0, 1, &b); - cpx_mtx_set(&m, 1, 0, &c); - cpx_mtx_set(&m, 1, 1, &d); - return m.ptr; + cpx_mtx_t m; + cpx_t a, b, c, d; + a.real = cos(theta/2.0); + a.imaginary = 0; + b.real = -cos(lambda) * sin(theta/2.0); + b.imaginary = sin(lambda) * sin(theta/2.0); + c.real = cos(phi) * sin(theta/2.0); + c.imaginary = sin(phi) * sin(theta/2.0); + d.real = cos(phi + lambda) * cos(theta/2.0); + d.imaginary = sin(phi + lambda) * cos(theta/2.0); + cpx_mtx_init(&m, 2, 2); + cpx_mtx_set(&m, 0, 0, &a); + cpx_mtx_set(&m, 0, 1, &b); + cpx_mtx_set(&m, 1, 0, &c); + cpx_mtx_set(&m, 1, 1, &d); + return m.ptr; } void qansel_instruction(cpx_mtx_t* stateVector, uint8_t qubitCount, QInstr* instr) { - cpx_mtx_t tmp; - cpx_mtx_t gate; - gate.rows = 2; - gate.cols = 2; - double* gate_ptr; - switch (instr->n[0]) - { - case 'h': gate_ptr = Hadamard; break; - case 'x': gate_ptr = PauliX; break; - case 'y': gate_ptr = PauliY; break; - case 'z': gate_ptr = PauliZ; break; - case 's': gate_ptr = PhaseS; break; - case 't': gate_ptr = PhaseT; break; - case 'u': - gate_ptr = qansel_unitary(instr->arg0, instr->arg1, instr->arg2); - break; - default: gate_ptr = Identity; break; - } + cpx_mtx_t tmp; + cpx_mtx_t gate; + gate.rows = 2; + gate.cols = 2; + double* gate_ptr; + switch (instr->n[0]) + { + case 'h': gate_ptr = Hadamard; break; + case 'x': gate_ptr = PauliX; break; + case 'y': gate_ptr = PauliY; break; + case 'z': gate_ptr = PauliZ; break; + case 's': gate_ptr = PhaseS; break; + case 't': gate_ptr = PhaseT; break; + case 'u': + gate_ptr = qansel_unitary(instr->arg0, instr->arg1, instr->arg2); + break; + default: gate_ptr = Identity; break; + } - cpx_t n; - cpx_mtx_t filter; - cpx_mtx_init(&filter, 2, 2); - uint8_t qubit = qubitCount - (instr->q0) - 1; - if (qubit == 0) - { - memcpy(filter.ptr, gate_ptr, 16 * sizeof(double)); - } - else - { - memcpy(filter.ptr, Identity, 16 * sizeof(double)); - } + cpx_t n; + cpx_mtx_t filter; + cpx_mtx_init(&filter, 2, 2); + uint8_t qubit = qubitCount - (instr->q0) - 1; + if (qubit == 0) + { + memcpy(filter.ptr, gate_ptr, 16 * sizeof(double)); + } + else + { + memcpy(filter.ptr, Identity, 16 * sizeof(double)); + } - for (uint8_t i = 1; i < qubitCount; i++) - { - if (qubit == i) - { - gate.ptr = gate_ptr; - } - else - { - gate.ptr = Identity; - } + for (uint8_t i = 1; i < qubitCount; i++) + { + if (qubit == i) + { + gate.ptr = gate_ptr; + } + else + { + gate.ptr = Identity; + } - tmp.rows = filter.rows * gate.rows; - tmp.cols = filter.cols * gate.cols; - tmp.ptr = malloc((tmp.rows * 2) * (tmp.cols * 2) * sizeof(double)); - cpx_ncpx_knk_mt - ( - tmp.ptr, tmp.rows, tmp.cols, - filter.ptr, filter.rows, filter.cols, - gate.ptr, gate.rows, gate.cols - ); + tmp.rows = filter.rows * gate.rows; + tmp.cols = filter.cols * gate.cols; + tmp.ptr = malloc((tmp.rows * 2) * (tmp.cols * 2) * sizeof(double)); + cpx_ncpx_knk_mt + ( + tmp.ptr, tmp.rows, tmp.cols, + filter.ptr, filter.rows, filter.cols, + gate.ptr, gate.rows, gate.cols + ); - free(filter.ptr); - filter.ptr = tmp.ptr; - filter.rows = tmp.rows; - filter.cols = tmp.cols; - } + free(filter.ptr); + filter.ptr = tmp.ptr; + filter.rows = tmp.rows; + filter.cols = tmp.cols; + } - cpx_mtx_init(&tmp, stateVector->rows, stateVector->cols); - cpx_ncpx_mmul_mt - ( - tmp.ptr, stateVector->ptr, filter.ptr, - stateVector->rows * 2, filter.cols * 2, stateVector->cols * 2 - ); - free(stateVector->ptr); - stateVector->ptr = tmp.ptr; - free(filter.ptr); - if (instr->n[0] == 'u') free(gate_ptr); + cpx_mtx_init(&tmp, stateVector->rows, stateVector->cols); + cpx_ncpx_mmul_mt + ( + tmp.ptr, stateVector->ptr, filter.ptr, + stateVector->rows * 2, filter.cols * 2, stateVector->cols * 2 + ); + free(stateVector->ptr); + stateVector->ptr = tmp.ptr; + free(filter.ptr); + if (instr->n[0] == 'u') free(gate_ptr); } uint8_t qansel_measure(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t qubit) { - uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); - cpx_t n; - double prob0 = 0; - for (uint32_t i = 0; i < qubitCountPow2; i++) - { - uint8_t bit = (i >> qubit) & 1; - cpx_mtx_get(stateVector, 0, i, &n); - if (bit == 0) prob0 += cpx_magsqr(&n); - } + uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); + cpx_t n; + double prob0 = 0; + for (uint32_t i = 0; i < qubitCountPow2; i++) + { + uint8_t bit = (i >> qubit) & 1; + cpx_mtx_get(stateVector, 0, i, &n); + if (bit == 0) prob0 += cpx_magsqr(&n); + } - double r = qansel_rand(); - uint8_t newBit = r < prob0 ? 0 : 1; - double probTot = 0; - for (uint32_t i = 0; i < qubitCountPow2; i++) - { - uint8_t bit = (i >> qubit) & 1; - cpx_mtx_get(stateVector, 0, i, &n); - if (bit != newBit) - { - n.real = 0; - n.imaginary = 0; - } - else - { - probTot += cpx_magsqr(&n); - } - cpx_mtx_set(stateVector, 0, i, &n); - } - - double multiplier = sqrt(1 / probTot); - for (uint32_t i = 0; i < qubitCountPow2; i++) - { - uint8_t bit = (i >> qubit) & 1; - cpx_mtx_get(stateVector, 0, i, &n); - if (bit == newBit) - { - n.real *= multiplier; - n.imaginary *= multiplier; - } - cpx_mtx_set(stateVector, 0, i, &n); - } + double r = qansel_rand(); + uint8_t newBit = r < prob0 ? 0 : 1; + double probTot = 0; + for (uint32_t i = 0; i < qubitCountPow2; i++) + { + uint8_t bit = (i >> qubit) & 1; + cpx_mtx_get(stateVector, 0, i, &n); + if (bit != newBit) + { + n.real = 0; + n.imaginary = 0; + } + else + { + probTot += cpx_magsqr(&n); + } + cpx_mtx_set(stateVector, 0, i, &n); + } + + double multiplier = sqrt(1 / probTot); + for (uint32_t i = 0; i < qubitCountPow2; i++) + { + uint8_t bit = (i >> qubit) & 1; + cpx_mtx_get(stateVector, 0, i, &n); + if (bit == newBit) + { + n.real *= multiplier; + n.imaginary *= multiplier; + } + cpx_mtx_set(stateVector, 0, i, &n); + } - return newBit; + return newBit; } void qansel_run(uint8_t qubitCount, uint8_t bitCount, QInstr* instr, uint32_t instrLen, uint8_t gfx) { - uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); + uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); - uint8_t bitVector[bitCount]; - cpx_mtx_t stateVector; - cpx_mtx_init(&stateVector, 1, qubitCountPow2); - cpx_mtx_set2(&stateVector, 0, 0, 1, 0); - if (gfx) display(&stateVector, qubitCount); - uint8_t flags; + uint8_t bitVector[bitCount]; + cpx_mtx_t stateVector; + cpx_mtx_init(&stateVector, 1, qubitCountPow2); + cpx_mtx_set2(&stateVector, 0, 0, 1, 0); + if (gfx) display(&stateVector, qubitCount); + uint8_t flags; - for (uint8_t i = 0; i < bitCount; i++) bitVector[i] = 0; - for (uint32_t i = 0; i < instrLen; i++) - { - if (strcmp(instr[i].n, "measure") == 0) - { - bitVector[instr[i].q1] = qansel_measure(&stateVector, qubitCount, instr[i].q0); - } - else if (strcmp(instr[i].n, "cswap") == 0) - { - qansel_fredkin(&stateVector, qubitCount, instr[i].q0, instr[i].q1, instr[i].q2); - } - else if (strcmp(instr[i].n, "ccx") == 0) - { - qansel_toffoli(&stateVector, qubitCount, instr[i].q0, instr[i].q1, instr[i].q2); - } - else if (strcmp(instr[i].n, "cx") == 0) - { - qansel_cnot(&stateVector, qubitCount, instr[i].q0, instr[i].q1); - } - else if (strcmp(instr[i].n, "swap") == 0) - { - qansel_swap(&stateVector, qubitCount, instr[i].q0, instr[i].q1); - } - else if (strcmp(instr[i].n, "if_all") == 0) - { - uint8_t val = 0; - for (int32_t j = bitCount - 1; j >= 0; j--) - { - val = (val << 1) | bitVector[j]; - } - if (val != instr[i].q0) i++; - } - else if (strcmp(instr[i].n, "if") == 0) - { - if (bitVector[instr[i].q0] != instr[i].q1) i++; - } - else if (strcmp(instr[i].n, "printq_all") == 0) - { - printf("[ "); cpx_mtx_print(&stateVector); printf(" ]\n"); - } - else if (strcmp(instr[i].n, "printc_all") == 0) - { - for (int32_t j = bitCount - 1; j >= 0; j--) - { - putchar('0' + bitVector[j]); - } - putchar('\n'); - } - else if (strcmp(instr[i].n, "printc") == 0) - { - putchar('0' + bitVector[instr[i].q0]); - putchar('\n'); - } - else if (strcmp(instr[i].n, "printq") == 0 || strcmp(instr[i].n, "density") == 0) - { - cpx_mtx_t tmp; - cpx_mtx_init(&tmp, 1, 2); - for (uint32_t j = 0; j < qubitCountPow2; j++) - { - if ((j >> instr[i].q0) & 1) - { - cpx_t a, b; - cpx_mtx_get(&tmp, 0, 1, &a); - cpx_mtx_get(&stateVector, 0, j, &b); - a.real += b.real; - a.imaginary += b.imaginary; - cpx_mtx_set(&tmp, 0, 1, &a); - } - else - { - cpx_t a, b; - cpx_mtx_get(&tmp, 0, 0, &a); - cpx_mtx_get(&stateVector, 0, j, &b); - a.real += b.real; - a.imaginary += b.imaginary; - cpx_mtx_set(&tmp, 0, 0, &a); - } - } - double multiplier = 0; - cpx_t n; - cpx_mtx_get(&tmp, 0, 0, &n); - multiplier += cpx_magsqr(&n); - cpx_mtx_get(&tmp, 0, 1, &n); - multiplier += cpx_magsqr(&n); - multiplier = sqrt(1 / multiplier); - n.real *= multiplier; - n.imaginary *= multiplier; - cpx_mtx_set(&tmp, 0, 1, &n); - cpx_mtx_get(&tmp, 0, 0, &n); - n.real *= multiplier; - n.imaginary *= multiplier; - cpx_mtx_set(&tmp, 0, 0, &n); + for (uint8_t i = 0; i < bitCount; i++) bitVector[i] = 0; + for (uint32_t i = 0; i < instrLen; i++) + { + if (strcmp(instr[i].n, "measure") == 0) + { + bitVector[instr[i].q1] = qansel_measure(&stateVector, qubitCount, instr[i].q0); + } + else if (strcmp(instr[i].n, "cswap") == 0) + { + qansel_fredkin(&stateVector, qubitCount, instr[i].q0, instr[i].q1, instr[i].q2); + } + else if (strcmp(instr[i].n, "ccx") == 0) + { + qansel_toffoli(&stateVector, qubitCount, instr[i].q0, instr[i].q1, instr[i].q2); + } + else if (strcmp(instr[i].n, "cx") == 0) + { + qansel_cnot(&stateVector, qubitCount, instr[i].q0, instr[i].q1); + } + else if (strcmp(instr[i].n, "swap") == 0) + { + qansel_swap(&stateVector, qubitCount, instr[i].q0, instr[i].q1); + } + else if (strcmp(instr[i].n, "if_all") == 0) + { + uint8_t val = 0; + for (int32_t j = bitCount - 1; j >= 0; j--) + { + val = (val << 1) | bitVector[j]; + } + if (val != instr[i].q0) i++; + } + else if (strcmp(instr[i].n, "if") == 0) + { + if (bitVector[instr[i].q0] != instr[i].q1) i++; + } + else if (strcmp(instr[i].n, "printq_all") == 0) + { + printf("[ "); cpx_mtx_print(&stateVector); printf(" ]\n"); + } + else if (strcmp(instr[i].n, "printc_all") == 0) + { + for (int32_t j = bitCount - 1; j >= 0; j--) + { + putchar('0' + bitVector[j]); + } + putchar('\n'); + } + else if (strcmp(instr[i].n, "printc") == 0) + { + putchar('0' + bitVector[instr[i].q0]); + putchar('\n'); + } + else if (strcmp(instr[i].n, "printq") == 0 || strcmp(instr[i].n, "density") == 0) + { + cpx_mtx_t tmp; + cpx_mtx_init(&tmp, 1, 2); + for (uint32_t j = 0; j < qubitCountPow2; j++) + { + if ((j >> instr[i].q0) & 1) + { + cpx_t a, b; + cpx_mtx_get(&tmp, 0, 1, &a); + cpx_mtx_get(&stateVector, 0, j, &b); + a.real += b.real; + a.imaginary += b.imaginary; + cpx_mtx_set(&tmp, 0, 1, &a); + } + else + { + cpx_t a, b; + cpx_mtx_get(&tmp, 0, 0, &a); + cpx_mtx_get(&stateVector, 0, j, &b); + a.real += b.real; + a.imaginary += b.imaginary; + cpx_mtx_set(&tmp, 0, 0, &a); + } + } + double multiplier = 0; + cpx_t n; + cpx_mtx_get(&tmp, 0, 0, &n); + multiplier += cpx_magsqr(&n); + cpx_mtx_get(&tmp, 0, 1, &n); + multiplier += cpx_magsqr(&n); + multiplier = sqrt(1 / multiplier); + n.real *= multiplier; + n.imaginary *= multiplier; + cpx_mtx_set(&tmp, 0, 1, &n); + cpx_mtx_get(&tmp, 0, 0, &n); + n.real *= multiplier; + n.imaginary *= multiplier; + cpx_mtx_set(&tmp, 0, 0, &n); - if (strcmp(instr[i].n, "density") == 0) - { - cpx_t a, b, c, d, x, y, z, w; - cpx_mtx_get(&tmp, 0, 0, &a); - cpx_mtx_get(&tmp, 0, 1, &b); - cpx_mtx_get(&tmp, 0, 0, &c); - cpx_mtx_get(&tmp, 0, 1, &d); - c.imaginary *= -1; - d.imaginary *= -1; - cpx_mul(&x, &a, &c); - cpx_mul(&y, &a, &d); - cpx_mul(&z, &b, &c); - cpx_mul(&w, &b, &d); - char* sx = cpx_str(&x); - char* sy = cpx_str(&y); - char* sz = cpx_str(&z); - char* sw = cpx_str(&w); - printf("[ %s, %s ]\n", sx, sy); - printf("[ %s, %s ]\n", sz, sw); - free(sx); - free(sy); - free(sz); - free(sw); - } - else - { - printf("[ "); cpx_mtx_print(&tmp); printf(" ]\n"); - } - cpx_mtx_free(&tmp); - } - else if (strcmp(instr[i].n, "sample_all") == 0) - { - for (uint32_t j = 0; j < qubitCountPow2; j++) - { - uint32_t tmp = j; - for (uint8_t k = 0; k < qubitCount; k++) - { - putchar('0' + (tmp >> (qubitCount - 1) & 1)); - tmp <<= 1; - } - cpx_t n; - cpx_mtx_get(&stateVector, 0, j, &n); - printf(": %.00f%%\n", cpx_magsqr(&n) * 100); - } - } - else if (strcmp(instr[i].n, "sample") == 0) - { - double prob = 0; - for (uint32_t j = 0; j < qubitCountPow2; j++) - { - cpx_t n; - cpx_mtx_get(&stateVector, 0, j, &n); - if ((j >> instr[i].q0) & 1) - { - prob += cpx_magsqr(&n); - } - } - printf("%.00f%%\n", prob * 100.0); - } - else if (strcmp(instr[i].n, "reset_all") == 0) - { - cpx_mtx_set2(&stateVector, 0, 0, 1, 0); - for (uint32_t j = 1; j < qubitCountPow2; j++) - { - cpx_mtx_set2(&stateVector, 0, j, 0, 0); - } - for (uint8_t j = 0; j < bitCount; j++) - { - bitVector[j] = 0; - } - } - else if (strcmp(instr[i].n, "resetq") == 0) - { - uint8_t bit = qansel_measure(&stateVector, qubitCount, instr[i].q0); - if (bit) - { - instr[i].n[0] = 'x'; - instr[i].n[1] = 0; - qansel_instruction(&stateVector, qubitCount, instr + i); - } - } - else if (strcmp(instr[i].n, "resetc") == 0) - { - bitVector[instr[i].q0] = 0; - } - else - { - qansel_instruction(&stateVector, qubitCount, instr + i); - } + if (strcmp(instr[i].n, "density") == 0) + { + cpx_t a, b, c, d, x, y, z, w; + cpx_mtx_get(&tmp, 0, 0, &a); + cpx_mtx_get(&tmp, 0, 1, &b); + cpx_mtx_get(&tmp, 0, 0, &c); + cpx_mtx_get(&tmp, 0, 1, &d); + c.imaginary *= -1; + d.imaginary *= -1; + cpx_mul(&x, &a, &c); + cpx_mul(&y, &a, &d); + cpx_mul(&z, &b, &c); + cpx_mul(&w, &b, &d); + char* sx = cpx_str(&x); + char* sy = cpx_str(&y); + char* sz = cpx_str(&z); + char* sw = cpx_str(&w); + printf("[ %s, %s ]\n", sx, sy); + printf("[ %s, %s ]\n", sz, sw); + free(sx); + free(sy); + free(sz); + free(sw); + } + else + { + printf("[ "); cpx_mtx_print(&tmp); printf(" ]\n"); + } + cpx_mtx_free(&tmp); + } + else if (strcmp(instr[i].n, "sample_all") == 0) + { + for (uint32_t j = 0; j < qubitCountPow2; j++) + { + uint32_t tmp = j; + for (uint8_t k = 0; k < qubitCount; k++) + { + putchar('0' + (tmp >> (qubitCount - 1) & 1)); + tmp <<= 1; + } + cpx_t n; + cpx_mtx_get(&stateVector, 0, j, &n); + printf(": %.00f%%\n", cpx_magsqr(&n) * 100); + } + } + else if (strcmp(instr[i].n, "sample") == 0) + { + double prob = 0; + for (uint32_t j = 0; j < qubitCountPow2; j++) + { + cpx_t n; + cpx_mtx_get(&stateVector, 0, j, &n); + if ((j >> instr[i].q0) & 1) + { + prob += cpx_magsqr(&n); + } + } + printf("%.00f%%\n", prob * 100.0); + } + else if (strcmp(instr[i].n, "reset_all") == 0) + { + cpx_mtx_set2(&stateVector, 0, 0, 1, 0); + for (uint32_t j = 1; j < qubitCountPow2; j++) + { + cpx_mtx_set2(&stateVector, 0, j, 0, 0); + } + for (uint8_t j = 0; j < bitCount; j++) + { + bitVector[j] = 0; + } + } + else if (strcmp(instr[i].n, "resetq") == 0) + { + uint8_t bit = qansel_measure(&stateVector, qubitCount, instr[i].q0); + if (bit) + { + instr[i].n[0] = 'x'; + instr[i].n[1] = 0; + qansel_instruction(&stateVector, qubitCount, instr + i); + } + } + else if (strcmp(instr[i].n, "resetc") == 0) + { + bitVector[instr[i].q0] = 0; + } + else + { + qansel_instruction(&stateVector, qubitCount, instr + i); + } - if (gfx) display(&stateVector, qubitCount); - } - display(NULL, -1); + if (gfx) display(&stateVector, qubitCount); + } + display(NULL, -1); - cpx_mtx_free(&stateVector); + cpx_mtx_free(&stateVector); } void main(int argc, char** argv) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - HIDDEN_VARIABLE = (double)((uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec); - char** lines = malloc(0); - uint32_t* lineIDs = malloc(0); - char* text = malloc(0); - uint32_t textLen = 0; - uint32_t linesLen = 0; - int c; - int pc = -1; - uint8_t comment = 0; - uint8_t commentM = 0; - uint32_t lineID = 1; - uint8_t skipSpaces = 1; - uint8_t inGate = 0; - while ( (c = getchar()) != EOF ) - { - if (c == '/' && commentM == 0 && comment == 0) - { - commentM = 1; - } - else if (c == '/' && commentM == 1 && comment == 0) - { - comment = 1; - commentM = 0; - } - else if (c == '\n') - { - comment = 0; - commentM = 0; - lineID += 1; - } - else if (comment || (c == ' ' && skipSpaces)) {} - else if (c != '\n' && c != '\t' && c != ';' && (c != ')' || inGate)) - { - if (commentM == 1) - { - text = realloc(text, textLen + 1); - text[textLen++] = '/'; - commentM = 0; - } - skipSpaces = 0; - if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; - if (c == 'u') inGate = 1; - if (c == 'r') inGate = 1; - text = realloc(text, textLen + 1); - text[textLen++] = c; - pc = c; - } - else if (c == ';' || (c == ')' && !inGate)) - { - inGate = 0; - skipSpaces = 1; - if (c == ')') - { - text = realloc(text, textLen + 1); - text[textLen++] = ')'; - } - text = realloc(text, textLen + 1); - text[textLen++] = 0; - lineIDs = realloc(lineIDs, (linesLen + 1) * sizeof(uint32_t)); - lineIDs[linesLen] = lineID; - lines = realloc(lines, (linesLen + 1) * sizeof(char*)); - lines[linesLen] = malloc(strlen(text) + 1); - strcpy(lines[linesLen++], text); - text = realloc(text, 0); - textLen = 0; - pc = ';'; - } - } - text = realloc(text, textLen + 1); - text[textLen++] = 0; - if (strlen(text) > 0) - { - printf(">%s<\n", text); - free(text); - fprintf(stderr, "QAnsel: Invalid trailing text"); - exit(1); - } - free(text); - - uint8_t qubitCount = 0xFF; - uint8_t bitCount = 0xFF; - QInstr* instr = malloc(0); - uint32_t instrLen = 0; - uint8_t doDisplay = 0; - uint8_t errFound = 0; - for (uint32_t i = 0; i < linesLen; i++) - { - lineID = i; + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + HIDDEN_VARIABLE = (double)((uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec); + char** lines = malloc(0); + uint32_t* lineIDs = malloc(0); + char* text = malloc(0); + uint32_t textLen = 0; + uint32_t linesLen = 0; + int c; + int pc = -1; + uint8_t comment = 0; + uint8_t commentM = 0; + uint32_t lineID = 1; + uint8_t skipSpaces = 1; + uint8_t inGate = 0; + while ( (c = getchar()) != EOF ) + { + if (c == '/' && commentM == 0 && comment == 0) + { + commentM = 1; + } + else if (c == '/' && commentM == 1 && comment == 0) + { + comment = 1; + commentM = 0; + } + else if (c == '\n') + { + comment = 0; + commentM = 0; + lineID += 1; + } + else if (comment || (c == ' ' && skipSpaces)) {} + else if (c != '\n' && c != '\t' && c != ';' && (c != ')' || inGate)) + { + if (commentM == 1) + { + text = realloc(text, textLen + 1); + text[textLen++] = '/'; + commentM = 0; + } + skipSpaces = 0; + if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; + if (c == 'u') inGate = 1; + if (c == 'r') inGate = 1; + text = realloc(text, textLen + 1); + text[textLen++] = c; + pc = c; + } + else if (c == ';' || (c == ')' && !inGate)) + { + inGate = 0; + skipSpaces = 1; + if (c == ')') + { + text = realloc(text, textLen + 1); + text[textLen++] = ')'; + } + text = realloc(text, textLen + 1); + text[textLen++] = 0; + lineIDs = realloc(lineIDs, (linesLen + 1) * sizeof(uint32_t)); + lineIDs[linesLen] = lineID; + lines = realloc(lines, (linesLen + 1) * sizeof(char*)); + lines[linesLen] = malloc(strlen(text) + 1); + strcpy(lines[linesLen++], text); + text = realloc(text, 0); + textLen = 0; + pc = ';'; + } + } + text = realloc(text, textLen + 1); + text[textLen++] = 0; + if (strlen(text) > 0) + { + printf(">%s<\n", text); + free(text); + fprintf(stderr, "QAnsel: Invalid trailing text"); + exit(1); + } + free(text); + + uint8_t qubitCount = 0xFF; + uint8_t bitCount = 0xFF; + QInstr* instr = malloc(0); + uint32_t instrLen = 0; + uint8_t doDisplay = 0; + uint8_t errFound = 0; + for (uint32_t i = 0; i < linesLen; i++) + { + lineID = i; - char g; - int q0, q1, q2; - float a0, a1, a2; + char g; + int q0, q1, q2; + float a0, a1, a2; - if (sscanf(lines[i], "qreg q[%i]", &q0) == 1) - { - if (qubitCount == 0xFF) - { - qubitCount = q0; - if (qubitCount < 1 || qubitCount > QUBITS_MAX) - { - fprintf(stderr, "QAnsel: Invalid count"); - errFound = 1; - break; - } - } - else - { - fprintf(stderr, "QAnsel: Repeated initialization"); - errFound = 1; - break; - } - } - else if (sscanf(lines[i], "creg c[%i]", &q0) == 1) - { - if (bitCount == 0xFF) - { - bitCount = q0; - if (bitCount < 1 || bitCount > QUBITS_MAX) - { - fprintf(stderr, "QAnsel: Invalid count"); - errFound = 1; - break; - } - } - else - { - fprintf(stderr, "QAnsel: Repeated initialization"); - errFound = 1; - break; - } - } - else if (sscanf(lines[i], "u(%f,%f,%f) q[%i]", &a0, &a1, &a2, &q0) == 4) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 < 0 || q0 >= qubitCount) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - instr[instrLen].n[0] = 'u'; - instr[instrLen].n[1] = 0; - instr[instrLen].q0 = q0; - instr[instrLen].arg0 = a0; - instr[instrLen].arg1 = a1; - instr[instrLen++].arg2 = a2; - } - else if - ( - memcmp("rx(", lines[i], 3) == 0 - || memcmp("ry(", lines[i], 3) == 0 - || memcmp("rz(", lines[i], 3) == 0 - ) - { - double angle; - char ty; - if (sscanf(lines[i], "r%c(%f/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) - { - angle = a0 / a1; - } - else if (sscanf(lines[i], "r%c(%f/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) - { - angle = a0 / (a1 * M_PI); - } - else if (sscanf(lines[i], "r%c(%f/pi) q[%i]", &ty, &a0, &q0) == 3) - { - angle = a0 / M_PI; - } - else if (sscanf(lines[i], "r%c(%f/-pi) q[%i]", &ty, &a0, &q0) == 3) - { - angle = a0 / -M_PI; - } - else if (sscanf(lines[i], "r%c(%fpi/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) - { - angle = (a0 * M_PI) / a1; - } - else if (sscanf(lines[i], "r%c(pi/%f) q[%i]", &ty, &a0, &q0) == 3) - { - angle = M_PI / a0; - } - else if (sscanf(lines[i], "r%c(-pi/%f) q[%i]", &ty, &a0, &q0) == 3) - { - angle = -M_PI / a0; - } - else if (sscanf(lines[i], "r%c(%fpi/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) - { - angle = (a0 * M_PI) / (a1 * M_PI); - } - else if (sscanf(lines[i], "r%c(pi/pi) q[%i]", &ty, &q0) == 2) - { - angle = 1; - } - else if (sscanf(lines[i], "r%c(-pi/pi) q[%i]", &ty, &q0) == 2) - { - angle = -1; - } - else if (sscanf(lines[i], "r%c(pi/-pi) q[%i]", &ty, &q0) == 2) - { - angle = -1; - } - else if (sscanf(lines[i], "r%c(-pi/-pi) q[%i]", &ty, &q0) == 2) - { - angle = 1; - } - else if (sscanf(lines[i], "r%c(%fpi) q[%i]", &ty, &a0, &q0) == 3) - { - angle = a0 * M_PI; - } - else if (sscanf(lines[i], "r%c(pi) q[%i]", &ty, &q0) == 2) - { - angle = M_PI; - } - else if (sscanf(lines[i], "r%c(-pi) q[%i]", &ty, &q0) == 2) - { - angle = -M_PI; - } - else if (sscanf(lines[i], "r%c(%f) q[%i]", &ty, &a0, &q0) == 3) - { - angle = a0; - } - else - { - fprintf(stderr, "QAnsel: Syntax error"); - errFound = 1; - break; - } - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 < 0 || q0 >= qubitCount) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } + if (sscanf(lines[i], "qreg q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF) + { + qubitCount = q0; + if (qubitCount < 1 || qubitCount > QUBITS_MAX) + { + fprintf(stderr, "QAnsel: Invalid count"); + errFound = 1; + break; + } + } + else + { + fprintf(stderr, "QAnsel: Repeated initialization"); + errFound = 1; + break; + } + } + else if (sscanf(lines[i], "creg c[%i]", &q0) == 1) + { + if (bitCount == 0xFF) + { + bitCount = q0; + if (bitCount < 1 || bitCount > QUBITS_MAX) + { + fprintf(stderr, "QAnsel: Invalid count"); + errFound = 1; + break; + } + } + else + { + fprintf(stderr, "QAnsel: Repeated initialization"); + errFound = 1; + break; + } + } + else if (sscanf(lines[i], "u(%f,%f,%f) q[%i]", &a0, &a1, &a2, &q0) == 4) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q0 >= qubitCount) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + instr[instrLen].n[0] = 'u'; + instr[instrLen].n[1] = 0; + instr[instrLen].q0 = q0; + instr[instrLen].arg0 = a0; + instr[instrLen].arg1 = a1; + instr[instrLen++].arg2 = a2; + } + else if + ( + memcmp("rx(", lines[i], 3) == 0 + || memcmp("ry(", lines[i], 3) == 0 + || memcmp("rz(", lines[i], 3) == 0 + ) + { + double angle; + char ty; + if (sscanf(lines[i], "r%c(%f/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = a0 / a1; + } + else if (sscanf(lines[i], "r%c(%f/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = a0 / (a1 * M_PI); + } + else if (sscanf(lines[i], "r%c(%f/pi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 / M_PI; + } + else if (sscanf(lines[i], "r%c(%f/-pi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 / -M_PI; + } + else if (sscanf(lines[i], "r%c(%fpi/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = (a0 * M_PI) / a1; + } + else if (sscanf(lines[i], "r%c(pi/%f) q[%i]", &ty, &a0, &q0) == 3) + { + angle = M_PI / a0; + } + else if (sscanf(lines[i], "r%c(-pi/%f) q[%i]", &ty, &a0, &q0) == 3) + { + angle = -M_PI / a0; + } + else if (sscanf(lines[i], "r%c(%fpi/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = (a0 * M_PI) / (a1 * M_PI); + } + else if (sscanf(lines[i], "r%c(pi/pi) q[%i]", &ty, &q0) == 2) + { + angle = 1; + } + else if (sscanf(lines[i], "r%c(-pi/pi) q[%i]", &ty, &q0) == 2) + { + angle = -1; + } + else if (sscanf(lines[i], "r%c(pi/-pi) q[%i]", &ty, &q0) == 2) + { + angle = -1; + } + else if (sscanf(lines[i], "r%c(-pi/-pi) q[%i]", &ty, &q0) == 2) + { + angle = 1; + } + else if (sscanf(lines[i], "r%c(%fpi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 * M_PI; + } + else if (sscanf(lines[i], "r%c(pi) q[%i]", &ty, &q0) == 2) + { + angle = M_PI; + } + else if (sscanf(lines[i], "r%c(-pi) q[%i]", &ty, &q0) == 2) + { + angle = -M_PI; + } + else if (sscanf(lines[i], "r%c(%f) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0; + } + else + { + fprintf(stderr, "QAnsel: Syntax error"); + errFound = 1; + break; + } + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q0 >= qubitCount) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - instr[instrLen].n[0] = 'u'; - instr[instrLen].n[1] = 0; - instr[instrLen].q0 = q0; - switch (ty) - { - case 'x': - instr[instrLen].arg0 = M_PI / 2; - instr[instrLen].arg1 = -M_PI / 2; - instr[instrLen].arg2 = angle - (M_PI / 2); - break; - case 'y': - instr[instrLen].arg0 = angle; - instr[instrLen].arg1 = 0; - instr[instrLen].arg2 = 0; - break; - case 'z': - instr[instrLen].arg0 = 0; - instr[instrLen].arg1 = 0; - instr[instrLen].arg2 = angle; - break; - } - instrLen++; - } - else if (sscanf(lines[i], "density q[%i]", &q0) == 1) - { - g = lines[i][0]; - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 < 0 || q0 >= qubitCount) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "density"); - instr[instrLen++].q0 = (uint8_t)q0; - } - else if - ( - sscanf(lines[i], "h q[%i]", &q0) == 1 - || sscanf(lines[i], "x q[%i]", &q0) == 1 - || sscanf(lines[i], "y q[%i]", &q0) == 1 - || sscanf(lines[i], "z q[%i]", &q0) == 1 - || sscanf(lines[i], "t q[%i]", &q0) == 1 - || sscanf(lines[i], "s q[%i]", &q0) == 1 - ) - { - g = lines[i][0]; - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 < 0 || q0 >= qubitCount) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - instr[instrLen].n[0] = g; - instr[instrLen].n[1] = 0; - instr[instrLen++].q0 = (uint8_t)q0; - } - else if (sscanf(lines[i], "cx q[%i], q[%i]", &q0, &q1) == 2) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q1 >= qubitCount | q0 < 0 || q1 < 0 || q0 == q1) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "cx"); - instr[instrLen].q0 = q0; - instr[instrLen++].q1 = q1; - } - else if (sscanf(lines[i], "swap q[%i], q[%i]", &q0, &q1) == 2) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q1 >= qubitCount | q0 < 0 || q1 < 0 || q0 == q1) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "swap"); - instr[instrLen].q0 = q0; - instr[instrLen++].q1 = q1; - } - else if - ( - sscanf(lines[i], "cswap q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 - || sscanf(lines[i], "fredkin q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 - ) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (qubitCount < 3) - { - fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q1 >= qubitCount || q2 >= qubitCount || q0 < 0 || q1< 0 || q2 < 0 || q0 == q1 || q1 == q2 || q0 == q2) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "cswap"); - instr[instrLen].q0 = q0; - instr[instrLen].q1 = q1; - instr[instrLen++].q2 = q2; - } - else if - ( - sscanf(lines[i], "ccx q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 - || sscanf(lines[i], "toffoli q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 - ) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction before initialization"); - errFound = 1; - break; - } - if (qubitCount < 3) - { - fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q1 >= qubitCount || q2 >= qubitCount || q0 < 0 || q1< 0 || q2 < 0 || q0 == q1 || q1 == q2 || q0 == q2) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "ccx"); - instr[instrLen].q0 = q0; - instr[instrLen].q1 = q1; - instr[instrLen++].q2 = q2; - } - else if (sscanf(lines[i], "measure q[%i] -> c[%i]", &q0, &q1) == 2) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Measure instruction used before bit initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q1 >= bitCount || q0 < 0 || q1 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "measure"); - instr[instrLen].q0 = q0; - instr[instrLen++].q1 = q1; - } - else if (sscanf(lines[i], "if(c==%i)", &q0) == 1) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: If instruction used before bit initialization"); - errFound = 1; - break; - } - if (q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid comparison"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "if_all"); - instr[instrLen++].q0 = q0; - } - else if (sscanf(lines[i], "if(c[%i]==%i)", &q0, &q1) == 2) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: If instruction used before bit initialization"); - errFound = 1; - break; - } - if (q0 < 0 || q1 < 0 || q0 > bitCount) - { - fprintf(stderr, "QAnsel: Invalid comparison"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "if"); - instr[instrLen].q0 = q0; - instr[instrLen++].q1 = q1; - } - /*else if (strcmp(lines[i], "display") == 0) - { - if (doDisplay) - { - fprintf(stderr, "QAnsel: Display re-initialized"); - errFound = 1; - break; - } - doDisplay = 1; - }*/ - else if (strcmp(lines[i], "print q") == 0) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "printq_all"); - instrLen++; - } - else if (strcmp(lines[i], "print c") == 0) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Bit instruction used before initialization"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "printc_all"); - instrLen++; - } - else if (sscanf(lines[i], "print q[%i]", &q0) == 1) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "printq"); - instr[instrLen++].q0 = q0; - } - else if (sscanf(lines[i], "print c[%i]", &q0) == 1) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Bit instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= bitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "printc"); - instr[instrLen++].q0 = q0; - } - else if (strcmp(lines[i], "sample") == 0) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "sample_all"); - instrLen++; - } - else if (sscanf(lines[i], "sample q[%i]", &q0) == 1) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "sample"); - instr[instrLen++].q0 = q0; - } - else if (sscanf(lines[i], "reset q[%i]", &q0) == 1) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "resetq"); - instr[instrLen++].q0 = q0; - } - else if (sscanf(lines[i], "reset c[%i]", &q0) == 1) - { - if (bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Bit instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= bitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "resetc"); - instr[instrLen++].q0 = q0; - } - else if (strcmp(lines[i], "reset") == 0) - { - instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "reset_all"); - instrLen++; - } - else if (strcmp(lines[i], "barrier q") == 0) - { - if (qubitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); - errFound = 1; - break; - } - //do nothing as there are currently no - // optimizations that this instruction - // would prevent - } - else if (sscanf(lines[i], "barrier q[%i]", &q0) == 1) - { - if (qubitCount == 0xFF || bitCount == 0xFF) - { - fprintf(stderr, "QAnsel: Instruction used before initialization"); - errFound = 1; - break; - } - if (q0 >= qubitCount || q0 < 0) - { - fprintf(stderr, "QAnsel: Invalid index"); - errFound = 1; - break; - } - //do nothing as there are currently no - // optimizations that this instruction - // would prevent - } - else - { - fprintf(stderr, "QAnsel: Syntax error"); - errFound = 1; - break; - } - } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + instr[instrLen].n[0] = 'u'; + instr[instrLen].n[1] = 0; + instr[instrLen].q0 = q0; + switch (ty) + { + case 'x': + instr[instrLen].arg0 = M_PI / 2; + instr[instrLen].arg1 = -M_PI / 2; + instr[instrLen].arg2 = angle - (M_PI / 2); + break; + case 'y': + instr[instrLen].arg0 = angle; + instr[instrLen].arg1 = 0; + instr[instrLen].arg2 = 0; + break; + case 'z': + instr[instrLen].arg0 = 0; + instr[instrLen].arg1 = 0; + instr[instrLen].arg2 = angle; + break; + } + instrLen++; + } + else if (sscanf(lines[i], "density q[%i]", &q0) == 1) + { + g = lines[i][0]; + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q0 >= qubitCount) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "density"); + instr[instrLen++].q0 = (uint8_t)q0; + } + else if + ( + sscanf(lines[i], "h q[%i]", &q0) == 1 + || sscanf(lines[i], "x q[%i]", &q0) == 1 + || sscanf(lines[i], "y q[%i]", &q0) == 1 + || sscanf(lines[i], "z q[%i]", &q0) == 1 + || sscanf(lines[i], "t q[%i]", &q0) == 1 + || sscanf(lines[i], "s q[%i]", &q0) == 1 + ) + { + g = lines[i][0]; + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q0 >= qubitCount) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + instr[instrLen].n[0] = g; + instr[instrLen].n[1] = 0; + instr[instrLen++].q0 = (uint8_t)q0; + } + else if (sscanf(lines[i], "cx q[%i], q[%i]", &q0, &q1) == 2) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q1 >= qubitCount | q0 < 0 || q1 < 0 || q0 == q1) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "cx"); + instr[instrLen].q0 = q0; + instr[instrLen++].q1 = q1; + } + else if (sscanf(lines[i], "swap q[%i], q[%i]", &q0, &q1) == 2) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q1 >= qubitCount | q0 < 0 || q1 < 0 || q0 == q1) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "swap"); + instr[instrLen].q0 = q0; + instr[instrLen++].q1 = q1; + } + else if + ( + sscanf(lines[i], "cswap q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 + || sscanf(lines[i], "fredkin q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 + ) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (qubitCount < 3) + { + fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q1 >= qubitCount || q2 >= qubitCount || q0 < 0 || q1< 0 || q2 < 0 || q0 == q1 || q1 == q2 || q0 == q2) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "cswap"); + instr[instrLen].q0 = q0; + instr[instrLen].q1 = q1; + instr[instrLen++].q2 = q2; + } + else if + ( + sscanf(lines[i], "ccx q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 + || sscanf(lines[i], "toffoli q[%i], q[%i], q[%i]", &q0, &q1, &q2) == 3 + ) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (qubitCount < 3) + { + fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q1 >= qubitCount || q2 >= qubitCount || q0 < 0 || q1< 0 || q2 < 0 || q0 == q1 || q1 == q2 || q0 == q2) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "ccx"); + instr[instrLen].q0 = q0; + instr[instrLen].q1 = q1; + instr[instrLen++].q2 = q2; + } + else if (sscanf(lines[i], "measure q[%i] -> c[%i]", &q0, &q1) == 2) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Measure instruction used before bit initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q1 >= bitCount || q0 < 0 || q1 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "measure"); + instr[instrLen].q0 = q0; + instr[instrLen++].q1 = q1; + } + else if (sscanf(lines[i], "if(c==%i)", &q0) == 1) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: If instruction used before bit initialization"); + errFound = 1; + break; + } + if (q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid comparison"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "if_all"); + instr[instrLen++].q0 = q0; + } + else if (sscanf(lines[i], "if(c[%i]==%i)", &q0, &q1) == 2) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: If instruction used before bit initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q1 < 0 || q0 > bitCount) + { + fprintf(stderr, "QAnsel: Invalid comparison"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "if"); + instr[instrLen].q0 = q0; + instr[instrLen++].q1 = q1; + } + /*else if (strcmp(lines[i], "display") == 0) + { + if (doDisplay) + { + fprintf(stderr, "QAnsel: Display re-initialized"); + errFound = 1; + break; + } + doDisplay = 1; + }*/ + else if (strcmp(lines[i], "print q") == 0) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "printq_all"); + instrLen++; + } + else if (strcmp(lines[i], "print c") == 0) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "printc_all"); + instrLen++; + } + else if (sscanf(lines[i], "print q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "printq"); + instr[instrLen++].q0 = q0; + } + else if (sscanf(lines[i], "print c[%i]", &q0) == 1) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= bitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "printc"); + instr[instrLen++].q0 = q0; + } + else if (strcmp(lines[i], "sample") == 0) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "sample_all"); + instrLen++; + } + else if (sscanf(lines[i], "sample q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "sample"); + instr[instrLen++].q0 = q0; + } + else if (sscanf(lines[i], "reset q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "resetq"); + instr[instrLen++].q0 = q0; + } + else if (sscanf(lines[i], "reset c[%i]", &q0) == 1) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= bitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "resetc"); + instr[instrLen++].q0 = q0; + } + else if (strcmp(lines[i], "reset") == 0) + { + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "reset_all"); + instrLen++; + } + else if (strcmp(lines[i], "barrier q") == 0) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + //do nothing as there are currently no + // optimizations that this instruction + // would prevent + } + else if (sscanf(lines[i], "barrier q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF || bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + //do nothing as there are currently no + // optimizations that this instruction + // would prevent + } + else + { + fprintf(stderr, "QAnsel: Syntax error"); + errFound = 1; + break; + } + } - for (uint32_t i = 0; i < linesLen; i++) free(lines[i]); - free(lines); + for (uint32_t i = 0; i < linesLen; i++) free(lines[i]); + free(lines); - if (errFound) - { - printf(" on line %i.\n", lineIDs[lineID]); - free(lineIDs); - free(instr); - exit(1); - } + if (errFound) + { + printf(" on line %i.\n", lineIDs[lineID]); + free(lineIDs); + free(instr); + exit(1); + } - if (argc == 2) - { - if (strcmp(argv[1], "-d") == 0) - { - doDisplay = 1; - } - } - else if (argc == 3) - { - if (strcmp(argv[1], "-h") == 0) - { - HIDDEN_VARIABLE = atof(argv[2]); - } - } - else if (argc == 4) - { - if (strcmp(argv[1], "-d") == 0) - { - doDisplay = 1; - } - else if (strcmp(argv[3], "-d") == 0) - { - doDisplay = 1; - } - if (strcmp(argv[1], "-h") == 0) - { - HIDDEN_VARIABLE = atof(argv[2]); - } - else if (strcmp(argv[2], "-h") == 0) - { - HIDDEN_VARIABLE = atof(argv[3]); - } - } + if (argc == 2) + { + if (strcmp(argv[1], "-d") == 0) + { + doDisplay = 1; + } + } + else if (argc == 3) + { + if (strcmp(argv[1], "-h") == 0) + { + HIDDEN_VARIABLE = atof(argv[2]); + } + } + else if (argc == 4) + { + if (strcmp(argv[1], "-d") == 0) + { + doDisplay = 1; + } + else if (strcmp(argv[3], "-d") == 0) + { + doDisplay = 1; + } + if (strcmp(argv[1], "-h") == 0) + { + HIDDEN_VARIABLE = atof(argv[2]); + } + else if (strcmp(argv[2], "-h") == 0) + { + HIDDEN_VARIABLE = atof(argv[3]); + } + } - qansel_run(qubitCount, bitCount, instr, instrLen, doDisplay); - free(instr); - free(lineIDs); + qansel_run(qubitCount, bitCount, instr, instrLen, doDisplay); + free(instr); + free(lineIDs); }