]> foleosoft.com Git - QAnsel.git/commitdiff
Sun 08 Dec 2024 04:40:01 PM EST
authora <[email protected]>
Sun, 8 Dec 2024 21:40:01 +0000 (16:40 -0500)
committera <[email protected]>
Sun, 8 Dec 2024 21:40:01 +0000 (16:40 -0500)
src/bytecode.c
src/openqasm.c

index 8212addfa027e76f26e32d354b722626c67bb577..bff1faf8a3f3c68e89a9332873f6a59c3e43eaae 100644 (file)
@@ -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
        {
index d57fc33d418e89c87e10473c0b21c79fdbc7a302..b57995e92192e1d680c4bfcf606710e4daa5254a 100644 (file)
@@ -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;
                }
        }