From: miha-q <> Date: Thu, 15 Aug 2024 21:47:44 +0000 (-0400) Subject: Thu Aug 15 05:47:44 PM EDT 2024 X-Git-Url: http://www.foleosoft.com/?a=commitdiff_plain;h=647858d3a1343ccbeb16bfcc9c33361e5a64af78;p=QAnsel.git Thu Aug 15 05:47:44 PM EDT 2024 --- diff --git a/src/bytecode.c b/src/bytecode.c index 9a73886..8ed1edb 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -61,7 +61,15 @@ float qansel_rand_t(QAnselContext* ctx) unsigned char r = 0; switch (ctx->hardware_rng) { - case QANSEL_HARDWARE_TRUERNG: r = fgetc(ctx->random_file); break; + case QANSEL_HARDWARE_TRUERNG: + r = fgetc(ctx->random_file); + ctx->buffer_pos += 1; + if (ctx->buffer_pos >= ctx->buffer_size) + { + fclose(ctx->random_file); + ctx->random_file = fopen(ctx->random_path, "r"); + } + break; case QANSEL_HARDWARE_RDSEED: r = qansel_hardware_rand(); break; } num = (num << 8) | r; diff --git a/src/context.c b/src/context.c index f21b534..60ff181 100644 --- a/src/context.c +++ b/src/context.c @@ -68,24 +68,38 @@ int qanselContextBegin(QAnselContext* ctx) if (ctx->hardware_rng == QANSEL_HARDWARE_AUTO) { - ctx->random_file = fopen("/dev/TrueRNG0", "r"); + ctx->random_file = fopen("/dev/qrandom0", "r"); if (ctx->random_file == NULL) { - if (qansel_hardware_rand_supported()) + ctx->random_file = fopen("/dev/TrueRNG0", "r"); + if (ctx->random_file == NULL) { - if (ctx->verbose) printf("QAnsel: Hardware `Intel Secure Key Technology` selected.\n"); - ctx->hardware_rng = QANSEL_HARDWARE_RDSEED; + if (qansel_hardware_rand_supported()) + { + if (ctx->verbose) printf("QAnsel: Hardware `Intel Secure Key Technology` selected.\n"); + ctx->hardware_rng = QANSEL_HARDWARE_RDSEED; + } + else + { + fprintf(stderr, "QAnsel: No supported hardware random number generator found.\n"); + return 0; + } } else { - fprintf(stderr, "QAnsel: No supported hardware random number generator found.\n"); - return 0; + if (ctx->verbose) printf("QAnsel: Hardware `TrueRNG` selected.\n"); + strcpy(ctx->random_path, "/dev/TrueRNG0"); + ctx->hardware_rng = QANSEL_HARDWARE_TRUERNG; + ctx->buffer_size = -1; } } else { - if (ctx->verbose) printf("QAnsel: Hardware `TrueRNG` selected.\n"); + if (ctx->verbose) printf("QAnsel: Hardware `Quantis` selected.\n"); + strcpy(ctx->random_path, "/dev/qrandom0"); ctx->hardware_rng = QANSEL_HARDWARE_TRUERNG; + ctx->buffer_size = 65535; + ctx->buffer_pos = 0; } } if (ctx->optimization_level & QANSEL_MODE_METAL) diff --git a/src/context.h b/src/context.h index 40374fb..39d1da2 100644 --- a/src/context.h +++ b/src/context.h @@ -19,6 +19,9 @@ typedef struct int bsampling_shots; int qubit_count; int bit_count; + int buffer_size; + int buffer_pos; + char random_path[256]; FILE* random_file; } QAnselContext; diff --git a/src/imports/bloch-sphere.html b/src/imports/bloch-sphere.html index a0742e3..ae4b53f 100644 --- a/src/imports/bloch-sphere.html +++ b/src/imports/bloch-sphere.html @@ -47,6 +47,11 @@ useColor = false; } var gate = {}; + gate.i = + [ + [1, 0], [0, 0], + [0, 0], [1, 0], + ]; gate.x = [ [0, 0], [1, 0], @@ -63,6 +68,10 @@ [0, 0], [-1, 0], ]; var R = 1/Math.sqrt(2); + [ + [ 1, 0 ], [ 0, 0 ], + [ 0, 0 ], [ 1, 0 ], + ]; gate.h = [ [ R, 0 ], [ R, 0 ], @@ -90,6 +99,96 @@ ]; gate.reset = "reset"; gate.measure = "measure"; + gate.add = function(a, b) + { + var ret = + [ + [0, 0], [0, 0], + [0, 0], [0, 0] + ]; + for (var i = 0; i < ret.length; i++) + { + ret[i] = complex.add(a[i], b[i]); + } + return ret; + }; + gate.mul1 = function(a, b) + { + var ret = + [ + [0, 0], [0, 0], + [0, 0], [0, 0] + ]; + for (var i = 0; i < ret.length; i++) + { + ret[i] = complex.multiply(a[i], b); + } + return ret; + }; + gate.copy = function(a) + { + var ret = + [ + [0, 0], [0, 0], + [0, 0], [0, 0] + ]; + for (var i = 0; i < ret.length; i++) + { + ret[i] = a[i]; + } + return ret; + }; + gate.div1 = function(a, b) + { + var ret = + [ + [0, 0], [0, 0], + [0, 0], [0, 0] + ]; + for (var i = 0; i < ret.length; i++) + { + ret[i] = complex.divide(a[i], b); + } + return ret; + }; + gate.pow1 = function(a, b) + { + var ret = + [ + [0, 0], [0, 0], + [0, 0], [0, 0] + ]; + for (var i = 0; i < ret.length; i++) + { + ret[i] = complex.power(a[i], b); + } + return ret; + }; + gate.exp = (g, p) => + { + var ret = gate.copy(gate.i); + for (var i = 0; i < p; i++) + { + var tmp = gate.copy(g); + gate.div(tmp, factorial(i + 1)); + ret = gate.add(ret, tmp); + } + return ret; + }; + gate.log = (g, p) => + { + var ret = gate.add(g, gate.mul1(gate.i, [-1, 0])); + for (var i = 2; i < p; i++) + { + console.log(i + ": " + (i % 2 == 0 ? " - " : " + ") + "(1/" + i + ")(A - I)^" + i); + var tmp = gate.add(g, gate.mul1(gate.i, [-1, 0])); + tmp = gate.pow1(tmp, i); + tmp = gate.div1(tmp, [i, 0]); + if (i % 2 == 0) tmp = gate.mul1(tmp, [-1, 0]); + ret = gate.add(ret, tmp); + } + return ret; + }; var complex = {}; complex.multiply = (a, b) => @@ -115,6 +214,27 @@ { return Math.sqrt( Math.pow(a[0], 2) + Math.pow(a[1], 2) ); }; + complex.power = (a, n) => + { + const r = Math.sqrt(a[0] * a[0] + a[1] * a[1]); + const theta = Math.atan2(a[1], a[0]); + const rPowerN = Math.pow(r, n); + const newTheta = n * theta; + const realPart = rPowerN * Math.cos(newTheta); + const imaginaryPart = rPowerN * Math.sin(newTheta); + return [realPart, imaginaryPart]; + }; + complex.divide = (a, b) => + { + d = b[1]; + c = b[0]; + b = a[1]; + a = a[0]; + var denominator = c * c + d * d; + var realPart = (a * c + b * d) / denominator; + var imaginaryPart = (b * c - a * d) / denominator; + return [realPart, imaginaryPart]; + }; var qubit = {}; qubit.state = [ [1, 0], [0, 0] ]; @@ -235,6 +355,14 @@ return sprite; } + function factorial(n) + { + if (n === 0 || n === 1) + { + return 1; + } + return n * factorial(n - 1); + } /* var sphereCenterY = sphere.position.y; // Y position of the sphere's center var sphereRadius = 1; // Radius of the sphere diff --git a/src/index.html b/src/index.html index 24bba2b..156a26d 100644 --- a/src/index.html +++ b/src/index.html @@ -334,7 +334,8 @@ } if (maxQ >= 0) { - ret = "qreg q[" + (maxQ + 1) + "];\n" + ret; +// ret = "qreg q[" + (maxQ + 1) + "];\n" + ret; + ret = "qreg q[" + ($("[pidx*=',0'").length - 1) + "];\n" + ret; if (maxC >= 0) { ret += "sample c;\n";