]> foleosoft.com Git - QAnsel.git/commitdiff
Fri Aug 2 05:23:16 PM EDT 2024
authormiha-q <>
Fri, 2 Aug 2024 21:23:16 +0000 (17:23 -0400)
committermiha-q <>
Fri, 2 Aug 2024 21:23:16 +0000 (17:23 -0400)
examples/ghz.txt
src/bytecode.c
src/bytecode.h
src/context.h
src/gui.html
src/imports/istina-editor.js
src/openqasm.c
src/qansel.h

index 07e46890d68b3d13344abdea16d4b348822cb09c..8bd66a2bb0d912061a476b11700f767bf92c50f2 100644 (file)
@@ -1,8 +1,3 @@
 qreg q[2];
-creg c[2];
-x q[0];
-z q[1];
-swap q[0], q[1];
-measure q[0] -> c[0];
-measure q[1] -> c[1];
-sample c;
\ No newline at end of file
+h q[0];
+sample q;
index 7327f7e369459b854080c53121ecafff9f0de2c4..7033c3a1918a869d5105c4e6c55cc5a400816f2c 100644 (file)
@@ -25,6 +25,7 @@ const char* qansel_instruction_to_string(unsigned char instr)
                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>";
@@ -509,6 +510,7 @@ int qansel_get_instruction_bitmax(unsigned char* ptr, int offset, int* bitmax, i
                        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;
@@ -593,6 +595,7 @@ int qansel_get_instruction_size(unsigned char instr)
                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);
@@ -645,6 +648,7 @@ void qansel_get_barrier(QBytecode** qbc, int idx)
                        (*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:
@@ -688,11 +692,76 @@ void qansel_get_barrier(QBytecode** qbc, int idx)
        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;
@@ -701,10 +770,11 @@ void qansel_born(cpx_mtx_t* stateVector, int PC, int qubitCount, unsigned char q
                                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)
        {
@@ -718,8 +788,21 @@ void qansel_born(cpx_mtx_t* stateVector, int PC, int qubitCount, unsigned char q
                                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);
        }
 }
 
@@ -982,9 +1065,18 @@ int qansel_crawl(QAnselContext* ctx, unsigned char* program, int programSize, in
                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;
 }
 
@@ -1401,7 +1493,10 @@ void qansel_run(QAnselContext* ctx, unsigned char* program, int programSize, int
                                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];
@@ -1546,14 +1641,14 @@ int qanselExecuteBytecode(unsigned char* buff, int sizeofbuff, QAnselContext* ct
                        }
                        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
index a3da33fe526513809c1eb5e5590eedd3d90050ae..71af0f28ad2d56470d93491c7162cae97490b865 100644 (file)
@@ -129,7 +129,7 @@ unsigned char qansel_measure(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigne
 int qansel_get_instruction_bitmax(unsigned char* ptr, int offset, int* bitmax, int* qbitmax);
 int qansel_get_instruction_size(unsigned char instr);
 void qansel_get_barrier(QBytecode** qbc, int idx);
-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);
 void qansel_density_or_print(cpx_mtx_t* stateVector, unsigned char* bitVector, unsigned char density, int bitCount, int qubitCount, unsigned char a0);
 float qansel_get_float(unsigned char* program, int offset);
 short qansel_get_short(unsigned char* program, int offset);
index ad4dc3514e05bcca713d46579985cdc1c6c63e18..40374fbe556aaeb262f06c89eca6927e33ac8925 100644 (file)
@@ -16,6 +16,9 @@ typedef struct
        float hidden_variable;
        int display_delay;
        int sampling_shots;
+       int bsampling_shots;
+       int qubit_count;
+       int bit_count;
        FILE* random_file;
 } QAnselContext;
 
index 5d45b2ccc755af99bbd12f66e6deab95ae9fefc4..b0ac8d3d306e892c0a83ec56a7733161d4118865 100644 (file)
                                                }
                                                else
                                                {
-                                                       ret += "born q;\n";
+                                                       ret += "sample q;\n";
                                                }
                                        }
                                        
                {
                        if (mode == 1)
                        {
-                               err = err.replace(/[\n]/g, "<br />");
+                               try
+                               {
+                                       err = err.replace(/[\n]/g, "<br />");
+                               }
+                               catch
+                               {
+                                       err = "Unknown server-side error.";
+                               }
                        }
                        $(".program-instr")[0].style.display = "none";
                        $("#modal-main-confirm")[0].setAttribute("onclick", "closeModal();");
index 7d6bc2dcd85a04b504821a79b51d7eaacc5316a1..12a78e18499c99047fbe2c110e9a3e3e71919ceb 100644 (file)
@@ -247,7 +247,8 @@ IstinaEditor.highlightForQAnsel = function(txt)
                "barrier",
                "hvar",
                "rand",
-               "born"
+               "born",
+               "bsample"
        ];
                
        for (var i = 0; i < keywords.length; i++)
index f71c81e09d6a144dd787ba710987f1ee8e17eef0..5104e0dc122b5c14f4897d5129b20c7b2502b72e 100644 (file)
@@ -278,6 +278,7 @@ int qansel_process_chunk(int index, char* chunk, int line, regmatch_t* regmatche
                        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;
@@ -723,7 +724,7 @@ int qansel_process_chunks(char** chunks, int* associatedLines, int count, unsign
        {
                "^[ ]*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]*)[ ]*\\][ ]*|)$",
@@ -778,6 +779,8 @@ int qansel_process_chunks(char** chunks, int* associatedLines, int count, unsign
        }
        *retBinary = binary;
        *retSize = binarySize;
+       ctx->qubit_count = qubitCount;
+       ctx->bit_count = bitCount;
        return status;
 }
 
@@ -806,6 +809,7 @@ int qanselBuildFromSource(char* osource, unsigned char** binary, int* binarySize
        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");
index c43f1c1d5f0ed46cf2e52f89a8514c2e0da064c2..da843580ac784d5211aac8993e11f6eac7d98271 100644 (file)
@@ -36,6 +36,7 @@
 #define QANSEL_INSTRUCTION_MEASURE 0xD0
 #define QANSEL_INSTRUCTION_DENSITY 0xD1
 #define QANSEL_INSTRUCTION_BORN 0xD2
+#define QANSEL_INSTRUCTION_BSAMPLE 0xD3
 #define QANSEL_INSTRUCTION_IF_E 0xE1
 #define QANSEL_INSTRUCTION_IF_NE 0xE2
 #define QANSEL_INSTRUCTION_IF_G 0xE3