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++)
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++)
{
}
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;
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++)
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)
}
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
{