added core code, README, and testing scripts
[strong_simulation_stabilizer_rank.git] / randominputcommutingHermitianPauli2.c
diff --git a/randominputcommutingHermitianPauli2.c b/randominputcommutingHermitianPauli2.c
new file mode 100644 (file)
index 0000000..1c79fbb
--- /dev/null
@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+// order of matrix elements is [row][column]!!!
+
+/*********************************************************/
+/* Generates random Hermitian Paulis that are commuting! */
+/*********************************************************/
+int main( int argc, char *argv[])
+{
+
+  if(argc != 4) {
+    printf("randominputPauli arguments: \"number of qubits\" \"number of T gates\" \"number of random Clifford steps\"\n");
+    exit(0);
+  }
+  
+  int N = atoi(argv[1]);              // number of qubits
+  int T = atoi(argv[2]);              // number of T gate magic states (set to the first 'K' of the 'N' qubits -- the rest are set to the '0' computational basis state)
+  int randsteps = atoi(argv[3]);              // number of random Clifford steps
+
+  printf("%d\n", N);
+  printf("%d\n", T);
+
+  int omega[N];
+  int Pauli[N][N];
+  srand((unsigned)time(NULL));
+
+
+  int i, j, k;
+
+  int sign = 1;
+
+  // don't initially generate Y's (which is represented by '3'; I=0, Z=1, X=2, Y=3)
+  for(i=0; i<N; i++) {
+    omega[i] = (rand()%2)*2; // omega must be 0 or 2 (since it is a power of i: i^omega)
+    for(j=0; j<i; j++)
+      Pauli[i][j] = 0; 
+    for(j=i; j<N; j++)
+      Pauli[i][j] = 1; 
+  }
+
+  int qubita, qubitb; // indices of qubits that are Hadamarded or CNOTed.
+  int gate;
+  for(i=0; i<randsteps; i++) {
+    //printf("i=%d\n", i);
+    gate = rand()%3;
+    //printf("gate=%d\n", gate);
+    if(gate==0) { // Hadamard
+      qubita = rand()%N;
+      for(j=0; j<N; j++) {
+       if(Pauli[j][qubita] ==1)
+         Pauli[j][qubita] = 2; // 1->2 and 2->1 (i.e. Z->X and X->Z)
+       else if(Pauli[j][qubita] ==2)
+         Pauli[j][qubita] = 1; // 1->2 and 2->1 (i.e. Z->X and X->Z)
+      }
+    } else if(gate==1) { // phaseshift
+      qubita = rand()%N;
+      //printf("qubita=%d", qubita);
+      for(j=0; j<N; j++) {
+       if(Pauli[j][qubita] == 2)
+         Pauli[j][qubita] = 3; // X->Y
+       else if(Pauli[j][qubita] == 3) {
+         Pauli[j][qubita] = 2; // Y->-X
+         omega[j] = (2*omega[j])%2;
+       }
+      }
+    } else { // CNOT
+      qubita = rand()%N;
+      qubitb = qubita;
+      while(qubitb == qubita)
+       qubitb = rand()%N;
+      for(j=0; j<N; j++) {
+       if((Pauli[j][qubita] == 1) && (Pauli[j][qubitb] == 1)) // ZZ ->ZI
+         Pauli[j][qubitb] == 0;
+       else if((Pauli[j][qubita] == 1) && (Pauli[j][qubitb] == 0)) // ZI ->ZZ
+         Pauli[j][qubitb] == 1;
+       else if((Pauli[j][qubita] == 2) && (Pauli[j][qubitb] == 2)) // XX ->IX
+         Pauli[j][qubita] == 1;
+       else if((Pauli[j][qubita] == 0) && (Pauli[j][qubitb] == 2)) // IX ->XX
+         Pauli[j][qubita] == 2;
+       else if((Pauli[j][qubita] == 1) && (Pauli[j][qubitb] == 2)) {// ZX ->YY
+         Pauli[j][qubita] == 3;
+         Pauli[j][qubitb] == 3;
+       } else if((Pauli[j][qubita] == 0) && (Pauli[j][qubitb] == 2)) {// YY ->ZX
+         Pauli[j][qubita] == 1;
+         Pauli[j][qubitb] == 2;
+       } else if((Pauli[j][qubita] == 3) && (Pauli[j][qubitb] == 2)) {// YX ->-ZY
+         Pauli[j][qubita] == 1;
+         Pauli[j][qubitb] == 3;
+         omega[j] = -omega[j];
+       } else if((Pauli[j][qubita] == 1) && (Pauli[j][qubitb] == 3)) {// ZY ->-YX
+         Pauli[j][qubita] == 3;
+         Pauli[j][qubitb] == 2;
+         omega[j] = -omega[j];
+       }
+      }
+    }
+  }
+
+  for(i=0; i<N; i++) {
+    printf("%d\n", omega[i]); 
+    for(j=0; j<N; j++) {
+      printf("%d %d %d %d\n", Pauli[i][j]==0, Pauli[i][j]==1, Pauli[i][j]==2, Pauli[i][j]==3);
+    }
+  }
+
+}