From 1e0805043c2898afdbb2d20ceeb932a92e51e104 Mon Sep 17 00:00:00 2001 From: miha-q <> Date: Sun, 17 Sep 2023 22:43:02 -0400 Subject: [PATCH] Sun Sep 17 10:43:02 PM EDT 2023 --- bin/QAnsel | Bin 66112 -> 89296 bytes examples/belltest/classic.sh | 113 ++ examples/big.qsm | 52 + examples/teleportation.qsm | 9 +- log | 2168 ++++++++++++++++++++++++++++++++++ po | 2048 ++++++++++++++++++++++++++++++++ src/QAnsel.c | 292 ++++- src/complex.c | 257 +++- src/cores.c | 53 + src/display.c | 40 +- src/gates.c | 2 +- 11 files changed, 4962 insertions(+), 72 deletions(-) create mode 100644 examples/belltest/classic.sh create mode 100644 examples/big.qsm create mode 100644 log create mode 100644 po create mode 100644 src/cores.c diff --git a/bin/QAnsel b/bin/QAnsel index baa3cc764d04649e48e350b8908cc56af433b66d..82b3bc701b1fa4a1e7bbc00dd5f60f6d1ce7c826 100755 GIT binary patch literal 89296 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 literal 66112 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 HoUHmEfnM1o diff --git a/examples/belltest/classic.sh b/examples/belltest/classic.sh new file mode 100644 index 0000000..2b72f35 --- /dev/null +++ b/examples/belltest/classic.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +function classic { +../../bin/QAnsel << HERE +qreg q[2]; +creg c[2]; + +h q[0]; +h q[1]; +measure q[0] -> c[0]; +measure q[1] -> c[1]; +x q[0]; +if(c[1]==1) x q[1]; +print c; + +//Player X rules +if(c[0]==1) x q[0]; + +//Player Y rules +x q[1]; + +//Results +measure q[0] -> c[0]; +measure q[1] -> c[1]; +print c; + +HERE +} + +function quantum { +../../bin/QAnsel << HERE +qreg q[2]; +creg c[2]; + +h q[0]; +h q[1]; +measure q[0] -> c[0]; +measure q[1] -> c[1]; +print c; +reset q[0]; +reset q[1]; + +h q[0]; +cx q[0], q[1]; + +if(c[0]==1) ry(pi/2) q[0]; +if(c[0]==1) rz(pi) q[0]; + +if(c[1]==0) ry(pi/4) q[1]; +if(c[1]==0) rz(pi) q[1]; + +if(c[1]==1) ry(-pi/4) q[1]; +if(c[1]==1) rz(pi) q[1]; + +measure q[0] -> c[0]; +measure q[1] -> c[1]; +print c; + +HERE +} + +function test +{ + if [ "$1" == "00 00" ] + then + echo 1 + elif [ "$1" == "00 11" ] + then + echo 1 + elif [ "$1" == "01 00" ] + then + echo 1 + elif [ "$1" == "01 11" ] + then + echo 1 + elif [ "$1" == "10 00" ] + then + echo 1 + elif [ "$1" == "10 11" ] + then + echo 1 + elif [ "$1" == "11 10" ] + then + echo 1 + elif [ "$1" == "11 01" ] + then + echo 1 + else + echo 0 + fi +} + +trials=1000 +cwins=0 +qwins=0 +for i in $(seq 1 $trials) +do + clear + echo "$(( (100 * i) / trials ))%" + + trial=$(classic | xargs) + results=$(test "$trial") + cwins=$((cwins+results)) + + trial=$(quantum | xargs) + results=$(test "$trial") + qwins=$((qwins+results)) + +done +clear + +echo "Classical Strategy: $cwins points" +echo "Quantum Strategy: $qwins points" diff --git a/examples/big.qsm b/examples/big.qsm new file mode 100644 index 0000000..583730e --- /dev/null +++ b/examples/big.qsm @@ -0,0 +1,52 @@ +qreg q[2]; +creg c[2]; + +h q[0]; +cx q[0], q[1]; + +//00 +h q[0]; +cx q[0], q[1]; + +ry(pi/4) q[1]; +rz(pi) q[1]; + +sample; +reset; + +//01 +h q[0]; +cx q[0], q[1]; + +ry(pi/2) q[0]; +rz(pi) q[0]; + +ry(pi/4) q[1]; +rz(pi) q[1]; + +sample; +reset; + +//10 +h q[0]; +cx q[0], q[1]; + +ry(-pi/4) q[1]; +rz(pi) q[1]; + +sample; +reset; + +//11 +h q[0]; +cx q[0], q[1]; + +ry(pi/2) q[0]; +rz(pi) q[0]; + +ry(-pi/4) q[1]; +rz(pi) q[1]; + +sample; +reset; + diff --git a/examples/teleportation.qsm b/examples/teleportation.qsm index c9fac7d..c17d924 100644 --- a/examples/teleportation.qsm +++ b/examples/teleportation.qsm @@ -2,7 +2,7 @@ qreg q[3]; creg c[2]; //qubit to teleport -u(1,2,3) q[0]; +u(1.6,1.6,1.6) q[0]; print q[0]; //show qubit to teleport //shared entangled qubit @@ -20,9 +20,12 @@ measure q[0] -> c[0]; measure q[1] -> c[1]; //rotate based on measurement results -if(c==2) x q[2]; if(c==1) z q[2]; +if(c==2) x q[2]; if(c==3) x q[2]; if(c==3) z q[2]; -print q[2]; //show teleported qubit \ No newline at end of file +//show teleported qubit +reset q[0]; +reset q[1]; +print q[2]; \ No newline at end of file diff --git a/log b/log new file mode 100644 index 0000000..37c580e --- /dev/null +++ b/log @@ -0,0 +1,2168 @@ +0;204 +204;408 +408;612 +612;816 +816;1020 +1020;1224 +1224;1428 +1428;1632 +1632;1836 +1836;2040 +2040;2244 +2244;2448 +2448;2652 +2652;2856 +2856;3060 +3060;3264 +3264;3468 +3468;3672 +3876;4096 +3672;3876 +1836;2040 +1632;1836 +1428;1632 +2244;2448 +2040;2244 +816;1020 +204;408 +0;204 +3264;3468 +2856;3060 +1224;1428 +2448;2652 +3060;3264 +2652;2856 +408;612 +612;816 +1020;1224 +3672;3876 +3876;4096 +3468;3672 +0;204 +204;408 +408;612 +612;816 +816;1020 +1020;1224 +1224;1428 +1428;1632 +1632;1836 +1836;2040 +2040;2244 +2244;2448 +2448;2652 +2652;2856 +2856;3060 +3060;3264 +3264;3468 +3468;3672 +3672;3876 +3876;4096 +1836;2040 +1428;1632 +1632;1836 +0;204 +612;816 +2244;2448 +2448;2652 +408;612 +3672;3876 +3060;3264 +204;408 +2652;2856 +3264;3468 +816;1020 +3468;3672 +2040;2244 +2856;3060 +1224;1428 +1020;1224 +3876;4096 +0;204 +204;408 +408;612 +612;816 +816;1020 +1020;1224 +1224;1428 +1428;1632 +1632;1836 +1836;2040 +2040;2244 +2244;2448 +2448;2652 +2652;2856 +2856;3060 +3060;3264 +3264;3468 +3468;3672 +3672;3876 +3876;4096 +2040;2244 +1836;2040 +1632;1836 +2244;2448 +408;612 +1428;1632 +2652;2856 +816;1020 +204;408 +2448;2652 +3060;3264 +2856;3060 +3468;3672 +1224;1428 +1020;1224 +3264;3468 +3876;4096 +612;816 +0;204 +3672;3876 +00000000000: 12% +00000000001: 0% +00000000010: 12% +00000000011: 0% +00000000100: 12% +00000000101: 0% +00000000110: 12% +00000000111: 0% +00000001000: 12% +00000001001: 0% +00000001010: 12% +00000001011: 0% +00000001100: 12% +00000001101: 0% +00000001110: 12% +00000001111: 0% +00000010000: 0% +00000010001: 0% +00000010010: 0% +00000010011: 0% +00000010100: 0% +00000010101: 0% +00000010110: 0% +00000010111: 0% +00000011000: 0% +00000011001: 0% +00000011010: 0% +00000011011: 0% +00000011100: 0% +00000011101: 0% +00000011110: 0% +00000011111: 0% +00000100000: 0% +00000100001: 0% +00000100010: 0% +00000100011: 0% +00000100100: 0% +00000100101: 0% +00000100110: 0% +00000100111: 0% +00000101000: 0% +00000101001: 0% +00000101010: 0% +00000101011: 0% +00000101100: 0% +00000101101: 0% +00000101110: 0% +00000101111: 0% +00000110000: 0% +00000110001: 0% +00000110010: 0% +00000110011: 0% +00000110100: 0% +00000110101: 0% +00000110110: 0% +00000110111: 0% +00000111000: 0% +00000111001: 0% +00000111010: 0% +00000111011: 0% +00000111100: 0% +00000111101: 0% +00000111110: 0% +00000111111: 0% +00001000000: 0% +00001000001: 0% +00001000010: 0% +00001000011: 0% +00001000100: 0% +00001000101: 0% +00001000110: 0% +00001000111: 0% +00001001000: 0% +00001001001: 0% +00001001010: 0% +00001001011: 0% +00001001100: 0% +00001001101: 0% +00001001110: 0% +00001001111: 0% +00001010000: 0% +00001010001: 0% +00001010010: 0% +00001010011: 0% +00001010100: 0% +00001010101: 0% +00001010110: 0% +00001010111: 0% +00001011000: 0% +00001011001: 0% +00001011010: 0% +00001011011: 0% +00001011100: 0% +00001011101: 0% +00001011110: 0% +00001011111: 0% +00001100000: 0% +00001100001: 0% +00001100010: 0% +00001100011: 0% +00001100100: 0% +00001100101: 0% +00001100110: 0% +00001100111: 0% +00001101000: 0% +00001101001: 0% +00001101010: 0% +00001101011: 0% +00001101100: 0% +00001101101: 0% +00001101110: 0% +00001101111: 0% +00001110000: 0% +00001110001: 0% +00001110010: 0% +00001110011: 0% +00001110100: 0% +00001110101: 0% +00001110110: 0% +00001110111: 0% +00001111000: 0% +00001111001: 0% +00001111010: 0% +00001111011: 0% +00001111100: 0% +00001111101: 0% +00001111110: 0% +00001111111: 0% +00010000000: 0% +00010000001: 0% +00010000010: 0% +00010000011: 0% +00010000100: 0% +00010000101: 0% +00010000110: 0% +00010000111: 0% +00010001000: 0% +00010001001: 0% +00010001010: 0% +00010001011: 0% +00010001100: 0% +00010001101: 0% +00010001110: 0% +00010001111: 0% +00010010000: 0% +00010010001: 0% +00010010010: 0% +00010010011: 0% +00010010100: 0% +00010010101: 0% +00010010110: 0% +00010010111: 0% +00010011000: 0% +00010011001: 0% +00010011010: 0% +00010011011: 0% +00010011100: 0% +00010011101: 0% +00010011110: 0% +00010011111: 0% +00010100000: 0% +00010100001: 0% +00010100010: 0% +00010100011: 0% +00010100100: 0% +00010100101: 0% +00010100110: 0% +00010100111: 0% +00010101000: 0% +00010101001: 0% +00010101010: 0% +00010101011: 0% +00010101100: 0% +00010101101: 0% +00010101110: 0% +00010101111: 0% +00010110000: 0% +00010110001: 0% +00010110010: 0% +00010110011: 0% +00010110100: 0% +00010110101: 0% +00010110110: 0% +00010110111: 0% +00010111000: 0% +00010111001: 0% +00010111010: 0% +00010111011: 0% +00010111100: 0% +00010111101: 0% +00010111110: 0% +00010111111: 0% +00011000000: 0% +00011000001: 0% +00011000010: 0% +00011000011: 0% +00011000100: 0% +00011000101: 0% +00011000110: 0% +00011000111: 0% +00011001000: 0% +00011001001: 0% +00011001010: 0% +00011001011: 0% +00011001100: 0% +00011001101: 0% +00011001110: 0% +00011001111: 0% +00011010000: 0% +00011010001: 0% +00011010010: 0% +00011010011: 0% +00011010100: 0% +00011010101: 0% +00011010110: 0% +00011010111: 0% +00011011000: 0% +00011011001: 0% +00011011010: 0% +00011011011: 0% +00011011100: 0% +00011011101: 0% +00011011110: 0% +00011011111: 0% +00011100000: 0% +00011100001: 0% +00011100010: 0% +00011100011: 0% +00011100100: 0% +00011100101: 0% +00011100110: 0% +00011100111: 0% +00011101000: 0% +00011101001: 0% +00011101010: 0% +00011101011: 0% +00011101100: 0% +00011101101: 0% +00011101110: 0% +00011101111: 0% +00011110000: 0% +00011110001: 0% +00011110010: 0% +00011110011: 0% +00011110100: 0% +00011110101: 0% +00011110110: 0% +00011110111: 0% +00011111000: 0% +00011111001: 0% +00011111010: 0% +00011111011: 0% +00011111100: 0% +00011111101: 0% +00011111110: 0% +00011111111: 0% +00100000000: 0% +00100000001: 0% +00100000010: 0% +00100000011: 0% +00100000100: 0% +00100000101: 0% +00100000110: 0% +00100000111: 0% +00100001000: 0% +00100001001: 0% +00100001010: 0% +00100001011: 0% +00100001100: 0% +00100001101: 0% +00100001110: 0% +00100001111: 0% +00100010000: 0% +00100010001: 0% +00100010010: 0% +00100010011: 0% +00100010100: 0% +00100010101: 0% +00100010110: 0% +00100010111: 0% +00100011000: 0% +00100011001: 0% +00100011010: 0% +00100011011: 0% +00100011100: 0% +00100011101: 0% +00100011110: 0% +00100011111: 0% +00100100000: 0% +00100100001: 0% +00100100010: 0% +00100100011: 0% +00100100100: 0% +00100100101: 0% +00100100110: 0% +00100100111: 0% +00100101000: 0% +00100101001: 0% +00100101010: 0% +00100101011: 0% +00100101100: 0% +00100101101: 0% +00100101110: 0% +00100101111: 0% +00100110000: 0% +00100110001: 0% +00100110010: 0% +00100110011: 0% +00100110100: 0% +00100110101: 0% +00100110110: 0% +00100110111: 0% +00100111000: 0% +00100111001: 0% +00100111010: 0% +00100111011: 0% +00100111100: 0% +00100111101: 0% +00100111110: 0% +00100111111: 0% +00101000000: 0% +00101000001: 0% +00101000010: 0% +00101000011: 0% +00101000100: 0% +00101000101: 0% +00101000110: 0% +00101000111: 0% +00101001000: 0% +00101001001: 0% +00101001010: 0% +00101001011: 0% +00101001100: 0% +00101001101: 0% +00101001110: 0% +00101001111: 0% +00101010000: 0% +00101010001: 0% +00101010010: 0% +00101010011: 0% +00101010100: 0% +00101010101: 0% +00101010110: 0% +00101010111: 0% +00101011000: 0% +00101011001: 0% +00101011010: 0% +00101011011: 0% +00101011100: 0% +00101011101: 0% +00101011110: 0% +00101011111: 0% +00101100000: 0% +00101100001: 0% +00101100010: 0% +00101100011: 0% +00101100100: 0% +00101100101: 0% +00101100110: 0% +00101100111: 0% +00101101000: 0% +00101101001: 0% +00101101010: 0% +00101101011: 0% +00101101100: 0% +00101101101: 0% +00101101110: 0% +00101101111: 0% +00101110000: 0% +00101110001: 0% +00101110010: 0% +00101110011: 0% +00101110100: 0% +00101110101: 0% +00101110110: 0% +00101110111: 0% +00101111000: 0% +00101111001: 0% +00101111010: 0% +00101111011: 0% +00101111100: 0% +00101111101: 0% +00101111110: 0% +00101111111: 0% +00110000000: 0% +00110000001: 0% +00110000010: 0% +00110000011: 0% +00110000100: 0% +00110000101: 0% +00110000110: 0% +00110000111: 0% +00110001000: 0% +00110001001: 0% +00110001010: 0% +00110001011: 0% +00110001100: 0% +00110001101: 0% +00110001110: 0% +00110001111: 0% +00110010000: 0% +00110010001: 0% +00110010010: 0% +00110010011: 0% +00110010100: 0% +00110010101: 0% +00110010110: 0% +00110010111: 0% +00110011000: 0% +00110011001: 0% +00110011010: 0% +00110011011: 0% +00110011100: 0% +00110011101: 0% +00110011110: 0% +00110011111: 0% +00110100000: 0% +00110100001: 0% +00110100010: 0% +00110100011: 0% +00110100100: 0% +00110100101: 0% +00110100110: 0% +00110100111: 0% +00110101000: 0% +00110101001: 0% +00110101010: 0% +00110101011: 0% +00110101100: 0% +00110101101: 0% +00110101110: 0% +00110101111: 0% +00110110000: 0% +00110110001: 0% +00110110010: 0% +00110110011: 0% +00110110100: 0% +00110110101: 0% +00110110110: 0% +00110110111: 0% +00110111000: 0% +00110111001: 0% +00110111010: 0% +00110111011: 0% +00110111100: 0% +00110111101: 0% +00110111110: 0% +00110111111: 0% +00111000000: 0% +00111000001: 0% +00111000010: 0% +00111000011: 0% +00111000100: 0% +00111000101: 0% +00111000110: 0% +00111000111: 0% +00111001000: 0% +00111001001: 0% +00111001010: 0% +00111001011: 0% +00111001100: 0% +00111001101: 0% +00111001110: 0% +00111001111: 0% +00111010000: 0% +00111010001: 0% +00111010010: 0% +00111010011: 0% +00111010100: 0% +00111010101: 0% +00111010110: 0% +00111010111: 0% +00111011000: 0% +00111011001: 0% +00111011010: 0% +00111011011: 0% +00111011100: 0% +00111011101: 0% +00111011110: 0% +00111011111: 0% +00111100000: 0% +00111100001: 0% +00111100010: 0% +00111100011: 0% +00111100100: 0% +00111100101: 0% +00111100110: 0% +00111100111: 0% +00111101000: 0% +00111101001: 0% +00111101010: 0% +00111101011: 0% +00111101100: 0% +00111101101: 0% +00111101110: 0% +00111101111: 0% +00111110000: 0% +00111110001: 0% +00111110010: 0% +00111110011: 0% +00111110100: 0% +00111110101: 0% +00111110110: 0% +00111110111: 0% +00111111000: 0% +00111111001: 0% +00111111010: 0% +00111111011: 0% +00111111100: 0% +00111111101: 0% +00111111110: 0% +00111111111: 0% +01000000000: 0% +01000000001: 0% +01000000010: 0% +01000000011: 0% +01000000100: 0% +01000000101: 0% +01000000110: 0% +01000000111: 0% +01000001000: 0% +01000001001: 0% +01000001010: 0% +01000001011: 0% +01000001100: 0% +01000001101: 0% +01000001110: 0% +01000001111: 0% +01000010000: 0% +01000010001: 0% +01000010010: 0% +01000010011: 0% +01000010100: 0% +01000010101: 0% +01000010110: 0% +01000010111: 0% +01000011000: 0% +01000011001: 0% +01000011010: 0% +01000011011: 0% +01000011100: 0% +01000011101: 0% +01000011110: 0% +01000011111: 0% +01000100000: 0% +01000100001: 0% +01000100010: 0% +01000100011: 0% +01000100100: 0% +01000100101: 0% +01000100110: 0% +01000100111: 0% +01000101000: 0% +01000101001: 0% +01000101010: 0% +01000101011: 0% +01000101100: 0% +01000101101: 0% +01000101110: 0% +01000101111: 0% +01000110000: 0% +01000110001: 0% +01000110010: 0% +01000110011: 0% +01000110100: 0% +01000110101: 0% +01000110110: 0% +01000110111: 0% +01000111000: 0% +01000111001: 0% +01000111010: 0% +01000111011: 0% +01000111100: 0% +01000111101: 0% +01000111110: 0% +01000111111: 0% +01001000000: 0% +01001000001: 0% +01001000010: 0% +01001000011: 0% +01001000100: 0% +01001000101: 0% +01001000110: 0% +01001000111: 0% +01001001000: 0% +01001001001: 0% +01001001010: 0% +01001001011: 0% +01001001100: 0% +01001001101: 0% +01001001110: 0% +01001001111: 0% +01001010000: 0% +01001010001: 0% +01001010010: 0% +01001010011: 0% +01001010100: 0% +01001010101: 0% +01001010110: 0% +01001010111: 0% +01001011000: 0% +01001011001: 0% +01001011010: 0% +01001011011: 0% +01001011100: 0% +01001011101: 0% +01001011110: 0% +01001011111: 0% +01001100000: 0% +01001100001: 0% +01001100010: 0% +01001100011: 0% +01001100100: 0% +01001100101: 0% +01001100110: 0% +01001100111: 0% +01001101000: 0% +01001101001: 0% +01001101010: 0% +01001101011: 0% +01001101100: 0% +01001101101: 0% +01001101110: 0% +01001101111: 0% +01001110000: 0% +01001110001: 0% +01001110010: 0% +01001110011: 0% +01001110100: 0% +01001110101: 0% +01001110110: 0% +01001110111: 0% +01001111000: 0% +01001111001: 0% +01001111010: 0% +01001111011: 0% +01001111100: 0% +01001111101: 0% +01001111110: 0% +01001111111: 0% +01010000000: 0% +01010000001: 0% +01010000010: 0% +01010000011: 0% +01010000100: 0% +01010000101: 0% +01010000110: 0% +01010000111: 0% +01010001000: 0% +01010001001: 0% +01010001010: 0% +01010001011: 0% +01010001100: 0% +01010001101: 0% +01010001110: 0% +01010001111: 0% +01010010000: 0% +01010010001: 0% +01010010010: 0% +01010010011: 0% +01010010100: 0% +01010010101: 0% +01010010110: 0% +01010010111: 0% +01010011000: 0% +01010011001: 0% +01010011010: 0% +01010011011: 0% +01010011100: 0% +01010011101: 0% +01010011110: 0% +01010011111: 0% +01010100000: 0% +01010100001: 0% +01010100010: 0% +01010100011: 0% +01010100100: 0% +01010100101: 0% +01010100110: 0% +01010100111: 0% +01010101000: 0% +01010101001: 0% +01010101010: 0% +01010101011: 0% +01010101100: 0% +01010101101: 0% +01010101110: 0% +01010101111: 0% +01010110000: 0% +01010110001: 0% +01010110010: 0% +01010110011: 0% +01010110100: 0% +01010110101: 0% +01010110110: 0% +01010110111: 0% +01010111000: 0% +01010111001: 0% +01010111010: 0% +01010111011: 0% +01010111100: 0% +01010111101: 0% +01010111110: 0% +01010111111: 0% +01011000000: 0% +01011000001: 0% +01011000010: 0% +01011000011: 0% +01011000100: 0% +01011000101: 0% +01011000110: 0% +01011000111: 0% +01011001000: 0% +01011001001: 0% +01011001010: 0% +01011001011: 0% +01011001100: 0% +01011001101: 0% +01011001110: 0% +01011001111: 0% +01011010000: 0% +01011010001: 0% +01011010010: 0% +01011010011: 0% +01011010100: 0% +01011010101: 0% +01011010110: 0% +01011010111: 0% +01011011000: 0% +01011011001: 0% +01011011010: 0% +01011011011: 0% +01011011100: 0% +01011011101: 0% +01011011110: 0% +01011011111: 0% +01011100000: 0% +01011100001: 0% +01011100010: 0% +01011100011: 0% +01011100100: 0% +01011100101: 0% +01011100110: 0% +01011100111: 0% +01011101000: 0% +01011101001: 0% +01011101010: 0% +01011101011: 0% +01011101100: 0% +01011101101: 0% +01011101110: 0% +01011101111: 0% +01011110000: 0% +01011110001: 0% +01011110010: 0% +01011110011: 0% +01011110100: 0% +01011110101: 0% +01011110110: 0% +01011110111: 0% +01011111000: 0% +01011111001: 0% +01011111010: 0% +01011111011: 0% +01011111100: 0% +01011111101: 0% +01011111110: 0% +01011111111: 0% +01100000000: 0% +01100000001: 0% +01100000010: 0% +01100000011: 0% +01100000100: 0% +01100000101: 0% +01100000110: 0% +01100000111: 0% +01100001000: 0% +01100001001: 0% +01100001010: 0% +01100001011: 0% +01100001100: 0% +01100001101: 0% +01100001110: 0% +01100001111: 0% +01100010000: 0% +01100010001: 0% +01100010010: 0% +01100010011: 0% +01100010100: 0% +01100010101: 0% +01100010110: 0% +01100010111: 0% +01100011000: 0% +01100011001: 0% +01100011010: 0% +01100011011: 0% +01100011100: 0% +01100011101: 0% +01100011110: 0% +01100011111: 0% +01100100000: 0% +01100100001: 0% +01100100010: 0% +01100100011: 0% +01100100100: 0% +01100100101: 0% +01100100110: 0% +01100100111: 0% +01100101000: 0% +01100101001: 0% +01100101010: 0% +01100101011: 0% +01100101100: 0% +01100101101: 0% +01100101110: 0% +01100101111: 0% +01100110000: 0% +01100110001: 0% +01100110010: 0% +01100110011: 0% +01100110100: 0% +01100110101: 0% +01100110110: 0% +01100110111: 0% +01100111000: 0% +01100111001: 0% +01100111010: 0% +01100111011: 0% +01100111100: 0% +01100111101: 0% +01100111110: 0% +01100111111: 0% +01101000000: 0% +01101000001: 0% +01101000010: 0% +01101000011: 0% +01101000100: 0% +01101000101: 0% +01101000110: 0% +01101000111: 0% +01101001000: 0% +01101001001: 0% +01101001010: 0% +01101001011: 0% +01101001100: 0% +01101001101: 0% +01101001110: 0% +01101001111: 0% +01101010000: 0% +01101010001: 0% +01101010010: 0% +01101010011: 0% +01101010100: 0% +01101010101: 0% +01101010110: 0% +01101010111: 0% +01101011000: 0% +01101011001: 0% +01101011010: 0% +01101011011: 0% +01101011100: 0% +01101011101: 0% +01101011110: 0% +01101011111: 0% +01101100000: 0% +01101100001: 0% +01101100010: 0% +01101100011: 0% +01101100100: 0% +01101100101: 0% +01101100110: 0% +01101100111: 0% +01101101000: 0% +01101101001: 0% +01101101010: 0% +01101101011: 0% +01101101100: 0% +01101101101: 0% +01101101110: 0% +01101101111: 0% +01101110000: 0% +01101110001: 0% +01101110010: 0% +01101110011: 0% +01101110100: 0% +01101110101: 0% +01101110110: 0% +01101110111: 0% +01101111000: 0% +01101111001: 0% +01101111010: 0% +01101111011: 0% +01101111100: 0% +01101111101: 0% +01101111110: 0% +01101111111: 0% +01110000000: 0% +01110000001: 0% +01110000010: 0% +01110000011: 0% +01110000100: 0% +01110000101: 0% +01110000110: 0% +01110000111: 0% +01110001000: 0% +01110001001: 0% +01110001010: 0% +01110001011: 0% +01110001100: 0% +01110001101: 0% +01110001110: 0% +01110001111: 0% +01110010000: 0% +01110010001: 0% +01110010010: 0% +01110010011: 0% +01110010100: 0% +01110010101: 0% +01110010110: 0% +01110010111: 0% +01110011000: 0% +01110011001: 0% +01110011010: 0% +01110011011: 0% +01110011100: 0% +01110011101: 0% +01110011110: 0% +01110011111: 0% +01110100000: 0% +01110100001: 0% +01110100010: 0% +01110100011: 0% +01110100100: 0% +01110100101: 0% +01110100110: 0% +01110100111: 0% +01110101000: 0% +01110101001: 0% +01110101010: 0% +01110101011: 0% +01110101100: 0% +01110101101: 0% +01110101110: 0% +01110101111: 0% +01110110000: 0% +01110110001: 0% +01110110010: 0% +01110110011: 0% +01110110100: 0% +01110110101: 0% +01110110110: 0% +01110110111: 0% +01110111000: 0% +01110111001: 0% +01110111010: 0% +01110111011: 0% +01110111100: 0% +01110111101: 0% +01110111110: 0% +01110111111: 0% +01111000000: 0% +01111000001: 0% +01111000010: 0% +01111000011: 0% +01111000100: 0% +01111000101: 0% +01111000110: 0% +01111000111: 0% +01111001000: 0% +01111001001: 0% +01111001010: 0% +01111001011: 0% +01111001100: 0% +01111001101: 0% +01111001110: 0% +01111001111: 0% +01111010000: 0% +01111010001: 0% +01111010010: 0% +01111010011: 0% +01111010100: 0% +01111010101: 0% +01111010110: 0% +01111010111: 0% +01111011000: 0% +01111011001: 0% +01111011010: 0% +01111011011: 0% +01111011100: 0% +01111011101: 0% +01111011110: 0% +01111011111: 0% +01111100000: 0% +01111100001: 0% +01111100010: 0% +01111100011: 0% +01111100100: 0% +01111100101: 0% +01111100110: 0% +01111100111: 0% +01111101000: 0% +01111101001: 0% +01111101010: 0% +01111101011: 0% +01111101100: 0% +01111101101: 0% +01111101110: 0% +01111101111: 0% +01111110000: 0% +01111110001: 0% +01111110010: 0% +01111110011: 0% +01111110100: 0% +01111110101: 0% +01111110110: 0% +01111110111: 0% +01111111000: 0% +01111111001: 0% +01111111010: 0% +01111111011: 0% +01111111100: 0% +01111111101: 0% +01111111110: 0% +01111111111: 0% +10000000000: 0% +10000000001: 0% +10000000010: 0% +10000000011: 0% +10000000100: 0% +10000000101: 0% +10000000110: 0% +10000000111: 0% +10000001000: 0% +10000001001: 0% +10000001010: 0% +10000001011: 0% +10000001100: 0% +10000001101: 0% +10000001110: 0% +10000001111: 0% +10000010000: 0% +10000010001: 0% +10000010010: 0% +10000010011: 0% +10000010100: 0% +10000010101: 0% +10000010110: 0% +10000010111: 0% +10000011000: 0% +10000011001: 0% +10000011010: 0% +10000011011: 0% +10000011100: 0% +10000011101: 0% +10000011110: 0% +10000011111: 0% +10000100000: 0% +10000100001: 0% +10000100010: 0% +10000100011: 0% +10000100100: 0% +10000100101: 0% +10000100110: 0% +10000100111: 0% +10000101000: 0% +10000101001: 0% +10000101010: 0% +10000101011: 0% +10000101100: 0% +10000101101: 0% +10000101110: 0% +10000101111: 0% +10000110000: 0% +10000110001: 0% +10000110010: 0% +10000110011: 0% +10000110100: 0% +10000110101: 0% +10000110110: 0% +10000110111: 0% +10000111000: 0% +10000111001: 0% +10000111010: 0% +10000111011: 0% +10000111100: 0% +10000111101: 0% +10000111110: 0% +10000111111: 0% +10001000000: 0% +10001000001: 0% +10001000010: 0% +10001000011: 0% +10001000100: 0% +10001000101: 0% +10001000110: 0% +10001000111: 0% +10001001000: 0% +10001001001: 0% +10001001010: 0% +10001001011: 0% +10001001100: 0% +10001001101: 0% +10001001110: 0% +10001001111: 0% +10001010000: 0% +10001010001: 0% +10001010010: 0% +10001010011: 0% +10001010100: 0% +10001010101: 0% +10001010110: 0% +10001010111: 0% +10001011000: 0% +10001011001: 0% +10001011010: 0% +10001011011: 0% +10001011100: 0% +10001011101: 0% +10001011110: 0% +10001011111: 0% +10001100000: 0% +10001100001: 0% +10001100010: 0% +10001100011: 0% +10001100100: 0% +10001100101: 0% +10001100110: 0% +10001100111: 0% +10001101000: 0% +10001101001: 0% +10001101010: 0% +10001101011: 0% +10001101100: 0% +10001101101: 0% +10001101110: 0% +10001101111: 0% +10001110000: 0% +10001110001: 0% +10001110010: 0% +10001110011: 0% +10001110100: 0% +10001110101: 0% +10001110110: 0% +10001110111: 0% +10001111000: 0% +10001111001: 0% +10001111010: 0% +10001111011: 0% +10001111100: 0% +10001111101: 0% +10001111110: 0% +10001111111: 0% +10010000000: 0% +10010000001: 0% +10010000010: 0% +10010000011: 0% +10010000100: 0% +10010000101: 0% +10010000110: 0% +10010000111: 0% +10010001000: 0% +10010001001: 0% +10010001010: 0% +10010001011: 0% +10010001100: 0% +10010001101: 0% +10010001110: 0% +10010001111: 0% +10010010000: 0% +10010010001: 0% +10010010010: 0% +10010010011: 0% +10010010100: 0% +10010010101: 0% +10010010110: 0% +10010010111: 0% +10010011000: 0% +10010011001: 0% +10010011010: 0% +10010011011: 0% +10010011100: 0% +10010011101: 0% +10010011110: 0% +10010011111: 0% +10010100000: 0% +10010100001: 0% +10010100010: 0% +10010100011: 0% +10010100100: 0% +10010100101: 0% +10010100110: 0% +10010100111: 0% +10010101000: 0% +10010101001: 0% +10010101010: 0% +10010101011: 0% +10010101100: 0% +10010101101: 0% +10010101110: 0% +10010101111: 0% +10010110000: 0% +10010110001: 0% +10010110010: 0% +10010110011: 0% +10010110100: 0% +10010110101: 0% +10010110110: 0% +10010110111: 0% +10010111000: 0% +10010111001: 0% +10010111010: 0% +10010111011: 0% +10010111100: 0% +10010111101: 0% +10010111110: 0% +10010111111: 0% +10011000000: 0% +10011000001: 0% +10011000010: 0% +10011000011: 0% +10011000100: 0% +10011000101: 0% +10011000110: 0% +10011000111: 0% +10011001000: 0% +10011001001: 0% +10011001010: 0% +10011001011: 0% +10011001100: 0% +10011001101: 0% +10011001110: 0% +10011001111: 0% +10011010000: 0% +10011010001: 0% +10011010010: 0% +10011010011: 0% +10011010100: 0% +10011010101: 0% +10011010110: 0% +10011010111: 0% +10011011000: 0% +10011011001: 0% +10011011010: 0% +10011011011: 0% +10011011100: 0% +10011011101: 0% +10011011110: 0% +10011011111: 0% +10011100000: 0% +10011100001: 0% +10011100010: 0% +10011100011: 0% +10011100100: 0% +10011100101: 0% +10011100110: 0% +10011100111: 0% +10011101000: 0% +10011101001: 0% +10011101010: 0% +10011101011: 0% +10011101100: 0% +10011101101: 0% +10011101110: 0% +10011101111: 0% +10011110000: 0% +10011110001: 0% +10011110010: 0% +10011110011: 0% +10011110100: 0% +10011110101: 0% +10011110110: 0% +10011110111: 0% +10011111000: 0% +10011111001: 0% +10011111010: 0% +10011111011: 0% +10011111100: 0% +10011111101: 0% +10011111110: 0% +10011111111: 0% +10100000000: 0% +10100000001: 0% +10100000010: 0% +10100000011: 0% +10100000100: 0% +10100000101: 0% +10100000110: 0% +10100000111: 0% +10100001000: 0% +10100001001: 0% +10100001010: 0% +10100001011: 0% +10100001100: 0% +10100001101: 0% +10100001110: 0% +10100001111: 0% +10100010000: 0% +10100010001: 0% +10100010010: 0% +10100010011: 0% +10100010100: 0% +10100010101: 0% +10100010110: 0% +10100010111: 0% +10100011000: 0% +10100011001: 0% +10100011010: 0% +10100011011: 0% +10100011100: 0% +10100011101: 0% +10100011110: 0% +10100011111: 0% +10100100000: 0% +10100100001: 0% +10100100010: 0% +10100100011: 0% +10100100100: 0% +10100100101: 0% +10100100110: 0% +10100100111: 0% +10100101000: 0% +10100101001: 0% +10100101010: 0% +10100101011: 0% +10100101100: 0% +10100101101: 0% +10100101110: 0% +10100101111: 0% +10100110000: 0% +10100110001: 0% +10100110010: 0% +10100110011: 0% +10100110100: 0% +10100110101: 0% +10100110110: 0% +10100110111: 0% +10100111000: 0% +10100111001: 0% +10100111010: 0% +10100111011: 0% +10100111100: 0% +10100111101: 0% +10100111110: 0% +10100111111: 0% +10101000000: 0% +10101000001: 0% +10101000010: 0% +10101000011: 0% +10101000100: 0% +10101000101: 0% +10101000110: 0% +10101000111: 0% +10101001000: 0% +10101001001: 0% +10101001010: 0% +10101001011: 0% +10101001100: 0% +10101001101: 0% +10101001110: 0% +10101001111: 0% +10101010000: 0% +10101010001: 0% +10101010010: 0% +10101010011: 0% +10101010100: 0% +10101010101: 0% +10101010110: 0% +10101010111: 0% +10101011000: 0% +10101011001: 0% +10101011010: 0% +10101011011: 0% +10101011100: 0% +10101011101: 0% +10101011110: 0% +10101011111: 0% +10101100000: 0% +10101100001: 0% +10101100010: 0% +10101100011: 0% +10101100100: 0% +10101100101: 0% +10101100110: 0% +10101100111: 0% +10101101000: 0% +10101101001: 0% +10101101010: 0% +10101101011: 0% +10101101100: 0% +10101101101: 0% +10101101110: 0% +10101101111: 0% +10101110000: 0% +10101110001: 0% +10101110010: 0% +10101110011: 0% +10101110100: 0% +10101110101: 0% +10101110110: 0% +10101110111: 0% +10101111000: 0% +10101111001: 0% +10101111010: 0% +10101111011: 0% +10101111100: 0% +10101111101: 0% +10101111110: 0% +10101111111: 0% +10110000000: 0% +10110000001: 0% +10110000010: 0% +10110000011: 0% +10110000100: 0% +10110000101: 0% +10110000110: 0% +10110000111: 0% +10110001000: 0% +10110001001: 0% +10110001010: 0% +10110001011: 0% +10110001100: 0% +10110001101: 0% +10110001110: 0% +10110001111: 0% +10110010000: 0% +10110010001: 0% +10110010010: 0% +10110010011: 0% +10110010100: 0% +10110010101: 0% +10110010110: 0% +10110010111: 0% +10110011000: 0% +10110011001: 0% +10110011010: 0% +10110011011: 0% +10110011100: 0% +10110011101: 0% +10110011110: 0% +10110011111: 0% +10110100000: 0% +10110100001: 0% +10110100010: 0% +10110100011: 0% +10110100100: 0% +10110100101: 0% +10110100110: 0% +10110100111: 0% +10110101000: 0% +10110101001: 0% +10110101010: 0% +10110101011: 0% +10110101100: 0% +10110101101: 0% +10110101110: 0% +10110101111: 0% +10110110000: 0% +10110110001: 0% +10110110010: 0% +10110110011: 0% +10110110100: 0% +10110110101: 0% +10110110110: 0% +10110110111: 0% +10110111000: 0% +10110111001: 0% +10110111010: 0% +10110111011: 0% +10110111100: 0% +10110111101: 0% +10110111110: 0% +10110111111: 0% +10111000000: 0% +10111000001: 0% +10111000010: 0% +10111000011: 0% +10111000100: 0% +10111000101: 0% +10111000110: 0% +10111000111: 0% +10111001000: 0% +10111001001: 0% +10111001010: 0% +10111001011: 0% +10111001100: 0% +10111001101: 0% +10111001110: 0% +10111001111: 0% +10111010000: 0% +10111010001: 0% +10111010010: 0% +10111010011: 0% +10111010100: 0% +10111010101: 0% +10111010110: 0% +10111010111: 0% +10111011000: 0% +10111011001: 0% +10111011010: 0% +10111011011: 0% +10111011100: 0% +10111011101: 0% +10111011110: 0% +10111011111: 0% +10111100000: 0% +10111100001: 0% +10111100010: 0% +10111100011: 0% +10111100100: 0% +10111100101: 0% +10111100110: 0% +10111100111: 0% +10111101000: 0% +10111101001: 0% +10111101010: 0% +10111101011: 0% +10111101100: 0% +10111101101: 0% +10111101110: 0% +10111101111: 0% +10111110000: 0% +10111110001: 0% +10111110010: 0% +10111110011: 0% +10111110100: 0% +10111110101: 0% +10111110110: 0% +10111110111: 0% +10111111000: 0% +10111111001: 0% +10111111010: 0% +10111111011: 0% +10111111100: 0% +10111111101: 0% +10111111110: 0% +10111111111: 0% +11000000000: 0% +11000000001: 0% +11000000010: 0% +11000000011: 0% +11000000100: 0% +11000000101: 0% +11000000110: 0% +11000000111: 0% +11000001000: 0% +11000001001: 0% +11000001010: 0% +11000001011: 0% +11000001100: 0% +11000001101: 0% +11000001110: 0% +11000001111: 0% +11000010000: 0% +11000010001: 0% +11000010010: 0% +11000010011: 0% +11000010100: 0% +11000010101: 0% +11000010110: 0% +11000010111: 0% +11000011000: 0% +11000011001: 0% +11000011010: 0% +11000011011: 0% +11000011100: 0% +11000011101: 0% +11000011110: 0% +11000011111: 0% +11000100000: 0% +11000100001: 0% +11000100010: 0% +11000100011: 0% +11000100100: 0% +11000100101: 0% +11000100110: 0% +11000100111: 0% +11000101000: 0% +11000101001: 0% +11000101010: 0% +11000101011: 0% +11000101100: 0% +11000101101: 0% +11000101110: 0% +11000101111: 0% +11000110000: 0% +11000110001: 0% +11000110010: 0% +11000110011: 0% +11000110100: 0% +11000110101: 0% +11000110110: 0% +11000110111: 0% +11000111000: 0% +11000111001: 0% +11000111010: 0% +11000111011: 0% +11000111100: 0% +11000111101: 0% +11000111110: 0% +11000111111: 0% +11001000000: 0% +11001000001: 0% +11001000010: 0% +11001000011: 0% +11001000100: 0% +11001000101: 0% +11001000110: 0% +11001000111: 0% +11001001000: 0% +11001001001: 0% +11001001010: 0% +11001001011: 0% +11001001100: 0% +11001001101: 0% +11001001110: 0% +11001001111: 0% +11001010000: 0% +11001010001: 0% +11001010010: 0% +11001010011: 0% +11001010100: 0% +11001010101: 0% +11001010110: 0% +11001010111: 0% +11001011000: 0% +11001011001: 0% +11001011010: 0% +11001011011: 0% +11001011100: 0% +11001011101: 0% +11001011110: 0% +11001011111: 0% +11001100000: 0% +11001100001: 0% +11001100010: 0% +11001100011: 0% +11001100100: 0% +11001100101: 0% +11001100110: 0% +11001100111: 0% +11001101000: 0% +11001101001: 0% +11001101010: 0% +11001101011: 0% +11001101100: 0% +11001101101: 0% +11001101110: 0% +11001101111: 0% +11001110000: 0% +11001110001: 0% +11001110010: 0% +11001110011: 0% +11001110100: 0% +11001110101: 0% +11001110110: 0% +11001110111: 0% +11001111000: 0% +11001111001: 0% +11001111010: 0% +11001111011: 0% +11001111100: 0% +11001111101: 0% +11001111110: 0% +11001111111: 0% +11010000000: 0% +11010000001: 0% +11010000010: 0% +11010000011: 0% +11010000100: 0% +11010000101: 0% +11010000110: 0% +11010000111: 0% +11010001000: 0% +11010001001: 0% +11010001010: 0% +11010001011: 0% +11010001100: 0% +11010001101: 0% +11010001110: 0% +11010001111: 0% +11010010000: 0% +11010010001: 0% +11010010010: 0% +11010010011: 0% +11010010100: 0% +11010010101: 0% +11010010110: 0% +11010010111: 0% +11010011000: 0% +11010011001: 0% +11010011010: 0% +11010011011: 0% +11010011100: 0% +11010011101: 0% +11010011110: 0% +11010011111: 0% +11010100000: 0% +11010100001: 0% +11010100010: 0% +11010100011: 0% +11010100100: 0% +11010100101: 0% +11010100110: 0% +11010100111: 0% +11010101000: 0% +11010101001: 0% +11010101010: 0% +11010101011: 0% +11010101100: 0% +11010101101: 0% +11010101110: 0% +11010101111: 0% +11010110000: 0% +11010110001: 0% +11010110010: 0% +11010110011: 0% +11010110100: 0% +11010110101: 0% +11010110110: 0% +11010110111: 0% +11010111000: 0% +11010111001: 0% +11010111010: 0% +11010111011: 0% +11010111100: 0% +11010111101: 0% +11010111110: 0% +11010111111: 0% +11011000000: 0% +11011000001: 0% +11011000010: 0% +11011000011: 0% +11011000100: 0% +11011000101: 0% +11011000110: 0% +11011000111: 0% +11011001000: 0% +11011001001: 0% +11011001010: 0% +11011001011: 0% +11011001100: 0% +11011001101: 0% +11011001110: 0% +11011001111: 0% +11011010000: 0% +11011010001: 0% +11011010010: 0% +11011010011: 0% +11011010100: 0% +11011010101: 0% +11011010110: 0% +11011010111: 0% +11011011000: 0% +11011011001: 0% +11011011010: 0% +11011011011: 0% +11011011100: 0% +11011011101: 0% +11011011110: 0% +11011011111: 0% +11011100000: 0% +11011100001: 0% +11011100010: 0% +11011100011: 0% +11011100100: 0% +11011100101: 0% +11011100110: 0% +11011100111: 0% +11011101000: 0% +11011101001: 0% +11011101010: 0% +11011101011: 0% +11011101100: 0% +11011101101: 0% +11011101110: 0% +11011101111: 0% +11011110000: 0% +11011110001: 0% +11011110010: 0% +11011110011: 0% +11011110100: 0% +11011110101: 0% +11011110110: 0% +11011110111: 0% +11011111000: 0% +11011111001: 0% +11011111010: 0% +11011111011: 0% +11011111100: 0% +11011111101: 0% +11011111110: 0% +11011111111: 0% +11100000000: 0% +11100000001: 0% +11100000010: 0% +11100000011: 0% +11100000100: 0% +11100000101: 0% +11100000110: 0% +11100000111: 0% +11100001000: 0% +11100001001: 0% +11100001010: 0% +11100001011: 0% +11100001100: 0% +11100001101: 0% +11100001110: 0% +11100001111: 0% +11100010000: 0% +11100010001: 0% +11100010010: 0% +11100010011: 0% +11100010100: 0% +11100010101: 0% +11100010110: 0% +11100010111: 0% +11100011000: 0% +11100011001: 0% +11100011010: 0% +11100011011: 0% +11100011100: 0% +11100011101: 0% +11100011110: 0% +11100011111: 0% +11100100000: 0% +11100100001: 0% +11100100010: 0% +11100100011: 0% +11100100100: 0% +11100100101: 0% +11100100110: 0% +11100100111: 0% +11100101000: 0% +11100101001: 0% +11100101010: 0% +11100101011: 0% +11100101100: 0% +11100101101: 0% +11100101110: 0% +11100101111: 0% +11100110000: 0% +11100110001: 0% +11100110010: 0% +11100110011: 0% +11100110100: 0% +11100110101: 0% +11100110110: 0% +11100110111: 0% +11100111000: 0% +11100111001: 0% +11100111010: 0% +11100111011: 0% +11100111100: 0% +11100111101: 0% +11100111110: 0% +11100111111: 0% +11101000000: 0% +11101000001: 0% +11101000010: 0% +11101000011: 0% +11101000100: 0% +11101000101: 0% +11101000110: 0% +11101000111: 0% +11101001000: 0% +11101001001: 0% +11101001010: 0% +11101001011: 0% +11101001100: 0% +11101001101: 0% +11101001110: 0% +11101001111: 0% +11101010000: 0% +11101010001: 0% +11101010010: 0% +11101010011: 0% +11101010100: 0% +11101010101: 0% +11101010110: 0% +11101010111: 0% +11101011000: 0% +11101011001: 0% +11101011010: 0% +11101011011: 0% +11101011100: 0% +11101011101: 0% +11101011110: 0% +11101011111: 0% +11101100000: 0% +11101100001: 0% +11101100010: 0% +11101100011: 0% +11101100100: 0% +11101100101: 0% +11101100110: 0% +11101100111: 0% +11101101000: 0% +11101101001: 0% +11101101010: 0% +11101101011: 0% +11101101100: 0% +11101101101: 0% +11101101110: 0% +11101101111: 0% +11101110000: 0% +11101110001: 0% +11101110010: 0% +11101110011: 0% +11101110100: 0% +11101110101: 0% +11101110110: 0% +11101110111: 0% +11101111000: 0% +11101111001: 0% +11101111010: 0% +11101111011: 0% +11101111100: 0% +11101111101: 0% +11101111110: 0% +11101111111: 0% +11110000000: 0% +11110000001: 0% +11110000010: 0% +11110000011: 0% +11110000100: 0% +11110000101: 0% +11110000110: 0% +11110000111: 0% +11110001000: 0% +11110001001: 0% +11110001010: 0% +11110001011: 0% +11110001100: 0% +11110001101: 0% +11110001110: 0% +11110001111: 0% +11110010000: 0% +11110010001: 0% +11110010010: 0% +11110010011: 0% +11110010100: 0% +11110010101: 0% +11110010110: 0% +11110010111: 0% +11110011000: 0% +11110011001: 0% +11110011010: 0% +11110011011: 0% +11110011100: 0% +11110011101: 0% +11110011110: 0% +11110011111: 0% +11110100000: 0% +11110100001: 0% +11110100010: 0% +11110100011: 0% +11110100100: 0% +11110100101: 0% +11110100110: 0% +11110100111: 0% +11110101000: 0% +11110101001: 0% +11110101010: 0% +11110101011: 0% +11110101100: 0% +11110101101: 0% +11110101110: 0% +11110101111: 0% +11110110000: 0% +11110110001: 0% +11110110010: 0% +11110110011: 0% +11110110100: 0% +11110110101: 0% +11110110110: 0% +11110110111: 0% +11110111000: 0% +11110111001: 0% +11110111010: 0% +11110111011: 0% +11110111100: 0% +11110111101: 0% +11110111110: 0% +11110111111: 0% +11111000000: 0% +11111000001: 0% +11111000010: 0% +11111000011: 0% +11111000100: 0% +11111000101: 0% +11111000110: 0% +11111000111: 0% +11111001000: 0% +11111001001: 0% +11111001010: 0% +11111001011: 0% +11111001100: 0% +11111001101: 0% +11111001110: 0% +11111001111: 0% +11111010000: 0% +11111010001: 0% +11111010010: 0% +11111010011: 0% +11111010100: 0% +11111010101: 0% +11111010110: 0% +11111010111: 0% +11111011000: 0% +11111011001: 0% +11111011010: 0% +11111011011: 0% +11111011100: 0% +11111011101: 0% +11111011110: 0% +11111011111: 0% +11111100000: 0% +11111100001: 0% +11111100010: 0% +11111100011: 0% +11111100100: 0% +11111100101: 0% +11111100110: 0% +11111100111: 0% +11111101000: 0% +11111101001: 0% +11111101010: 0% +11111101011: 0% +11111101100: 0% +11111101101: 0% +11111101110: 0% +11111101111: 0% +11111110000: 0% +11111110001: 0% +11111110010: 0% +11111110011: 0% +11111110100: 0% +11111110101: 0% +11111110110: 0% +11111110111: 0% +11111111000: 0% +11111111001: 0% +11111111010: 0% +11111111011: 0% +11111111100: 0% +11111111101: 0% +11111111110: 0% +11111111111: 0% diff --git a/po b/po new file mode 100644 index 0000000..4bd0fbc --- /dev/null +++ b/po @@ -0,0 +1,2048 @@ +00000000000: 12% +00000000001: 0% +00000000010: 12% +00000000011: 0% +00000000100: 12% +00000000101: 0% +00000000110: 12% +00000000111: 0% +00000001000: 12% +00000001001: 0% +00000001010: 12% +00000001011: 0% +00000001100: 12% +00000001101: 0% +00000001110: 12% +00000001111: 0% +00000010000: 0% +00000010001: 0% +00000010010: 0% +00000010011: 0% +00000010100: 0% +00000010101: 0% +00000010110: 0% +00000010111: 0% +00000011000: 0% +00000011001: 0% +00000011010: 0% +00000011011: 0% +00000011100: 0% +00000011101: 0% +00000011110: 0% +00000011111: 0% +00000100000: 0% +00000100001: 0% +00000100010: 0% +00000100011: 0% +00000100100: 0% +00000100101: 0% +00000100110: 0% +00000100111: 0% +00000101000: 0% +00000101001: 0% +00000101010: 0% +00000101011: 0% +00000101100: 0% +00000101101: 0% +00000101110: 0% +00000101111: 0% +00000110000: 0% +00000110001: 0% +00000110010: 0% +00000110011: 0% +00000110100: 0% +00000110101: 0% +00000110110: 0% +00000110111: 0% +00000111000: 0% +00000111001: 0% +00000111010: 0% +00000111011: 0% +00000111100: 0% +00000111101: 0% +00000111110: 0% +00000111111: 0% +00001000000: 0% +00001000001: 0% +00001000010: 0% +00001000011: 0% +00001000100: 0% +00001000101: 0% +00001000110: 0% +00001000111: 0% +00001001000: 0% +00001001001: 0% +00001001010: 0% +00001001011: 0% +00001001100: 0% +00001001101: 0% +00001001110: 0% +00001001111: 0% +00001010000: 0% +00001010001: 0% +00001010010: 0% +00001010011: 0% +00001010100: 0% +00001010101: 0% +00001010110: 0% +00001010111: 0% +00001011000: 0% +00001011001: 0% +00001011010: 0% +00001011011: 0% +00001011100: 0% +00001011101: 0% +00001011110: 0% +00001011111: 0% +00001100000: 0% +00001100001: 0% +00001100010: 0% +00001100011: 0% +00001100100: 0% +00001100101: 0% +00001100110: 0% +00001100111: 0% +00001101000: 0% +00001101001: 0% +00001101010: 0% +00001101011: 0% +00001101100: 0% +00001101101: 0% +00001101110: 0% +00001101111: 0% +00001110000: 0% +00001110001: 0% +00001110010: 0% +00001110011: 0% +00001110100: 0% +00001110101: 0% +00001110110: 0% +00001110111: 0% +00001111000: 0% +00001111001: 0% +00001111010: 0% +00001111011: 0% +00001111100: 0% +00001111101: 0% +00001111110: 0% +00001111111: 0% +00010000000: 0% +00010000001: 0% +00010000010: 0% +00010000011: 0% +00010000100: 0% +00010000101: 0% +00010000110: 0% +00010000111: 0% +00010001000: 0% +00010001001: 0% +00010001010: 0% +00010001011: 0% +00010001100: 0% +00010001101: 0% +00010001110: 0% +00010001111: 0% +00010010000: 0% +00010010001: 0% +00010010010: 0% +00010010011: 0% +00010010100: 0% +00010010101: 0% +00010010110: 0% +00010010111: 0% +00010011000: 0% +00010011001: 0% +00010011010: 0% +00010011011: 0% +00010011100: 0% +00010011101: 0% +00010011110: 0% +00010011111: 0% +00010100000: 0% +00010100001: 0% +00010100010: 0% +00010100011: 0% +00010100100: 0% +00010100101: 0% +00010100110: 0% +00010100111: 0% +00010101000: 0% +00010101001: 0% +00010101010: 0% +00010101011: 0% +00010101100: 0% +00010101101: 0% +00010101110: 0% +00010101111: 0% +00010110000: 0% +00010110001: 0% +00010110010: 0% +00010110011: 0% +00010110100: 0% +00010110101: 0% +00010110110: 0% +00010110111: 0% +00010111000: 0% +00010111001: 0% +00010111010: 0% +00010111011: 0% +00010111100: 0% +00010111101: 0% +00010111110: 0% +00010111111: 0% +00011000000: 0% +00011000001: 0% +00011000010: 0% +00011000011: 0% +00011000100: 0% +00011000101: 0% +00011000110: 0% +00011000111: 0% +00011001000: 0% +00011001001: 0% +00011001010: 0% +00011001011: 0% +00011001100: 0% +00011001101: 0% +00011001110: 0% +00011001111: 0% +00011010000: 0% +00011010001: 0% +00011010010: 0% +00011010011: 0% +00011010100: 0% +00011010101: 0% +00011010110: 0% +00011010111: 0% +00011011000: 0% +00011011001: 0% +00011011010: 0% +00011011011: 0% +00011011100: 0% +00011011101: 0% +00011011110: 0% +00011011111: 0% +00011100000: 0% +00011100001: 0% +00011100010: 0% +00011100011: 0% +00011100100: 0% +00011100101: 0% +00011100110: 0% +00011100111: 0% +00011101000: 0% +00011101001: 0% +00011101010: 0% +00011101011: 0% +00011101100: 0% +00011101101: 0% +00011101110: 0% +00011101111: 0% +00011110000: 0% +00011110001: 0% +00011110010: 0% +00011110011: 0% +00011110100: 0% +00011110101: 0% +00011110110: 0% +00011110111: 0% +00011111000: 0% +00011111001: 0% +00011111010: 0% +00011111011: 0% +00011111100: 0% +00011111101: 0% +00011111110: 0% +00011111111: 0% +00100000000: 0% +00100000001: 0% +00100000010: 0% +00100000011: 0% +00100000100: 0% +00100000101: 0% +00100000110: 0% +00100000111: 0% +00100001000: 0% +00100001001: 0% +00100001010: 0% +00100001011: 0% +00100001100: 0% +00100001101: 0% +00100001110: 0% +00100001111: 0% +00100010000: 0% +00100010001: 0% +00100010010: 0% +00100010011: 0% +00100010100: 0% +00100010101: 0% +00100010110: 0% +00100010111: 0% +00100011000: 0% +00100011001: 0% +00100011010: 0% +00100011011: 0% +00100011100: 0% +00100011101: 0% +00100011110: 0% +00100011111: 0% +00100100000: 0% +00100100001: 0% +00100100010: 0% +00100100011: 0% +00100100100: 0% +00100100101: 0% +00100100110: 0% +00100100111: 0% +00100101000: 0% +00100101001: 0% +00100101010: 0% +00100101011: 0% +00100101100: 0% +00100101101: 0% +00100101110: 0% +00100101111: 0% +00100110000: 0% +00100110001: 0% +00100110010: 0% +00100110011: 0% +00100110100: 0% +00100110101: 0% +00100110110: 0% +00100110111: 0% +00100111000: 0% +00100111001: 0% +00100111010: 0% +00100111011: 0% +00100111100: 0% +00100111101: 0% +00100111110: 0% +00100111111: 0% +00101000000: 0% +00101000001: 0% +00101000010: 0% +00101000011: 0% +00101000100: 0% +00101000101: 0% +00101000110: 0% +00101000111: 0% +00101001000: 0% +00101001001: 0% +00101001010: 0% +00101001011: 0% +00101001100: 0% +00101001101: 0% +00101001110: 0% +00101001111: 0% +00101010000: 0% +00101010001: 0% +00101010010: 0% +00101010011: 0% +00101010100: 0% +00101010101: 0% +00101010110: 0% +00101010111: 0% +00101011000: 0% +00101011001: 0% +00101011010: 0% +00101011011: 0% +00101011100: 0% +00101011101: 0% +00101011110: 0% +00101011111: 0% +00101100000: 0% +00101100001: 0% +00101100010: 0% +00101100011: 0% +00101100100: 0% +00101100101: 0% +00101100110: 0% +00101100111: 0% +00101101000: 0% +00101101001: 0% +00101101010: 0% +00101101011: 0% +00101101100: 0% +00101101101: 0% +00101101110: 0% +00101101111: 0% +00101110000: 0% +00101110001: 0% +00101110010: 0% +00101110011: 0% +00101110100: 0% +00101110101: 0% +00101110110: 0% +00101110111: 0% +00101111000: 0% +00101111001: 0% +00101111010: 0% +00101111011: 0% +00101111100: 0% +00101111101: 0% +00101111110: 0% +00101111111: 0% +00110000000: 0% +00110000001: 0% +00110000010: 0% +00110000011: 0% +00110000100: 0% +00110000101: 0% +00110000110: 0% +00110000111: 0% +00110001000: 0% +00110001001: 0% +00110001010: 0% +00110001011: 0% +00110001100: 0% +00110001101: 0% +00110001110: 0% +00110001111: 0% +00110010000: 0% +00110010001: 0% +00110010010: 0% +00110010011: 0% +00110010100: 0% +00110010101: 0% +00110010110: 0% +00110010111: 0% +00110011000: 0% +00110011001: 0% +00110011010: 0% +00110011011: 0% +00110011100: 0% +00110011101: 0% +00110011110: 0% +00110011111: 0% +00110100000: 0% +00110100001: 0% +00110100010: 0% +00110100011: 0% +00110100100: 0% +00110100101: 0% +00110100110: 0% +00110100111: 0% +00110101000: 0% +00110101001: 0% +00110101010: 0% +00110101011: 0% +00110101100: 0% +00110101101: 0% +00110101110: 0% +00110101111: 0% +00110110000: 0% +00110110001: 0% +00110110010: 0% +00110110011: 0% +00110110100: 0% +00110110101: 0% +00110110110: 0% +00110110111: 0% +00110111000: 0% +00110111001: 0% +00110111010: 0% +00110111011: 0% +00110111100: 0% +00110111101: 0% +00110111110: 0% +00110111111: 0% +00111000000: 0% +00111000001: 0% +00111000010: 0% +00111000011: 0% +00111000100: 0% +00111000101: 0% +00111000110: 0% +00111000111: 0% +00111001000: 0% +00111001001: 0% +00111001010: 0% +00111001011: 0% +00111001100: 0% +00111001101: 0% +00111001110: 0% +00111001111: 0% +00111010000: 0% +00111010001: 0% +00111010010: 0% +00111010011: 0% +00111010100: 0% +00111010101: 0% +00111010110: 0% +00111010111: 0% +00111011000: 0% +00111011001: 0% +00111011010: 0% +00111011011: 0% +00111011100: 0% +00111011101: 0% +00111011110: 0% +00111011111: 0% +00111100000: 0% +00111100001: 0% +00111100010: 0% +00111100011: 0% +00111100100: 0% +00111100101: 0% +00111100110: 0% +00111100111: 0% +00111101000: 0% +00111101001: 0% +00111101010: 0% +00111101011: 0% +00111101100: 0% +00111101101: 0% +00111101110: 0% +00111101111: 0% +00111110000: 0% +00111110001: 0% +00111110010: 0% +00111110011: 0% +00111110100: 0% +00111110101: 0% +00111110110: 0% +00111110111: 0% +00111111000: 0% +00111111001: 0% +00111111010: 0% +00111111011: 0% +00111111100: 0% +00111111101: 0% +00111111110: 0% +00111111111: 0% +01000000000: 0% +01000000001: 0% +01000000010: 0% +01000000011: 0% +01000000100: 0% +01000000101: 0% +01000000110: 0% +01000000111: 0% +01000001000: 0% +01000001001: 0% +01000001010: 0% +01000001011: 0% +01000001100: 0% +01000001101: 0% +01000001110: 0% +01000001111: 0% +01000010000: 0% +01000010001: 0% +01000010010: 0% +01000010011: 0% +01000010100: 0% +01000010101: 0% +01000010110: 0% +01000010111: 0% +01000011000: 0% +01000011001: 0% +01000011010: 0% +01000011011: 0% +01000011100: 0% +01000011101: 0% +01000011110: 0% +01000011111: 0% +01000100000: 0% +01000100001: 0% +01000100010: 0% +01000100011: 0% +01000100100: 0% +01000100101: 0% +01000100110: 0% +01000100111: 0% +01000101000: 0% +01000101001: 0% +01000101010: 0% +01000101011: 0% +01000101100: 0% +01000101101: 0% +01000101110: 0% +01000101111: 0% +01000110000: 0% +01000110001: 0% +01000110010: 0% +01000110011: 0% +01000110100: 0% +01000110101: 0% +01000110110: 0% +01000110111: 0% +01000111000: 0% +01000111001: 0% +01000111010: 0% +01000111011: 0% +01000111100: 0% +01000111101: 0% +01000111110: 0% +01000111111: 0% +01001000000: 0% +01001000001: 0% +01001000010: 0% +01001000011: 0% +01001000100: 0% +01001000101: 0% +01001000110: 0% +01001000111: 0% +01001001000: 0% +01001001001: 0% +01001001010: 0% +01001001011: 0% +01001001100: 0% +01001001101: 0% +01001001110: 0% +01001001111: 0% +01001010000: 0% +01001010001: 0% +01001010010: 0% +01001010011: 0% +01001010100: 0% +01001010101: 0% +01001010110: 0% +01001010111: 0% +01001011000: 0% +01001011001: 0% +01001011010: 0% +01001011011: 0% +01001011100: 0% +01001011101: 0% +01001011110: 0% +01001011111: 0% +01001100000: 0% +01001100001: 0% +01001100010: 0% +01001100011: 0% +01001100100: 0% +01001100101: 0% +01001100110: 0% +01001100111: 0% +01001101000: 0% +01001101001: 0% +01001101010: 0% +01001101011: 0% +01001101100: 0% +01001101101: 0% +01001101110: 0% +01001101111: 0% +01001110000: 0% +01001110001: 0% +01001110010: 0% +01001110011: 0% +01001110100: 0% +01001110101: 0% +01001110110: 0% +01001110111: 0% +01001111000: 0% +01001111001: 0% +01001111010: 0% +01001111011: 0% +01001111100: 0% +01001111101: 0% +01001111110: 0% +01001111111: 0% +01010000000: 0% +01010000001: 0% +01010000010: 0% +01010000011: 0% +01010000100: 0% +01010000101: 0% +01010000110: 0% +01010000111: 0% +01010001000: 0% +01010001001: 0% +01010001010: 0% +01010001011: 0% +01010001100: 0% +01010001101: 0% +01010001110: 0% +01010001111: 0% +01010010000: 0% +01010010001: 0% +01010010010: 0% +01010010011: 0% +01010010100: 0% +01010010101: 0% +01010010110: 0% +01010010111: 0% +01010011000: 0% +01010011001: 0% +01010011010: 0% +01010011011: 0% +01010011100: 0% +01010011101: 0% +01010011110: 0% +01010011111: 0% +01010100000: 0% +01010100001: 0% +01010100010: 0% +01010100011: 0% +01010100100: 0% +01010100101: 0% +01010100110: 0% +01010100111: 0% +01010101000: 0% +01010101001: 0% +01010101010: 0% +01010101011: 0% +01010101100: 0% +01010101101: 0% +01010101110: 0% +01010101111: 0% +01010110000: 0% +01010110001: 0% +01010110010: 0% +01010110011: 0% +01010110100: 0% +01010110101: 0% +01010110110: 0% +01010110111: 0% +01010111000: 0% +01010111001: 0% +01010111010: 0% +01010111011: 0% +01010111100: 0% +01010111101: 0% +01010111110: 0% +01010111111: 0% +01011000000: 0% +01011000001: 0% +01011000010: 0% +01011000011: 0% +01011000100: 0% +01011000101: 0% +01011000110: 0% +01011000111: 0% +01011001000: 0% +01011001001: 0% +01011001010: 0% +01011001011: 0% +01011001100: 0% +01011001101: 0% +01011001110: 0% +01011001111: 0% +01011010000: 0% +01011010001: 0% +01011010010: 0% +01011010011: 0% +01011010100: 0% +01011010101: 0% +01011010110: 0% +01011010111: 0% +01011011000: 0% +01011011001: 0% +01011011010: 0% +01011011011: 0% +01011011100: 0% +01011011101: 0% +01011011110: 0% +01011011111: 0% +01011100000: 0% +01011100001: 0% +01011100010: 0% +01011100011: 0% +01011100100: 0% +01011100101: 0% +01011100110: 0% +01011100111: 0% +01011101000: 0% +01011101001: 0% +01011101010: 0% +01011101011: 0% +01011101100: 0% +01011101101: 0% +01011101110: 0% +01011101111: 0% +01011110000: 0% +01011110001: 0% +01011110010: 0% +01011110011: 0% +01011110100: 0% +01011110101: 0% +01011110110: 0% +01011110111: 0% +01011111000: 0% +01011111001: 0% +01011111010: 0% +01011111011: 0% +01011111100: 0% +01011111101: 0% +01011111110: 0% +01011111111: 0% +01100000000: 0% +01100000001: 0% +01100000010: 0% +01100000011: 0% +01100000100: 0% +01100000101: 0% +01100000110: 0% +01100000111: 0% +01100001000: 0% +01100001001: 0% +01100001010: 0% +01100001011: 0% +01100001100: 0% +01100001101: 0% +01100001110: 0% +01100001111: 0% +01100010000: 0% +01100010001: 0% +01100010010: 0% +01100010011: 0% +01100010100: 0% +01100010101: 0% +01100010110: 0% +01100010111: 0% +01100011000: 0% +01100011001: 0% +01100011010: 0% +01100011011: 0% +01100011100: 0% +01100011101: 0% +01100011110: 0% +01100011111: 0% +01100100000: 0% +01100100001: 0% +01100100010: 0% +01100100011: 0% +01100100100: 0% +01100100101: 0% +01100100110: 0% +01100100111: 0% +01100101000: 0% +01100101001: 0% +01100101010: 0% +01100101011: 0% +01100101100: 0% +01100101101: 0% +01100101110: 0% +01100101111: 0% +01100110000: 0% +01100110001: 0% +01100110010: 0% +01100110011: 0% +01100110100: 0% +01100110101: 0% +01100110110: 0% +01100110111: 0% +01100111000: 0% +01100111001: 0% +01100111010: 0% +01100111011: 0% +01100111100: 0% +01100111101: 0% +01100111110: 0% +01100111111: 0% +01101000000: 0% +01101000001: 0% +01101000010: 0% +01101000011: 0% +01101000100: 0% +01101000101: 0% +01101000110: 0% +01101000111: 0% +01101001000: 0% +01101001001: 0% +01101001010: 0% +01101001011: 0% +01101001100: 0% +01101001101: 0% +01101001110: 0% +01101001111: 0% +01101010000: 0% +01101010001: 0% +01101010010: 0% +01101010011: 0% +01101010100: 0% +01101010101: 0% +01101010110: 0% +01101010111: 0% +01101011000: 0% +01101011001: 0% +01101011010: 0% +01101011011: 0% +01101011100: 0% +01101011101: 0% +01101011110: 0% +01101011111: 0% +01101100000: 0% +01101100001: 0% +01101100010: 0% +01101100011: 0% +01101100100: 0% +01101100101: 0% +01101100110: 0% +01101100111: 0% +01101101000: 0% +01101101001: 0% +01101101010: 0% +01101101011: 0% +01101101100: 0% +01101101101: 0% +01101101110: 0% +01101101111: 0% +01101110000: 0% +01101110001: 0% +01101110010: 0% +01101110011: 0% +01101110100: 0% +01101110101: 0% +01101110110: 0% +01101110111: 0% +01101111000: 0% +01101111001: 0% +01101111010: 0% +01101111011: 0% +01101111100: 0% +01101111101: 0% +01101111110: 0% +01101111111: 0% +01110000000: 0% +01110000001: 0% +01110000010: 0% +01110000011: 0% +01110000100: 0% +01110000101: 0% +01110000110: 0% +01110000111: 0% +01110001000: 0% +01110001001: 0% +01110001010: 0% +01110001011: 0% +01110001100: 0% +01110001101: 0% +01110001110: 0% +01110001111: 0% +01110010000: 0% +01110010001: 0% +01110010010: 0% +01110010011: 0% +01110010100: 0% +01110010101: 0% +01110010110: 0% +01110010111: 0% +01110011000: 0% +01110011001: 0% +01110011010: 0% +01110011011: 0% +01110011100: 0% +01110011101: 0% +01110011110: 0% +01110011111: 0% +01110100000: 0% +01110100001: 0% +01110100010: 0% +01110100011: 0% +01110100100: 0% +01110100101: 0% +01110100110: 0% +01110100111: 0% +01110101000: 0% +01110101001: 0% +01110101010: 0% +01110101011: 0% +01110101100: 0% +01110101101: 0% +01110101110: 0% +01110101111: 0% +01110110000: 0% +01110110001: 0% +01110110010: 0% +01110110011: 0% +01110110100: 0% +01110110101: 0% +01110110110: 0% +01110110111: 0% +01110111000: 0% +01110111001: 0% +01110111010: 0% +01110111011: 0% +01110111100: 0% +01110111101: 0% +01110111110: 0% +01110111111: 0% +01111000000: 0% +01111000001: 0% +01111000010: 0% +01111000011: 0% +01111000100: 0% +01111000101: 0% +01111000110: 0% +01111000111: 0% +01111001000: 0% +01111001001: 0% +01111001010: 0% +01111001011: 0% +01111001100: 0% +01111001101: 0% +01111001110: 0% +01111001111: 0% +01111010000: 0% +01111010001: 0% +01111010010: 0% +01111010011: 0% +01111010100: 0% +01111010101: 0% +01111010110: 0% +01111010111: 0% +01111011000: 0% +01111011001: 0% +01111011010: 0% +01111011011: 0% +01111011100: 0% +01111011101: 0% +01111011110: 0% +01111011111: 0% +01111100000: 0% +01111100001: 0% +01111100010: 0% +01111100011: 0% +01111100100: 0% +01111100101: 0% +01111100110: 0% +01111100111: 0% +01111101000: 0% +01111101001: 0% +01111101010: 0% +01111101011: 0% +01111101100: 0% +01111101101: 0% +01111101110: 0% +01111101111: 0% +01111110000: 0% +01111110001: 0% +01111110010: 0% +01111110011: 0% +01111110100: 0% +01111110101: 0% +01111110110: 0% +01111110111: 0% +01111111000: 0% +01111111001: 0% +01111111010: 0% +01111111011: 0% +01111111100: 0% +01111111101: 0% +01111111110: 0% +01111111111: 0% +10000000000: 0% +10000000001: 0% +10000000010: 0% +10000000011: 0% +10000000100: 0% +10000000101: 0% +10000000110: 0% +10000000111: 0% +10000001000: 0% +10000001001: 0% +10000001010: 0% +10000001011: 0% +10000001100: 0% +10000001101: 0% +10000001110: 0% +10000001111: 0% +10000010000: 0% +10000010001: 0% +10000010010: 0% +10000010011: 0% +10000010100: 0% +10000010101: 0% +10000010110: 0% +10000010111: 0% +10000011000: 0% +10000011001: 0% +10000011010: 0% +10000011011: 0% +10000011100: 0% +10000011101: 0% +10000011110: 0% +10000011111: 0% +10000100000: 0% +10000100001: 0% +10000100010: 0% +10000100011: 0% +10000100100: 0% +10000100101: 0% +10000100110: 0% +10000100111: 0% +10000101000: 0% +10000101001: 0% +10000101010: 0% +10000101011: 0% +10000101100: 0% +10000101101: 0% +10000101110: 0% +10000101111: 0% +10000110000: 0% +10000110001: 0% +10000110010: 0% +10000110011: 0% +10000110100: 0% +10000110101: 0% +10000110110: 0% +10000110111: 0% +10000111000: 0% +10000111001: 0% +10000111010: 0% +10000111011: 0% +10000111100: 0% +10000111101: 0% +10000111110: 0% +10000111111: 0% +10001000000: 0% +10001000001: 0% +10001000010: 0% +10001000011: 0% +10001000100: 0% +10001000101: 0% +10001000110: 0% +10001000111: 0% +10001001000: 0% +10001001001: 0% +10001001010: 0% +10001001011: 0% +10001001100: 0% +10001001101: 0% +10001001110: 0% +10001001111: 0% +10001010000: 0% +10001010001: 0% +10001010010: 0% +10001010011: 0% +10001010100: 0% +10001010101: 0% +10001010110: 0% +10001010111: 0% +10001011000: 0% +10001011001: 0% +10001011010: 0% +10001011011: 0% +10001011100: 0% +10001011101: 0% +10001011110: 0% +10001011111: 0% +10001100000: 0% +10001100001: 0% +10001100010: 0% +10001100011: 0% +10001100100: 0% +10001100101: 0% +10001100110: 0% +10001100111: 0% +10001101000: 0% +10001101001: 0% +10001101010: 0% +10001101011: 0% +10001101100: 0% +10001101101: 0% +10001101110: 0% +10001101111: 0% +10001110000: 0% +10001110001: 0% +10001110010: 0% +10001110011: 0% +10001110100: 0% +10001110101: 0% +10001110110: 0% +10001110111: 0% +10001111000: 0% +10001111001: 0% +10001111010: 0% +10001111011: 0% +10001111100: 0% +10001111101: 0% +10001111110: 0% +10001111111: 0% +10010000000: 0% +10010000001: 0% +10010000010: 0% +10010000011: 0% +10010000100: 0% +10010000101: 0% +10010000110: 0% +10010000111: 0% +10010001000: 0% +10010001001: 0% +10010001010: 0% +10010001011: 0% +10010001100: 0% +10010001101: 0% +10010001110: 0% +10010001111: 0% +10010010000: 0% +10010010001: 0% +10010010010: 0% +10010010011: 0% +10010010100: 0% +10010010101: 0% +10010010110: 0% +10010010111: 0% +10010011000: 0% +10010011001: 0% +10010011010: 0% +10010011011: 0% +10010011100: 0% +10010011101: 0% +10010011110: 0% +10010011111: 0% +10010100000: 0% +10010100001: 0% +10010100010: 0% +10010100011: 0% +10010100100: 0% +10010100101: 0% +10010100110: 0% +10010100111: 0% +10010101000: 0% +10010101001: 0% +10010101010: 0% +10010101011: 0% +10010101100: 0% +10010101101: 0% +10010101110: 0% +10010101111: 0% +10010110000: 0% +10010110001: 0% +10010110010: 0% +10010110011: 0% +10010110100: 0% +10010110101: 0% +10010110110: 0% +10010110111: 0% +10010111000: 0% +10010111001: 0% +10010111010: 0% +10010111011: 0% +10010111100: 0% +10010111101: 0% +10010111110: 0% +10010111111: 0% +10011000000: 0% +10011000001: 0% +10011000010: 0% +10011000011: 0% +10011000100: 0% +10011000101: 0% +10011000110: 0% +10011000111: 0% +10011001000: 0% +10011001001: 0% +10011001010: 0% +10011001011: 0% +10011001100: 0% +10011001101: 0% +10011001110: 0% +10011001111: 0% +10011010000: 0% +10011010001: 0% +10011010010: 0% +10011010011: 0% +10011010100: 0% +10011010101: 0% +10011010110: 0% +10011010111: 0% +10011011000: 0% +10011011001: 0% +10011011010: 0% +10011011011: 0% +10011011100: 0% +10011011101: 0% +10011011110: 0% +10011011111: 0% +10011100000: 0% +10011100001: 0% +10011100010: 0% +10011100011: 0% +10011100100: 0% +10011100101: 0% +10011100110: 0% +10011100111: 0% +10011101000: 0% +10011101001: 0% +10011101010: 0% +10011101011: 0% +10011101100: 0% +10011101101: 0% +10011101110: 0% +10011101111: 0% +10011110000: 0% +10011110001: 0% +10011110010: 0% +10011110011: 0% +10011110100: 0% +10011110101: 0% +10011110110: 0% +10011110111: 0% +10011111000: 0% +10011111001: 0% +10011111010: 0% +10011111011: 0% +10011111100: 0% +10011111101: 0% +10011111110: 0% +10011111111: 0% +10100000000: 0% +10100000001: 0% +10100000010: 0% +10100000011: 0% +10100000100: 0% +10100000101: 0% +10100000110: 0% +10100000111: 0% +10100001000: 0% +10100001001: 0% +10100001010: 0% +10100001011: 0% +10100001100: 0% +10100001101: 0% +10100001110: 0% +10100001111: 0% +10100010000: 0% +10100010001: 0% +10100010010: 0% +10100010011: 0% +10100010100: 0% +10100010101: 0% +10100010110: 0% +10100010111: 0% +10100011000: 0% +10100011001: 0% +10100011010: 0% +10100011011: 0% +10100011100: 0% +10100011101: 0% +10100011110: 0% +10100011111: 0% +10100100000: 0% +10100100001: 0% +10100100010: 0% +10100100011: 0% +10100100100: 0% +10100100101: 0% +10100100110: 0% +10100100111: 0% +10100101000: 0% +10100101001: 0% +10100101010: 0% +10100101011: 0% +10100101100: 0% +10100101101: 0% +10100101110: 0% +10100101111: 0% +10100110000: 0% +10100110001: 0% +10100110010: 0% +10100110011: 0% +10100110100: 0% +10100110101: 0% +10100110110: 0% +10100110111: 0% +10100111000: 0% +10100111001: 0% +10100111010: 0% +10100111011: 0% +10100111100: 0% +10100111101: 0% +10100111110: 0% +10100111111: 0% +10101000000: 0% +10101000001: 0% +10101000010: 0% +10101000011: 0% +10101000100: 0% +10101000101: 0% +10101000110: 0% +10101000111: 0% +10101001000: 0% +10101001001: 0% +10101001010: 0% +10101001011: 0% +10101001100: 0% +10101001101: 0% +10101001110: 0% +10101001111: 0% +10101010000: 0% +10101010001: 0% +10101010010: 0% +10101010011: 0% +10101010100: 0% +10101010101: 0% +10101010110: 0% +10101010111: 0% +10101011000: 0% +10101011001: 0% +10101011010: 0% +10101011011: 0% +10101011100: 0% +10101011101: 0% +10101011110: 0% +10101011111: 0% +10101100000: 0% +10101100001: 0% +10101100010: 0% +10101100011: 0% +10101100100: 0% +10101100101: 0% +10101100110: 0% +10101100111: 0% +10101101000: 0% +10101101001: 0% +10101101010: 0% +10101101011: 0% +10101101100: 0% +10101101101: 0% +10101101110: 0% +10101101111: 0% +10101110000: 0% +10101110001: 0% +10101110010: 0% +10101110011: 0% +10101110100: 0% +10101110101: 0% +10101110110: 0% +10101110111: 0% +10101111000: 0% +10101111001: 0% +10101111010: 0% +10101111011: 0% +10101111100: 0% +10101111101: 0% +10101111110: 0% +10101111111: 0% +10110000000: 0% +10110000001: 0% +10110000010: 0% +10110000011: 0% +10110000100: 0% +10110000101: 0% +10110000110: 0% +10110000111: 0% +10110001000: 0% +10110001001: 0% +10110001010: 0% +10110001011: 0% +10110001100: 0% +10110001101: 0% +10110001110: 0% +10110001111: 0% +10110010000: 0% +10110010001: 0% +10110010010: 0% +10110010011: 0% +10110010100: 0% +10110010101: 0% +10110010110: 0% +10110010111: 0% +10110011000: 0% +10110011001: 0% +10110011010: 0% +10110011011: 0% +10110011100: 0% +10110011101: 0% +10110011110: 0% +10110011111: 0% +10110100000: 0% +10110100001: 0% +10110100010: 0% +10110100011: 0% +10110100100: 0% +10110100101: 0% +10110100110: 0% +10110100111: 0% +10110101000: 0% +10110101001: 0% +10110101010: 0% +10110101011: 0% +10110101100: 0% +10110101101: 0% +10110101110: 0% +10110101111: 0% +10110110000: 0% +10110110001: 0% +10110110010: 0% +10110110011: 0% +10110110100: 0% +10110110101: 0% +10110110110: 0% +10110110111: 0% +10110111000: 0% +10110111001: 0% +10110111010: 0% +10110111011: 0% +10110111100: 0% +10110111101: 0% +10110111110: 0% +10110111111: 0% +10111000000: 0% +10111000001: 0% +10111000010: 0% +10111000011: 0% +10111000100: 0% +10111000101: 0% +10111000110: 0% +10111000111: 0% +10111001000: 0% +10111001001: 0% +10111001010: 0% +10111001011: 0% +10111001100: 0% +10111001101: 0% +10111001110: 0% +10111001111: 0% +10111010000: 0% +10111010001: 0% +10111010010: 0% +10111010011: 0% +10111010100: 0% +10111010101: 0% +10111010110: 0% +10111010111: 0% +10111011000: 0% +10111011001: 0% +10111011010: 0% +10111011011: 0% +10111011100: 0% +10111011101: 0% +10111011110: 0% +10111011111: 0% +10111100000: 0% +10111100001: 0% +10111100010: 0% +10111100011: 0% +10111100100: 0% +10111100101: 0% +10111100110: 0% +10111100111: 0% +10111101000: 0% +10111101001: 0% +10111101010: 0% +10111101011: 0% +10111101100: 0% +10111101101: 0% +10111101110: 0% +10111101111: 0% +10111110000: 0% +10111110001: 0% +10111110010: 0% +10111110011: 0% +10111110100: 0% +10111110101: 0% +10111110110: 0% +10111110111: 0% +10111111000: 0% +10111111001: 0% +10111111010: 0% +10111111011: 0% +10111111100: 0% +10111111101: 0% +10111111110: 0% +10111111111: 0% +11000000000: 0% +11000000001: 0% +11000000010: 0% +11000000011: 0% +11000000100: 0% +11000000101: 0% +11000000110: 0% +11000000111: 0% +11000001000: 0% +11000001001: 0% +11000001010: 0% +11000001011: 0% +11000001100: 0% +11000001101: 0% +11000001110: 0% +11000001111: 0% +11000010000: 0% +11000010001: 0% +11000010010: 0% +11000010011: 0% +11000010100: 0% +11000010101: 0% +11000010110: 0% +11000010111: 0% +11000011000: 0% +11000011001: 0% +11000011010: 0% +11000011011: 0% +11000011100: 0% +11000011101: 0% +11000011110: 0% +11000011111: 0% +11000100000: 0% +11000100001: 0% +11000100010: 0% +11000100011: 0% +11000100100: 0% +11000100101: 0% +11000100110: 0% +11000100111: 0% +11000101000: 0% +11000101001: 0% +11000101010: 0% +11000101011: 0% +11000101100: 0% +11000101101: 0% +11000101110: 0% +11000101111: 0% +11000110000: 0% +11000110001: 0% +11000110010: 0% +11000110011: 0% +11000110100: 0% +11000110101: 0% +11000110110: 0% +11000110111: 0% +11000111000: 0% +11000111001: 0% +11000111010: 0% +11000111011: 0% +11000111100: 0% +11000111101: 0% +11000111110: 0% +11000111111: 0% +11001000000: 0% +11001000001: 0% +11001000010: 0% +11001000011: 0% +11001000100: 0% +11001000101: 0% +11001000110: 0% +11001000111: 0% +11001001000: 0% +11001001001: 0% +11001001010: 0% +11001001011: 0% +11001001100: 0% +11001001101: 0% +11001001110: 0% +11001001111: 0% +11001010000: 0% +11001010001: 0% +11001010010: 0% +11001010011: 0% +11001010100: 0% +11001010101: 0% +11001010110: 0% +11001010111: 0% +11001011000: 0% +11001011001: 0% +11001011010: 0% +11001011011: 0% +11001011100: 0% +11001011101: 0% +11001011110: 0% +11001011111: 0% +11001100000: 0% +11001100001: 0% +11001100010: 0% +11001100011: 0% +11001100100: 0% +11001100101: 0% +11001100110: 0% +11001100111: 0% +11001101000: 0% +11001101001: 0% +11001101010: 0% +11001101011: 0% +11001101100: 0% +11001101101: 0% +11001101110: 0% +11001101111: 0% +11001110000: 0% +11001110001: 0% +11001110010: 0% +11001110011: 0% +11001110100: 0% +11001110101: 0% +11001110110: 0% +11001110111: 0% +11001111000: 0% +11001111001: 0% +11001111010: 0% +11001111011: 0% +11001111100: 0% +11001111101: 0% +11001111110: 0% +11001111111: 0% +11010000000: 0% +11010000001: 0% +11010000010: 0% +11010000011: 0% +11010000100: 0% +11010000101: 0% +11010000110: 0% +11010000111: 0% +11010001000: 0% +11010001001: 0% +11010001010: 0% +11010001011: 0% +11010001100: 0% +11010001101: 0% +11010001110: 0% +11010001111: 0% +11010010000: 0% +11010010001: 0% +11010010010: 0% +11010010011: 0% +11010010100: 0% +11010010101: 0% +11010010110: 0% +11010010111: 0% +11010011000: 0% +11010011001: 0% +11010011010: 0% +11010011011: 0% +11010011100: 0% +11010011101: 0% +11010011110: 0% +11010011111: 0% +11010100000: 0% +11010100001: 0% +11010100010: 0% +11010100011: 0% +11010100100: 0% +11010100101: 0% +11010100110: 0% +11010100111: 0% +11010101000: 0% +11010101001: 0% +11010101010: 0% +11010101011: 0% +11010101100: 0% +11010101101: 0% +11010101110: 0% +11010101111: 0% +11010110000: 0% +11010110001: 0% +11010110010: 0% +11010110011: 0% +11010110100: 0% +11010110101: 0% +11010110110: 0% +11010110111: 0% +11010111000: 0% +11010111001: 0% +11010111010: 0% +11010111011: 0% +11010111100: 0% +11010111101: 0% +11010111110: 0% +11010111111: 0% +11011000000: 0% +11011000001: 0% +11011000010: 0% +11011000011: 0% +11011000100: 0% +11011000101: 0% +11011000110: 0% +11011000111: 0% +11011001000: 0% +11011001001: 0% +11011001010: 0% +11011001011: 0% +11011001100: 0% +11011001101: 0% +11011001110: 0% +11011001111: 0% +11011010000: 0% +11011010001: 0% +11011010010: 0% +11011010011: 0% +11011010100: 0% +11011010101: 0% +11011010110: 0% +11011010111: 0% +11011011000: 0% +11011011001: 0% +11011011010: 0% +11011011011: 0% +11011011100: 0% +11011011101: 0% +11011011110: 0% +11011011111: 0% +11011100000: 0% +11011100001: 0% +11011100010: 0% +11011100011: 0% +11011100100: 0% +11011100101: 0% +11011100110: 0% +11011100111: 0% +11011101000: 0% +11011101001: 0% +11011101010: 0% +11011101011: 0% +11011101100: 0% +11011101101: 0% +11011101110: 0% +11011101111: 0% +11011110000: 0% +11011110001: 0% +11011110010: 0% +11011110011: 0% +11011110100: 0% +11011110101: 0% +11011110110: 0% +11011110111: 0% +11011111000: 0% +11011111001: 0% +11011111010: 0% +11011111011: 0% +11011111100: 0% +11011111101: 0% +11011111110: 0% +11011111111: 0% +11100000000: 0% +11100000001: 0% +11100000010: 0% +11100000011: 0% +11100000100: 0% +11100000101: 0% +11100000110: 0% +11100000111: 0% +11100001000: 0% +11100001001: 0% +11100001010: 0% +11100001011: 0% +11100001100: 0% +11100001101: 0% +11100001110: 0% +11100001111: 0% +11100010000: 0% +11100010001: 0% +11100010010: 0% +11100010011: 0% +11100010100: 0% +11100010101: 0% +11100010110: 0% +11100010111: 0% +11100011000: 0% +11100011001: 0% +11100011010: 0% +11100011011: 0% +11100011100: 0% +11100011101: 0% +11100011110: 0% +11100011111: 0% +11100100000: 0% +11100100001: 0% +11100100010: 0% +11100100011: 0% +11100100100: 0% +11100100101: 0% +11100100110: 0% +11100100111: 0% +11100101000: 0% +11100101001: 0% +11100101010: 0% +11100101011: 0% +11100101100: 0% +11100101101: 0% +11100101110: 0% +11100101111: 0% +11100110000: 0% +11100110001: 0% +11100110010: 0% +11100110011: 0% +11100110100: 0% +11100110101: 0% +11100110110: 0% +11100110111: 0% +11100111000: 0% +11100111001: 0% +11100111010: 0% +11100111011: 0% +11100111100: 0% +11100111101: 0% +11100111110: 0% +11100111111: 0% +11101000000: 0% +11101000001: 0% +11101000010: 0% +11101000011: 0% +11101000100: 0% +11101000101: 0% +11101000110: 0% +11101000111: 0% +11101001000: 0% +11101001001: 0% +11101001010: 0% +11101001011: 0% +11101001100: 0% +11101001101: 0% +11101001110: 0% +11101001111: 0% +11101010000: 0% +11101010001: 0% +11101010010: 0% +11101010011: 0% +11101010100: 0% +11101010101: 0% +11101010110: 0% +11101010111: 0% +11101011000: 0% +11101011001: 0% +11101011010: 0% +11101011011: 0% +11101011100: 0% +11101011101: 0% +11101011110: 0% +11101011111: 0% +11101100000: 0% +11101100001: 0% +11101100010: 0% +11101100011: 0% +11101100100: 0% +11101100101: 0% +11101100110: 0% +11101100111: 0% +11101101000: 0% +11101101001: 0% +11101101010: 0% +11101101011: 0% +11101101100: 0% +11101101101: 0% +11101101110: 0% +11101101111: 0% +11101110000: 0% +11101110001: 0% +11101110010: 0% +11101110011: 0% +11101110100: 0% +11101110101: 0% +11101110110: 0% +11101110111: 0% +11101111000: 0% +11101111001: 0% +11101111010: 0% +11101111011: 0% +11101111100: 0% +11101111101: 0% +11101111110: 0% +11101111111: 0% +11110000000: 0% +11110000001: 0% +11110000010: 0% +11110000011: 0% +11110000100: 0% +11110000101: 0% +11110000110: 0% +11110000111: 0% +11110001000: 0% +11110001001: 0% +11110001010: 0% +11110001011: 0% +11110001100: 0% +11110001101: 0% +11110001110: 0% +11110001111: 0% +11110010000: 0% +11110010001: 0% +11110010010: 0% +11110010011: 0% +11110010100: 0% +11110010101: 0% +11110010110: 0% +11110010111: 0% +11110011000: 0% +11110011001: 0% +11110011010: 0% +11110011011: 0% +11110011100: 0% +11110011101: 0% +11110011110: 0% +11110011111: 0% +11110100000: 0% +11110100001: 0% +11110100010: 0% +11110100011: 0% +11110100100: 0% +11110100101: 0% +11110100110: 0% +11110100111: 0% +11110101000: 0% +11110101001: 0% +11110101010: 0% +11110101011: 0% +11110101100: 0% +11110101101: 0% +11110101110: 0% +11110101111: 0% +11110110000: 0% +11110110001: 0% +11110110010: 0% +11110110011: 0% +11110110100: 0% +11110110101: 0% +11110110110: 0% +11110110111: 0% +11110111000: 0% +11110111001: 0% +11110111010: 0% +11110111011: 0% +11110111100: 0% +11110111101: 0% +11110111110: 0% +11110111111: 0% +11111000000: 0% +11111000001: 0% +11111000010: 0% +11111000011: 0% +11111000100: 0% +11111000101: 0% +11111000110: 0% +11111000111: 0% +11111001000: 0% +11111001001: 0% +11111001010: 0% +11111001011: 0% +11111001100: 0% +11111001101: 0% +11111001110: 0% +11111001111: 0% +11111010000: 0% +11111010001: 0% +11111010010: 0% +11111010011: 0% +11111010100: 0% +11111010101: 0% +11111010110: 0% +11111010111: 0% +11111011000: 0% +11111011001: 0% +11111011010: 0% +11111011011: 0% +11111011100: 0% +11111011101: 0% +11111011110: 0% +11111011111: 0% +11111100000: 0% +11111100001: 0% +11111100010: 0% +11111100011: 0% +11111100100: 0% +11111100101: 0% +11111100110: 0% +11111100111: 0% +11111101000: 0% +11111101001: 0% +11111101010: 0% +11111101011: 0% +11111101100: 0% +11111101101: 0% +11111101110: 0% +11111101111: 0% +11111110000: 0% +11111110001: 0% +11111110010: 0% +11111110011: 0% +11111110100: 0% +11111110101: 0% +11111110110: 0% +11111110111: 0% +11111111000: 0% +11111111001: 0% +11111111010: 0% +11111111011: 0% +11111111100: 0% +11111111101: 0% +11111111110: 0% +11111111111: 0% diff --git a/src/QAnsel.c b/src/QAnsel.c index 716d0e1..af46dd8 100644 --- a/src/QAnsel.c +++ b/src/QAnsel.c @@ -45,12 +45,13 @@ double qansel_rand() { num = (num << 8) | block[i]; } + free(block); return ((double)num) / ((double)UINT32_MAX); } void qansel_cnot(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB) { - uint32_t retLen = (uint8_t)pow(2, qubitCount); + uint32_t retLen = (uint32_t)pow(2, qubitCount); cpx_mtx_t ret; cpx_mtx_init(&ret, 1, retLen); cpx_t n; @@ -71,7 +72,7 @@ void qansel_cnot(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8 void qansel_swap(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB) { - uint32_t retLen = (uint8_t)pow(2, qubitCount); + uint32_t retLen = (uint32_t)pow(2, qubitCount); cpx_mtx_t ret; cpx_mtx_init(&ret, 1, retLen); cpx_t n; @@ -93,7 +94,7 @@ void qansel_swap(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8 void qansel_fredkin(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB, uint8_t bitC) { - uint32_t retLen = (uint8_t)pow(2, qubitCount); + uint32_t retLen = (uint32_t)pow(2, qubitCount); cpx_mtx_t ret; cpx_mtx_init(&ret, 1, retLen); cpx_t n; @@ -117,7 +118,7 @@ void qansel_fredkin(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, ui void qansel_toffoli(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t bitA, uint8_t bitB, uint8_t bitC) { - uint32_t retLen = (uint8_t)pow(2, qubitCount); + uint32_t retLen = (uint32_t)pow(2, qubitCount); cpx_mtx_t ret; cpx_mtx_init(&ret, 1, retLen); cpx_t n; @@ -193,7 +194,6 @@ void qansel_instruction(cpx_mtx_t* stateVector, uint8_t qubitCount, QInstr* inst for (uint8_t i = 1; i < qubitCount; i++) { - cpx_mtx_init(&tmp, filter.rows * 2, filter.cols * 2); if (qubit == i) { gate.ptr = gate_ptr; @@ -202,7 +202,17 @@ void qansel_instruction(cpx_mtx_t* stateVector, uint8_t qubitCount, QInstr* inst { gate.ptr = Identity; } - cpx_mtx_knk(&tmp, &filter, &gate); + + tmp.rows = filter.rows * gate.rows; + tmp.cols = filter.cols * gate.cols; + tmp.ptr = malloc((tmp.rows * 2) * (tmp.cols * 2) * sizeof(double)); + cpx_ncpx_knk_mt + ( + tmp.ptr, tmp.rows, tmp.cols, + filter.ptr, filter.rows, filter.cols, + gate.ptr, gate.rows, gate.cols + ); + free(filter.ptr); filter.ptr = tmp.ptr; filter.rows = tmp.rows; @@ -210,14 +220,17 @@ void qansel_instruction(cpx_mtx_t* stateVector, uint8_t qubitCount, QInstr* inst } cpx_mtx_init(&tmp, stateVector->rows, stateVector->cols); - cpx_mtx_mul(&tmp, stateVector, &filter); + cpx_ncpx_mmul_mt + ( + tmp.ptr, stateVector->ptr, filter.ptr, + stateVector->rows * 2, filter.cols * 2, stateVector->cols * 2 + ); free(stateVector->ptr); stateVector->ptr = tmp.ptr; free(filter.ptr); if (instr->n[0] == 'u') free(gate_ptr); } - uint8_t qansel_measure(cpx_mtx_t* stateVector, uint8_t qubitCount, uint8_t qubit) { uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); @@ -396,7 +409,7 @@ void qansel_run(uint8_t qubitCount, uint8_t bitCount, QInstr* instr, uint32_t in } printf("%.00f%%\n", prob * 100.0); } - else if (strcmp(instr[i].n, "reset") == 0) + else if (strcmp(instr[i].n, "reset_all") == 0) { cpx_mtx_set2(&stateVector, 0, 0, 1, 0); for (uint32_t j = 1; j < qubitCountPow2; j++) @@ -408,6 +421,20 @@ void qansel_run(uint8_t qubitCount, uint8_t bitCount, QInstr* instr, uint32_t in bitVector[j] = 0; } } + else if (strcmp(instr[i].n, "resetq") == 0) + { + uint8_t bit = qansel_measure(&stateVector, qubitCount, instr[i].q0); + if (bit) + { + instr[i].n[0] = 'x'; + instr[i].n[1] = 0; + qansel_instruction(&stateVector, qubitCount, instr + i); + } + } + else if (strcmp(instr[i].n, "resetc") == 0) + { + bitVector[instr[i].q0] = 0; + } else { qansel_instruction(&stateVector, qubitCount, instr + i); @@ -420,7 +447,7 @@ void qansel_run(uint8_t qubitCount, uint8_t bitCount, QInstr* instr, uint32_t in cpx_mtx_free(&stateVector); } -void main() +void main(int argc, char** argv) { char** lines = malloc(0); uint32_t* lineIDs = malloc(0); @@ -454,9 +481,16 @@ void main() else if (comment || (c == ' ' && skipSpaces)) {} else if (c != '\n' && c != '\t' && c != ';' && (c != ')' || inGate)) { + if (commentM == 1) + { + text = realloc(text, textLen + 1); + text[textLen++] = '/'; + commentM = 0; + } skipSpaces = 0; if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; if (c == 'u') inGate = 1; + if (c == 'r') inGate = 1; text = realloc(text, textLen + 1); text[textLen++] = c; pc = c; @@ -487,7 +521,7 @@ void main() if (strlen(text) > 0) { free(text); - fprintf(stderr, "QAnsel: Invalid trailing text.\n"); + fprintf(stderr, "QAnsel: Invalid trailing text"); exit(1); } free(text); @@ -548,13 +582,13 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } if (q0 < 0 || q0 >= qubitCount) { - fprintf(stderr, "QAnsel: Invalid index "); + fprintf(stderr, "QAnsel: Invalid index"); errFound = 1; break; } @@ -567,25 +601,141 @@ void main() instr[instrLen++].arg2 = a2; } else if + ( + memcmp("rx(", lines[i], 3) == 0 + || memcmp("ry(", lines[i], 3) == 0 + || memcmp("rz(", lines[i], 3) == 0 + ) + { + double angle; + char ty; + if (sscanf(lines[i], "r%c(%f/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = a0 / a1; + } + else if (sscanf(lines[i], "r%c(%f/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = a0 / (a1 * M_PI); + } + else if (sscanf(lines[i], "r%c(%f/pi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 / M_PI; + } + else if (sscanf(lines[i], "r%c(%f/-pi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 / -M_PI; + } + else if (sscanf(lines[i], "r%c(%fpi/%f) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = (a0 * M_PI) / a1; + } + else if (sscanf(lines[i], "r%c(pi/%f) q[%i]", &ty, &a0, &q0) == 3) + { + angle = M_PI / a0; + } + else if (sscanf(lines[i], "r%c(-pi/%f) q[%i]", &ty, &a0, &q0) == 3) + { + angle = -M_PI / a0; + } + else if (sscanf(lines[i], "r%c(%fpi/%fpi) q[%i]", &ty, &a0, &a1, &q0) == 4) + { + angle = (a0 * M_PI) / (a1 * M_PI); + } + else if (sscanf(lines[i], "r%c(pi/pi) q[%i]", &ty, &q0) == 2) + { + angle = 1; + } + else if (sscanf(lines[i], "r%c(-pi/pi) q[%i]", &ty, &q0) == 2) + { + angle = -1; + } + else if (sscanf(lines[i], "r%c(pi/-pi) q[%i]", &ty, &q0) == 2) + { + angle = -1; + } + else if (sscanf(lines[i], "r%c(-pi/-pi) q[%i]", &ty, &q0) == 2) + { + angle = 1; + } + else if (sscanf(lines[i], "r%c(%fpi) q[%i]", &ty, &a0, &q0) == 3) + { + angle = a0 * M_PI; + } + else if (sscanf(lines[i], "r%c(pi) q[%i]", &ty, &q0) == 2) + { + angle = M_PI; + } + else if (sscanf(lines[i], "r%c(-pi) q[%i]", &ty, &q0) == 2) + { + angle = -M_PI; + } + else if (sscanf(lines[i], "r%c(%f) q[%i]", &ty, &a0, &q0) == 2) + { + angle = a0; + } + else + { + fprintf(stderr, "QAnsel: Syntax error"); + errFound = 1; + break; + } + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction before initialization"); + errFound = 1; + break; + } + if (q0 < 0 || q0 >= qubitCount) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + instr[instrLen].n[0] = 'u'; + instr[instrLen].n[1] = 0; + instr[instrLen].q0 = q0; + switch (ty) + { + case 'x': + instr[instrLen].arg0 = M_PI / 2; + instr[instrLen].arg1 = -M_PI / 2; + instr[instrLen].arg2 = angle - (M_PI / 2); + break; + case 'y': + instr[instrLen].arg0 = angle; + instr[instrLen].arg1 = 0; + instr[instrLen].arg2 = 0; + break; + case 'z': + instr[instrLen].arg0 = 0; + instr[instrLen].arg1 = 0; + instr[instrLen].arg2 = angle; + break; + } + instrLen++; + } + else if ( sscanf(lines[i], "h q[%i]", &q0) == 1 || sscanf(lines[i], "x q[%i]", &q0) == 1 || sscanf(lines[i], "y q[%i]", &q0) == 1 || sscanf(lines[i], "z q[%i]", &q0) == 1 || sscanf(lines[i], "t q[%i]", &q0) == 1 - || sscanf(lines[i], "z q[%i]", &q0) == 1 + || sscanf(lines[i], "s q[%i]", &q0) == 1 ) { g = lines[i][0]; if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } if (q0 < 0 || q0 >= qubitCount) { - fprintf(stderr, "QAnsel: Invalid index "); + fprintf(stderr, "QAnsel: Invalid index"); errFound = 1; break; } @@ -598,7 +748,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } @@ -617,7 +767,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } @@ -640,13 +790,13 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } if (qubitCount < 3) { - fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized.\n"); + fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); errFound = 1; break; } @@ -670,13 +820,13 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Instruction before initialization.\n"); + fprintf(stderr, "QAnsel: Instruction before initialization"); errFound = 1; break; } if (qubitCount < 3) { - fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized.\n"); + fprintf(stderr, "QAnsel: Three qubit gate used with insufficient qubits initialized"); errFound = 1; break; } @@ -696,7 +846,7 @@ void main() { if (bitCount == 0xFF) { - fprintf(stderr, "QAnsel: Measure instruction used before bit initialization.\n"); + fprintf(stderr, "QAnsel: Measure instruction used before bit initialization"); errFound = 1; break; } @@ -715,7 +865,7 @@ void main() { if (bitCount == 0xFF) { - fprintf(stderr, "QAnsel: If instruction used before bit initialization.\n"); + fprintf(stderr, "QAnsel: If instruction used before bit initialization"); errFound = 1; break; } @@ -733,7 +883,7 @@ void main() { if (bitCount == 0xFF) { - fprintf(stderr, "QAnsel: If instruction used before bit initialization.\n"); + fprintf(stderr, "QAnsel: If instruction used before bit initialization"); errFound = 1; break; } @@ -752,7 +902,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); errFound = 1; break; } @@ -764,7 +914,7 @@ void main() { if (bitCount == 0xFF) { - fprintf(stderr, "QAnsel: Bit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); errFound = 1; break; } @@ -776,7 +926,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); errFound = 1; break; } @@ -794,7 +944,7 @@ void main() { if (bitCount == 0xFF) { - fprintf(stderr, "QAnsel: Bit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); errFound = 1; break; } @@ -812,7 +962,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); errFound = 1; break; } @@ -824,7 +974,7 @@ void main() { if (qubitCount == 0xFF) { - fprintf(stderr, "QAnsel: Qubit instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); errFound = 1; break; } @@ -838,18 +988,78 @@ void main() strcpy(instr[instrLen].n, "sample"); instr[instrLen++].q0 = q0; } - else if (strcmp(lines[i], "reset") == 0) + else if (sscanf(lines[i], "reset q[%i]", &q0) == 1) { - if (qubitCount == 0xFF || bitCount == 0xFF) + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "resetq"); + instr[instrLen++].q0 = q0; + } + else if (sscanf(lines[i], "reset c[%i]", &q0) == 1) + { + if (bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Bit instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= bitCount || q0 < 0) { - fprintf(stderr, "QAnsel: Instruction used before initialization.\n"); + fprintf(stderr, "QAnsel: Invalid index"); errFound = 1; break; } instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); - strcpy(instr[instrLen].n, "reset"); + strcpy(instr[instrLen].n, "resetc"); + instr[instrLen++].q0 = q0; + } + else if (strcmp(lines[i], "reset") == 0) + { + instr = realloc(instr, (instrLen + 1) * sizeof(QInstr)); + strcpy(instr[instrLen].n, "reset_all"); instrLen++; } + else if (strcmp(lines[i], "barrier q") == 0) + { + if (qubitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Qubit instruction used before initialization"); + errFound = 1; + break; + } + //do nothing as there are currently no + // optimizations that this instruction + // would prevent + } + else if (sscanf(lines[i], "barrier q[%i]", &q0) == 1) + { + if (qubitCount == 0xFF || bitCount == 0xFF) + { + fprintf(stderr, "QAnsel: Instruction used before initialization"); + errFound = 1; + break; + } + if (q0 >= qubitCount || q0 < 0) + { + fprintf(stderr, "QAnsel: Invalid index"); + errFound = 1; + break; + } + //do nothing as there are currently no + // optimizations that this instruction + // would prevent + } else { fprintf(stderr, "QAnsel: Syntax error"); @@ -869,7 +1079,17 @@ void main() exit(1); } - qansel_run(qubitCount, bitCount, instr, instrLen, 0); + if (argc == 2) + { + if (strcmp(argv[1], "-d") == 0) + { + qansel_run(qubitCount, bitCount, instr, instrLen, 1); + } + } + else + { + qansel_run(qubitCount, bitCount, instr, instrLen, 0); + } free(instr); free(lineIDs); } diff --git a/src/complex.c b/src/complex.c index e9736c4..c5346b7 100644 --- a/src/complex.c +++ b/src/complex.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include "cores.c" typedef struct { @@ -96,6 +99,110 @@ void cpx_ncpx_mmul(double* ptrR, double* ptrA, double* ptrB, size_t rowsA, size_ } } +typedef struct +{ + size_t ID; + size_t Threads; + size_t Last; + size_t Loops; + size_t Continue; + size_t BlockSize; + double* ptrR; + double* ptrA; + double* ptrB; + size_t rowsA; + size_t colsB; + size_t shared; +} cpx_mul_shared; + +void* cpx_ncpx_mmul_mtc(void *context) +{ + cpx_mul_shared* data = (cpx_mul_shared*)context; + double* ptrR = data->ptrR; + double* ptrA = data->ptrA; + double* ptrB = data->ptrB; + size_t rowsA = data->rowsA; + size_t colsB = data->colsB; + size_t shared = data->shared; + + size_t colsA = data->shared; + size_t rowsB = data->shared; + size_t rowsR = data->rowsA; + size_t colsR = data->colsB; + + for (size_t rowR = 0; rowR < rowsR; rowR++) + { + size_t a = data->ID * data->BlockSize; + size_t b = (data->ID + 1) * data->BlockSize; + if (data->ID == data->Last) b += data->Continue; + + //printf("%i;%i\n", a, b); + + for (size_t colR = a; colR < b; colR++) + { + size_t posR = colR + rowR * colsR; + size_t rowA = rowR; + size_t colB = colR; + ptrR[posR] = 0; + for (size_t i = 0; i < data->shared; i++) + { + size_t posA = i + rowA * colsA; + size_t posB = colB + i * colsB; + data->ptrR[posR] += data->ptrA[posA] * data->ptrB[posB]; + } + } + } +} + +void cpx_ncpx_mmul_mt(double* ptrR, double* ptrA, double* ptrB, size_t rowsA, size_t colsB, size_t shared) +{ + cpx_mul_shared share; + share.Threads = get_core_count(); + share.ptrR = ptrR; + share.ptrA = ptrA; + share.ptrB = ptrB; + share.rowsA = rowsA; + share.colsB = colsB; + share.shared = shared; + if (colsB <= share.Threads) + { + share.Threads = colsB; + } + share.BlockSize = (size_t)floor(((double)colsB) / ((double)share.Threads)); + share.Loops = (size_t)floor(((double)colsB) / ((double)share.BlockSize)); + share.Last = share.Loops - 1; + share.Continue = (size_t)(((double)colsB) - ((double)share.Loops) * ((double)share.BlockSize)); + + pthread_t threads[share.Loops]; + cpx_mul_shared contexts[share.Loops]; + for (size_t i = 0; i < share.Loops; i++) + { + pthread_t tid; + threads[i] = tid; + memcpy(contexts + i, &share, sizeof(cpx_mul_shared)); + contexts[i].ID = i; + } + + for (size_t i = 0; i < share.Loops; i++) + { + if (pthread_create(threads + i, NULL, &cpx_ncpx_mmul_mtc, contexts + i)) + { + fprintf(stderr, "QAnsel: Thread error. (1)\n"); + exit(1); + } + } + + for (uint32_t i = 0; i < share.Loops; i++) + { + pthread_t tid; + tid = threads[i]; + if (pthread_join(tid, NULL)) + { + fprintf(stderr, "QAnsel: Thread error. (2)\n"); + } + } +} + //non-complex kronecker product void cpx_ncpx_mknk(double* ptrR, double* ptrA, double* ptrB, size_t rowsA, size_t colsA, size_t rowsB, size_t colsB) { @@ -162,8 +269,12 @@ void cpx_mtx_get(cpx_mtx_t* m, size_t row, size_t col, cpx_t* n) row *= 2; col *= 2; size_t cols = m->cols * 2; + + //printf("qqq\n"); n->real = m->ptr[(col + 1) + (row + 1) * cols]; + //printf("ppp\n"); n->imaginary = m->ptr[col + (row + 1) * cols]; + //printf("ggg\n"); } double cpx_mtx_get_real(cpx_mtx_t* m, size_t row, size_t col) @@ -206,7 +317,136 @@ void cpx_mtx_free(cpx_mtx_t* m) m->cols = 0; } -void cpx_mtx_knk2 +typedef struct +{ + size_t ID; + size_t Threads; + size_t Last; + size_t Loops; + size_t Continue; + size_t BlockSize; + double* ptrR; + size_t rowsR; + size_t colsR; + double* ptrA; + size_t rowsA; + size_t colsA; + double* ptrB; + size_t rowsB; + size_t colsB; +} cpx_knk_shared; + +void* cpx_ncpx_knk_mtc(void *context) +{ + cpx_knk_shared* data = (cpx_knk_shared*)context; + double* ptrR = data->ptrR; + size_t rowsR = data->rowsR; + size_t colsR = data->colsR; + double* ptrA = data->ptrA; + size_t rowsA = data->rowsA; + size_t colsA = data->colsA; + double* ptrB = data->ptrB; + size_t rowsB = data->rowsB; + size_t colsB = data->colsB; + + for (size_t rowR = 0; rowR < rowsR; rowR++) + { + size_t a = data->ID * data->BlockSize; + size_t b = (data->ID + 1) * data->BlockSize; + if (data->ID == data->Last) b += data->Continue; + for (size_t colR = a; colR < b; colR++) + { + size_t rowA = rowR / rowsB; + size_t colA = colR / colsB; + size_t rowB = rowR % rowsB; + size_t colB = colR % colsB; + + double r1 = ptrA[((colA * 2) + 1) + ((rowA * 2) + 1) * (colsA * 2)]; + double i1 = ptrA[(colA * 2) + ((rowA * 2) + 1) * (colsA * 2)]; + double r2 = ptrB[((colB * 2) + 1) + ((rowB * 2) + 1) * (colsB * 2)]; + double i2 = ptrB[(colB * 2) + ((rowB * 2) + 1) * (colsB * 2)]; + + double first = r1 * r2; //real + double outer = r1 * i2; //imaginary + double inner = i1 * r2; //imaginary + double last = -(i1 * i2); //real + r1 = first + last; + i1 = outer + inner; + + ptrR[(colR * 2) + (rowR * 2) * (colsR * 2)] = r1; + ptrR[((colR * 2) + 1) + (rowR * 2) * (colsR * 2)] = -i1; + ptrR[(colR * 2) + ((rowR * 2) + 1) * (colsR * 2)] = i1; + ptrR[((colR * 2) + 1) + ((rowR * 2) + 1) * (colsR * 2)] = r1; + + } + } +} + +void cpx_ncpx_knk_mt +( + double* ptrR, + size_t rowsR, + size_t colsR, + double* ptrA, + size_t rowsA, + size_t colsA, + double* ptrB, + size_t rowsB, + size_t colsB +) +{ + cpx_knk_shared share; + share.Threads = get_core_count(); + share.ptrR = ptrR; + share.rowsR = rowsR; + share.colsR = colsR; + share.ptrA = ptrA; + share.rowsA = rowsA; + share.colsA = colsA; + share.ptrB = ptrB; + share.rowsB = rowsB; + share.colsB = colsB; + + if (colsR <= share.Threads) + { + share.Threads = colsR; + } + share.BlockSize = (size_t)floor(((double)colsR) / ((double)share.Threads)); + share.Loops = (size_t)floor(((double)colsR) / ((double)share.BlockSize)); + share.Last = share.Loops - 1; + share.Continue = (size_t)(((double)colsR) - ((double)share.Loops) * ((double)share.BlockSize)); + + pthread_t threads[share.Loops]; + cpx_knk_shared contexts[share.Loops]; + for (size_t i = 0; i < share.Loops; i++) + { + pthread_t tid; + threads[i] = tid; + memcpy(contexts + i, &share, sizeof(cpx_knk_shared)); + contexts[i].ID = i; + } + + for (size_t i = 0; i < share.Loops; i++) + { + if (pthread_create(threads + i, NULL, &cpx_ncpx_knk_mtc, contexts + i)) + { + fprintf(stderr, "QAnsel: Thread error. (1)\n"); + exit(1); + } + } + + for (uint32_t i = 0; i < share.Loops; i++) + { + pthread_t tid; + tid = threads[i]; + if (pthread_join(tid, NULL)) + { + fprintf(stderr, "QAnsel: Thread error. (2)\n"); + } + } +} + +void cpx_ncpx_knk ( double* ptrR, size_t rowsR, @@ -257,7 +497,6 @@ void cpx_mtx_knk(cpx_mtx_t* r, cpx_mtx_t* a, cpx_mtx_t* b) size_t colsB = b->cols; size_t rowsR = rowsA * rowsB; size_t colsR = colsA * colsB; - cpx_mtx_init(r, rowsR, colsR); for (size_t rowR = 0; rowR < rowsR; rowR++) { for (size_t colR = 0; colR < colsR; colR++) @@ -277,20 +516,6 @@ void cpx_mtx_knk(cpx_mtx_t* r, cpx_mtx_t* a, cpx_mtx_t* b) } } - -void cpx_mtx_(cpx_mtx_t* m) -{ - for (size_t r = 0; r < m->rows * 2; r++) - { - for (size_t c = 0; c < m->cols * 2; c++) - { - if (c > 0) printf(", "); - printf("%f", m->ptr[c + r * m->cols * 2]); - } - printf("\n"); - } -} - void cpx_mtx_print(cpx_mtx_t* m) { for (size_t r = 0; r < m->rows; r++) diff --git a/src/cores.c b/src/cores.c new file mode 100644 index 0000000..4320e71 --- /dev/null +++ b/src/cores.c @@ -0,0 +1,53 @@ +#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#elif defined(__linux__) +#include +#elif defined(__APPLE__) +#include +#endif + +int ___get_core_count() +{ + #if defined(_WIN32) || defined(_WIN64) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + #elif defined(__linux__) + return sysconf(_SC_NPROCESSORS_ONLN); + #elif defined(__APPLE__) + int nm[2]; + size_t len = 4; + uint32_t count; + + nm[0] = CTL_HW; + nm[1] = HW_AVAILCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + + if(count < 1) { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + if(count < 1) { + count = 1; + } + } + return count; + #else + return -1; // Unknown platform + #endif +} + +int get_core_count() +{ + static int coreCount = -1; + if (coreCount == -1) + { + coreCount = ___get_core_count(); + if (coreCount == -1) + { + coreCount = 1; + } + } + return coreCount; +} \ No newline at end of file diff --git a/src/display.c b/src/display.c index 02ff639..1862610 100644 --- a/src/display.c +++ b/src/display.c @@ -20,6 +20,11 @@ void DrawThickLine(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, int t } } +void display_wait(uint32_t i) +{ + SDL_Delay(i); +} + void display(cpx_mtx_t* stateVector, uint8_t qubitCount) { uint32_t qubitCountPow2 = (uint32_t)pow(2, qubitCount); @@ -29,6 +34,7 @@ void display(cpx_mtx_t* stateVector, uint8_t qubitCount) static SDL_Renderer* renderer = NULL; int SCREEN_WIDTH = 640 * 2; int SCREEN_HEIGHT = 480; + int SCREEN_HALF = SCREEN_HEIGHT / 2; if (stateVector == NULL) { @@ -47,7 +53,7 @@ void display(cpx_mtx_t* stateVector, uint8_t qubitCount) } window = SDL_CreateWindow ( - "D", + "QAnsel", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, @@ -73,7 +79,7 @@ void display(cpx_mtx_t* stateVector, uint8_t qubitCount) double p0 = 0; double i0 = 0; - for (int i = -20; i < SCREEN_WIDTH; i++) + for (int i = 0; i < SCREEN_WIDTH; i++) { double p1 = 0; double i1 = 0; @@ -81,8 +87,8 @@ void display(cpx_mtx_t* stateVector, uint8_t qubitCount) { cpx_t n; cpx_mtx_get(stateVector, 0, j - 1, &n); - p1 += (sin(i * ((2 * M_PI) / (SCREEN_WIDTH / j))) * (SCREEN_HEIGHT / 4)) * (n.real * n.real) * (n.real < 0 ? -1 : 1); - i1 += (cos(i * ((2 * M_PI) / (SCREEN_WIDTH / j))) * (SCREEN_HEIGHT / 4)) * (n.imaginary * n.imaginary) * (n.imaginary < 0 ? -1 : 1); + p1 += (sin(i * ((2 * M_PI) / (SCREEN_WIDTH / j))) * (SCREEN_HEIGHT / 4)) * pow(n.real, 2) * (n.real < 0 ? -1 : 1); + i1 += (cos(i * ((2 * M_PI) / (SCREEN_WIDTH / j))) * (SCREEN_HEIGHT / 4)) * pow(n.imaginary, 2) * (n.imaginary < 0 ? -1 : 1); } int x0 = i - 1; @@ -90,27 +96,29 @@ void display(cpx_mtx_t* stateVector, uint8_t qubitCount) int x1 = i; int y1 = p1; - x0 += i0 / 4; - y0 += i0 / 2; - x1 += i1 / 4; - y1 += i1 / 2; - y0 += SCREEN_HEIGHT / 2; y1 += SCREEN_HEIGHT / 2; - if ( (i0 + i1) / 2 < 0) + if (i > 0) { - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - DrawThickLine(renderer, x0, SCREEN_HEIGHT / 2, x1, SCREEN_HEIGHT / 2, 5); SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0x00); DrawThickLine(renderer, x0, y0, x1, y1, 5); + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0x00); + DrawThickLine(renderer, x0, SCREEN_HALF, x1, SCREEN_HALF, 5); } - else + + y0 = i0; + y1 = i1; + + y0 += SCREEN_HEIGHT / 2; + y1 += SCREEN_HEIGHT / 2; + + if (i > 0) { + SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00); DrawThickLine(renderer, x0, y0, x1, y1, 5); - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - DrawThickLine(renderer, x0, SCREEN_HEIGHT / 2, x1, SCREEN_HEIGHT / 2, 5); - SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0x00); + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0x00); + DrawThickLine(renderer, x0, SCREEN_HALF, x1, SCREEN_HALF, 5); } p0 = p1; i0 = i1; diff --git a/src/gates.c b/src/gates.c index 347a72e..bca311d 100644 --- a/src/gates.c +++ b/src/gates.c @@ -52,7 +52,7 @@ double PhaseS[] = 0, 1, 0, 0, 0, 0, 0,-1, - 0, 0, 0, 0 + 0, 0, 1, 0 }; // 1/sqrt(2) + 1/sqrt(2)i -- 2.39.5