From: a Date: Sun, 8 Dec 2024 21:40:01 +0000 (-0500) Subject: Sun 08 Dec 2024 04:40:01 PM EST X-Git-Url: http://www.foleosoft.com/?a=commitdiff_plain;h=b18c6b0dfa8bb2ac7308c4257a1f4ad3fc827a0d;p=QAnsel.git Sun 08 Dec 2024 04:40:01 PM EST --- diff --git a/src/bytecode.c b/src/bytecode.c index 8212add..bff1faf 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -445,9 +445,8 @@ void qansel_instruction if (needToFreeGate) free(gate_ptr); } -unsigned char qansel_measure(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigned char qubitCount, unsigned char qubit) +unsigned char qansel_rand_b(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigned int qubitCountPow2, unsigned char qubit) { - unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount); cpx_t n; float prob0 = 0; for (unsigned int i = 0; i < qubitCountPow2; i++) @@ -468,7 +467,46 @@ unsigned char qansel_measure(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigne prob0 /= probtot; prob1 /= probtot; } - unsigned char newBit = r < prob0 ? 0 : 1; + return r < prob0 ? 0 : 1; +} + +void qansel_sample_stats(unsigned short* stats, int allMode, int shots, int bitCount, int samplingBit) +{ + unsigned int count = 0; + for (unsigned int i = 0; i < (1 << bitCount); i++) + { + unsigned int tmp = i; + for (unsigned char j = 0; j < bitCount; j++) + { + unsigned char bit = (tmp >> (bitCount - 1) & 1); + if (j == (bitCount - samplingBit - 1) && bit) + { + count += stats[i]; + } + if (samplingBit == allMode) + { + putchar('0' + bit); + } + tmp <<= 1; + } + if (samplingBit == allMode) + { + printf("\t%i\t%.2f%%\n", stats[i], ((float)stats[i] / (float)shots) * (float)100); + } + } + if (samplingBit != allMode) + { + float prob = ((float)count / (float)shots) * (float)100; + printf("0\t%i\t%.2f%%\n", shots-count, ((float)100)-prob); + printf("1\t%i\t%.2f%%\n", count, prob); + } +} + +unsigned char qansel_measure(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigned char qubitCount, unsigned char qubit) +{ + cpx_t n; + unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount); + unsigned char newBit = qansel_rand_b(ctx, stateVector, qubitCountPow2, qubit); float probTot = 0; for (unsigned int i = 0; i < qubitCountPow2; i++) { @@ -485,8 +523,7 @@ unsigned char qansel_measure(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigne } cpx_mtx_set(stateVector, 0, i, &n); } - - float multiplier = sqrt(1 / probTot); + float multiplier = probTot == 0 ? 1 : sqrt(1 / probTot); for (unsigned int i = 0; i < qubitCountPow2; i++) { unsigned char bit = (i >> qubit) & 1; @@ -712,10 +749,12 @@ void qansel_get_barrier(QBytecode** qbc, int idx) exit(1); } +//mode0 = born rule +//mode1 = bsample void qansel_born(QAnselContext* ctx, cpx_mtx_t* stateVector, int PC, int qubitCount, unsigned char q0, unsigned char mode) { unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount); - if (q0 == QANSEL_ALL_QUANTUM) + if (mode == 0) { float *psisquared = malloc(sizeof(float) * qubitCountPow2); for (unsigned int j = 0; j < qubitCountPow2; j++) @@ -724,126 +763,60 @@ void qansel_born(QAnselContext* ctx, cpx_mtx_t* stateVector, int PC, int qubitCo cpx_mtx_get(stateVector, 0, j, &n); psisquared[j] = cpx_magsqr(&n); } - //add any error skew if desired - if (ctx->noise > 0) - { - float totalprob = 0; - for (unsigned int j = 0; j < qubitCountPow2; j++) - { - psisquared[j] += ctx->noise; - totalprob += psisquared[j]; - } - for (unsigned int j = 0; j < qubitCountPow2; j++) - { - psisquared[j] /= totalprob; - } - } - if (mode == 0) + for (unsigned int j = 0; j < qubitCountPow2; j++) { - for (unsigned int j = 0; j < qubitCountPow2; j++) + unsigned int tmp = j; + for (unsigned char k = 0; k < qubitCount; k++) { - unsigned int tmp = j; - for (unsigned char k = 0; k < qubitCount; k++) + if (q0 == QANSEL_ALL_QUANTUM) { putchar('0' + (tmp >> (qubitCount - 1) & 1)); - tmp <<= 1; } - printf("\t%.2f%%\n", psisquared[j] * 100); + tmp <<= 1; } - free(psisquared); - return; - } - float *psisquared_sorted = malloc(sizeof(float) * qubitCountPow2); - unsigned short *sorting = malloc(sizeof(unsigned short) * qubitCountPow2); - unsigned short *rsorting = malloc(sizeof(unsigned short) * qubitCountPow2); - for (int i = 0; i < qubitCountPow2; i++) psisquared_sorted[i] = 0; - for (int i = 0; i < qubitCountPow2; i++) - { - float max = -1; - int maxi = -1; - for (int j = 0; j < qubitCountPow2; j++) + if (q0 == QANSEL_ALL_QUANTUM) { - if (psisquared[j] >= max) - { - max = psisquared[j]; - maxi = j; - } - } - psisquared_sorted[i] = max; - sorting[i] = maxi; - rsorting[maxi] = i; - psisquared[maxi] = -1; - } - //for (int i = 0; i < qubitCountPow2; i++) printf("]%i -> %i: %f[\n", rsorting[i], sorting[i], psisquared_sorted[i]); - free(psisquared); - unsigned short *stats = malloc(sizeof(unsigned short) * qubitCountPow2); - for (int i = 0; i < qubitCountPow2; i++) stats[i] = 0; - for (int i = 0; i < (ctx->bsampling_shots); i++) - { - float r = (ctx->hidden_variable_set) ? qansel_rand_h() : qansel_rand_t(ctx); - float j = 0; - //printf("--------------------------------\n"); - for (unsigned int j = 0; j < qubitCountPow2; j++) - { - //printf("%f >= %f\n", psisquared_sorted[j], r); - if (psisquared_sorted[j] >= (r - 0.0000001)) - { - stats[j]++; - //printf("%i _/\n", j); - break; - } - r -= psisquared_sorted[j]; - if (j == qubitCountPow2 - 1) - { - stats[j]++; - //printf("%i _/\n", j); - } + printf("\t%.2f%%\n", psisquared[j] * 100); } } - for (unsigned int j = 0; j < qubitCountPow2; j++) + if (q0 != QANSEL_ALL_QUANTUM) { - unsigned int tmp = j; - for (unsigned char k = 0; k < qubitCount; k++) + float prob0; + for (unsigned int i = 0; i < qubitCountPow2; i++) { - putchar('0' + (tmp >> (qubitCount - 1) & 1)); - tmp <<= 1; + cpx_t n; + unsigned char bit = (i >> q0) & 1; + cpx_mtx_get(stateVector, 0, i, &n); + if (bit == 0) prob0 += cpx_magsqr(&n); } - //printf("%i -> %i\n", j, sorting[j]); - printf("\t%i\t%.2f%%\n", stats[rsorting[j]], ((float)stats[rsorting[j]] / (float)(ctx->bsampling_shots)) * (float)100); + printf("%i\t%.2f%%\n", 0, prob0 * 100); + printf("%i\t%.2f%%\n", 1, (1 - prob0) * 100); } - free(psisquared_sorted); - free(stats); - free(sorting); - free(rsorting); + free(psisquared); + return; } - else if (q0 <= QANSEL_QBOUND_UPPER) - { - float prob = 0; - for (unsigned int j = 0; j < qubitCountPow2; j++) - { - cpx_t n; - cpx_mtx_get(stateVector, 0, j, &n); - if ((j >> q0) & 1) - { - prob += cpx_magsqr(&n); - } - } - if (mode == 0) - { - printf("0\t%.2f%%\n", (1 - prob) * 100.0); - printf("1\t%.2f%%\n", prob * 100.0); - return; - } - unsigned short stats = 0; - for (int i = 0; i < (ctx->bsampling_shots); i++) + cpx_mtx_t oldStateVector; + cpx_mtx_init(&oldStateVector, stateVector->rows, stateVector->cols); + cpx_mtx_copy(&oldStateVector, stateVector); + unsigned short stats[65536]; + for (unsigned int i = 0; i < qubitCountPow2; i++) + { + stats[i] = 0; + } + for (unsigned int i = 0; i < ctx->bsampling_shots; i++) + { + unsigned int bitidx = 0; + for (unsigned int j = 0; j < qubitCount; j++) { - float r = (ctx->hidden_variable_set) ? qansel_rand_h() : qansel_rand_t(ctx); - stats += r < prob ? 1 : 0; + unsigned char newBit = qansel_measure(ctx, stateVector, qubitCount, j); + bitidx |= newBit << j; } - printf("0\t%i\t%.2f%%\n", (ctx->bsampling_shots) - stats, (((float)(ctx->bsampling_shots) - (float)stats) / (float)(ctx->bsampling_shots)) * (float)100); - printf("1\t%i\t%.2f%%\n", stats, ((float)stats / (float)(ctx->bsampling_shots)) * (float)100); + stats[bitidx]++; + cpx_mtx_copy(stateVector, &oldStateVector); } + qansel_sample_stats(stats, QANSEL_ALL_QUANTUM, ctx->bsampling_shots, qubitCount, q0); + cpx_mtx_free(&oldStateVector); } void qansel_density_or_print(cpx_mtx_t* stateVector, unsigned char* bitVector, unsigned char density, int bitCount, int qubitCount, unsigned char a0) @@ -1714,34 +1687,7 @@ int qanselExecuteBytecode(unsigned char* buff, int sizeofbuff, QAnselContext* ct } stats[stat]++; } - unsigned int count = 0; - for (unsigned int i = 0; i < (1 << bitCount); i++) - { - unsigned int tmp = i; - for (unsigned char j = 0; j < bitCount; j++) - { - unsigned char bit = (tmp >> (bitCount - 1) & 1); - if (j == (bitCount - (ctx->sampling_bit) - 1) && bit) - { - count += stats[i]; - } - if ((ctx->sampling_bit) == QANSEL_ALL) - { - putchar('0' + bit); - } - tmp <<= 1; - } - if ((ctx->sampling_bit) == QANSEL_ALL) - { - printf("\t%i\t%.2f%%\n", stats[i], ((float)stats[i] / (float)shots) * (float)100); - } - } - if ((ctx->sampling_bit) != QANSEL_ALL) - { - float prob = ((float)count / (float)shots) * (float)100; - printf("0\t%i\t%.2f%%\n", shots-count, ((float)100)-prob); - printf("1\t%i\t%.2f%%\n", count, prob); - } + qansel_sample_stats(stats, QANSEL_ALL, shots, bitCount, ctx->sampling_bit); } else { diff --git a/src/openqasm.c b/src/openqasm.c index d57fc33..b57995e 100644 --- a/src/openqasm.c +++ b/src/openqasm.c @@ -694,6 +694,7 @@ int qansel_process_chunk(int index, char* chunk, int line, regmatch_t* regmatche return 0; } *samplingshots = d0; + ctx->bsampling_shots = d0; break; } }