case QANSEL_INSTRUCTION_MEASURE: return "measure";
case QANSEL_INSTRUCTION_DENSITY: return "density";
case QANSEL_INSTRUCTION_BORN: return "born";
+ case QANSEL_INSTRUCTION_BSAMPLE: return "bsample";
case QANSEL_INSTRUCTION_IF_E: return "if==";
case QANSEL_INSTRUCTION_IF_NE: return "if!=";
case QANSEL_INSTRUCTION_IF_G: return "if>";
return 1;
case QANSEL_INSTRUCTION_BARRIER:
case QANSEL_INSTRUCTION_BORN:
+ case QANSEL_INSTRUCTION_BSAMPLE:
a0 = ptr[offset + 1];
if (a0 > QANSEL_QBOUND_UPPER && a0 != QANSEL_ALL_QUANTUM) return 0;
if (a0 != QANSEL_ALL_QUANTUM) *qbitmax = a0 + 1;
case QANSEL_INSTRUCTION_CSWAP: return 1 + 3;
case QANSEL_INSTRUCTION_MEASURE: return 1 + 2;
case QANSEL_INSTRUCTION_DENSITY: return 1 + 1;
+ case QANSEL_INSTRUCTION_BSAMPLE: return 1 + 1;
case QANSEL_INSTRUCTION_BORN: return 1 + 1;
case QANSEL_INSTRUCTION_IF_E: return 1 + 1 + sizeof(unsigned short);
case QANSEL_INSTRUCTION_IF_NE: return 1 + 1 + sizeof(unsigned short);
(*qbc)[idx].barrier[0] = (*qbc)[idx].bytes[1];
(*qbc)[idx].barrier[1] = (*qbc)[idx].bytes[2];
return;
+ case QANSEL_INSTRUCTION_BSAMPLE:
case QANSEL_INSTRUCTION_BORN:
case QANSEL_INSTRUCTION_BARRIER:
case QANSEL_INSTRUCTION_PRINT:
exit(1);
}
-void qansel_born(cpx_mtx_t* stateVector, int PC, int qubitCount, unsigned char q0)
+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)
{
+ float *psisquared = malloc(sizeof(float) * qubitCountPow2);
+ for (unsigned int j = 0; j < qubitCountPow2; j++)
+ {
+ if (mode == 0)
+ {
+ unsigned int tmp = j;
+ for (unsigned char k = 0; k < qubitCount; k++)
+ {
+ putchar('0' + (tmp >> (qubitCount - 1) & 1));
+ tmp <<= 1;
+ }
+ }
+ cpx_t n;
+ cpx_mtx_get(stateVector, 0, j, &n);
+ psisquared[j] = cpx_magsqr(&n);
+ if (mode == 0)
+ {
+ printf("\t%.2f%%\n", psisquared[j] * 100);
+ }
+ }
+ if (mode == 0)
+ {
+ free(psisquared);
+ return;
+ }
+ float *psisquared_sorted = malloc(sizeof(float) * qubitCountPow2);
+ unsigned short *sorting = 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 (psisquared[j] > max)
+ {
+ max = psisquared[j];
+ maxi = j;
+ }
+ }
+ psisquared_sorted[i] = max;
+ sorting[i] = maxi;
+ psisquared[maxi] = -1;
+ }
+ 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) ? qansel_rand_h() : qansel_rand_t(ctx);
+ float j = 0;
+ for (unsigned int j = 0; j < qubitCountPow2; j++)
+ {
+ if (psisquared_sorted[j] >= r)
+ {
+ stats[j]++;
+ break;
+ }
+ r -= psisquared_sorted[j];
+ if (j == qubitCountPow2 - 1)
+ {
+ stats[j]++;
+ }
+ }
+ }
for (unsigned int j = 0; j < qubitCountPow2; j++)
{
unsigned int tmp = j;
putchar('0' + (tmp >> (qubitCount - 1) & 1));
tmp <<= 1;
}
- cpx_t n;
- cpx_mtx_get(stateVector, 0, j, &n);
- printf("\t%.1f%%\n", cpx_magsqr(&n) * 100);
+ printf("\t%i\t%.2f%%\n", stats[sorting[j]], ((float)stats[sorting[j]] / (float)(ctx->bsampling_shots)) * (float)100);
}
+ free(psisquared_sorted);
+ free(stats);
+ free(sorting);
}
else if (q0 <= QANSEL_QBOUND_UPPER)
{
prob += cpx_magsqr(&n);
}
}
- printf("0\t%.1f%%\n", (1 - prob) * 100.0);
- printf("1\t%.1f%%\n", prob * 100.0);
+ 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++)
+ {
+ float r = (ctx->hidden_variable) ? qansel_rand_h() : qansel_rand_t(ctx);
+ stats += r < prob ? 1 : 0;
+ }
+ 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);
}
}
if (qbitmax > *qubitCount) *qubitCount = qbitmax;
PC += next;
}
- if (ctx->verbose) printf("Quantum bits allocated: %i\n", *qubitCount);
- if (ctx->verbose) printf("Classical bits allocated: %i\n", *bitCount);
-
+ if (*qubitCount > ctx->qubit_count)
+ {
+ fprintf(stderr, "QAnsel: Not enough qubits allocated.\n");
+ return 0;
+ }
+ if (*bitCount > ctx->bit_count)
+ {
+ fprintf(stderr, "QAnsel: Not enough classical bits allocated.\n");
+ return 0;
+ }
+ *qubitCount = ctx->qubit_count;
+ *bitCount = ctx->bit_count;
return 1;
}
break;
case QANSEL_INSTRUCTION_BORN:
a0 = program[PC + 1];
- qansel_born(&stateVector, PC, qubitCount, a0);
+ qansel_born(ctx, &stateVector, PC, qubitCount, a0, 0);
+ case QANSEL_INSTRUCTION_BSAMPLE:
+ a0 = program[PC + 1];
+ qansel_born(ctx, &stateVector, PC, qubitCount, a0, 1);
break;
case QANSEL_INSTRUCTION_DENSITY:
a0 = program[PC + 1];
}
if ((ctx->sampling_bit) == QANSEL_ALL)
{
- printf("\t%i\t%.1f%%\n", stats[i], ((float)stats[i] / (float)shots) * (float)100);
+ 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%.1f%%\n", shots-count, ((float)100)-prob);
- printf("1\t%i\t%.1f%%\n", count, prob);
+ printf("0\t%i\t%.2f%%\n", shots-count, ((float)100)-prob);
+ printf("1\t%i\t%.2f%%\n", count, prob);
}
}
else
else if (strcmp(tmp, "reset") == 0) instr = QANSEL_INSTRUCTION_RESET;
else if (strcmp(tmp, "barrier") == 0) instr = QANSEL_INSTRUCTION_BARRIER;
else if (strcmp(tmp, "born") == 0) instr = QANSEL_INSTRUCTION_BORN;
+ else if (strcmp(tmp, "sample") == 0) instr = QANSEL_INSTRUCTION_BSAMPLE;
else if (strcmp(tmp, "density") == 0) instr = QANSEL_INSTRUCTION_DENSITY;
else if (strcmp(tmp, "print") == 0) instr = QANSEL_INSTRUCTION_PRINT;
else if (strcmp(tmp, "not") == 0) instr = QANSEL_INSTRUCTION_X;
{
"^[ ]*qreg[ ]*q[ ]*\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*$",
"^[ ]*creg[ ]*c[ ]*\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*$",
- "^[ ]*(x|y|z|h|sdg|tdg|s|t|set|reset|barrier|born|density|print)[ ]*q[ ]*(\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*|)$",
+ "^[ ]*(x|y|z|h|sdg|tdg|s|t|set|reset|barrier|born|sample|density|print)[ ]*q[ ]*(\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*|)$",
"^[ ]*(rx|ry|rz|u1)\\([ ]*([-/0-9PI.]*)[ ]*\\)[ ]*q[ ]*(\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*|)$",
"^[ ]*(u2)\\([ ]*([-/0-9PI.]*)[ ]*,[ ]*([-/0-9PI.]*)[ ]*\\)[ ]*q[ ]*(\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*|)$",
"^[ ]*(u|u3)\\([ ]*([-/0-9PI.]*)[ ]*,[ ]*([-/0-9PI.]*)[ ]*,[ ]*([-/0-9PI.]*)[ ]*\\)[ ]*q[ ]*(\\[[ ]*([0-9][0-9]*)[ ]*\\][ ]*|)$",
}
*retBinary = binary;
*retSize = binarySize;
+ ctx->qubit_count = qubitCount;
+ ctx->bit_count = bitCount;
return status;
}
int status = qansel_read_script(source, &chunks, &chunksAssociatedLines, &chunksCount);
int samplingshots = ctx->sampling_shots;
ctx->sampling_shots = 0;
+ ctx->bsampling_shots = samplingshots == 0 ? QANSEL_SHOTS_DEFAULT : samplingshots;
if (!status)
{
fprintf(stderr, "QAnsel: Read script failure.\n");