added core code, README, and testing scripts
[strong_simulation_stabilizer_rank.git] / strongsim1.c
diff --git a/strongsim1.c b/strongsim1.c
new file mode 100644 (file)
index 0000000..2277799
--- /dev/null
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <complex.h>
+#include "matrix.h"
+#include "exponentialsum.h"
+#include "shrink.h"
+#include "extend.h"
+#include "measurepauli.h"
+#include "innerproduct.h"
+
+int readPaulicoeffs(int *omega, int *alpha, int *beta, int *gamma, int *delta, int numqubits);
+
+// order of matrix elements is [row][column]!!!
+
+int main()
+{
+
+  int N;              // number of qubits
+  scanf("%d", &N);
+
+  int T;              // 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)
+  scanf("%d", &T);
+
+  int omega;
+  int alpha[N], beta[N], gamma[N], delta[N];
+  int Paulicounter = 0;
+
+  int i, j, k, l;
+
+
+  int n1 = 1; int k1 = 0; int (*(G1[])) = { (int[]) {1} }; int (*(GBar1[])) = { (int[]) {1} }; int h1[] = {0}; int Q1 = 0; int D1[] = {0}; int (*(J1[])) = { (int[]) {0} };
+  int n2 = 1; int k2 = 0; int (*(G2[])) = { (int[]) {1} }; int (*(GBar2[])) = { (int[]) {1} }; int h2[] = {1}; int Q2 = 0; int D2[] = {0}; int (*(J2[])) = { (int[]) {0} };
+
+  int *K; int ***G; int ***GBar; int **h; int *Q; int **D; int ***J;
+  double complex Gamma[(int)pow(2,N)]; // prefactor in front of resultant state
+  G = calloc(pow(2,N),sizeof(int*)); GBar = calloc(pow(2,N),sizeof(int*));
+  h = calloc(pow(2,N),sizeof(int*));
+  
+  J = calloc(pow(2,N),sizeof(int*)); D = calloc(pow(2,N),sizeof(int*)); Q = calloc(pow(2,N),sizeof(int));
+
+  K = calloc(pow(2,N), sizeof(int));
+
+  double complex origGamma[(int)pow(2,N)];
+  int *origK, *origQ, **origD, ***origJ;
+  int ***origG, ***origGBar, **origh;
+
+  origG = calloc(pow(2,N),sizeof(int*)); origGBar = calloc(pow(2,N),sizeof(int*));
+  origh = calloc(pow(2,N),sizeof(int*));
+  
+  origJ = calloc(pow(2,N),sizeof(int*)); origD = calloc(pow(2,N),sizeof(int*)); origQ = calloc(pow(2,N),sizeof(int));
+
+  origK = calloc(pow(2,N), sizeof(int));
+
+  int combination; // a particular combination from the linear combo of stabilizer states making up the tensor factors multiplied together
+  
+
+  for(j=0; j<pow(2,N); j++) { // there will be 2^N combinations when using k=1 tensor factors
+    combination = j;
+
+    Gamma[j] = 1.0;
+    
+    G[j] = calloc(N, sizeof(int*)); GBar[j] = calloc(N, sizeof(int*));
+    h[j] = calloc(N, sizeof(int));
+
+    if(K[j] > 0) {
+
+      J[j] = calloc(K[j], sizeof(int*)); D[j] = calloc(K[j], sizeof(int));
+    }
+
+    origG[j] = calloc(N, sizeof(int*)); origGBar[j] = calloc(N, sizeof(int*));
+    origh[j] = calloc(N, sizeof(int));
+    
+    if(K[j] > 0) {
+      origJ[j] = calloc(K[j], sizeof(int*)); origD[j] = calloc(K[j], sizeof(int));
+    }
+
+    for(k=0; k<N; k++) {
+
+      Gamma[j] *= (1.0/sqrt(2.0))*((combination & 0x1)*cexp(0.25*PI*I) + (~combination & 0x1)*cexp(0.0*PI*I));
+      
+      G[j][k] = calloc(N, sizeof(int*)); GBar[j][k] = calloc(N, sizeof(int*));
+
+      if(K[j] > 0)
+       J[j] = calloc(K[j], sizeof(int*));
+
+      origG[j][k] = calloc(N, sizeof(int*)); origGBar[j][k] = calloc(N, sizeof(int*));
+      
+      if(K[j] > 0)
+       origJ[j] = calloc(K[j], sizeof(int*));
+      
+      h[j][k] = (combination & 0x1)*h2[0] + (~combination & 0x1)*h1[0];
+      for(l=0; l<n1; l++) { // assuming n1=n2
+       G[j][k][k*n1+l] = (combination & 0x1)*G2[0][l] + (~combination & 0x1)*G1[0][l];
+       GBar[j][k][k*n1+l] = (combination & 0x1)*GBar2[0][l] + (~combination & 0x1)*GBar1[0][l];
+      }
+      memcpy(origG[j][k], G[j][k], N*sizeof(int)); memcpy(origGBar[j][k], GBar[j][k], N*sizeof(int));
+      
+      combination /= 2; // shift to the right by one (in base-2 arithmetic)
+    }
+
+    memcpy(origh[j], h[j], N*sizeof(int));
+
+  }
+
+  memcpy(origGamma, Gamma, pow(2,N)*sizeof(double complex));
+
+  while(readPaulicoeffs(&omega, alpha, beta, gamma, delta, N)) {
+
+    Paulicounter++;
+    if(Paulicounter > N) {
+      printf("Error: Number of Paulis is greater than N!\n");
+      return 1;
+    }
+    
+    // Let's break up the Ys into Xs and Zs in the order Z X, as required to pass to measurepauli()
+    // Y_i = -I*Z*X
+    for(i=0; i<N; i++) {
+      if(delta[i]){
+       omega += 3; // -I = I^3
+       beta[i] = delta[i];
+       gamma[i] = delta[i];
+      }
+    }
+
+    for(j=0; j<pow(2,N); j++) { // the kets
+
+      Gamma[j] *= measurepauli(N, &K[j], h[j], G[j], GBar[j], &Q[j], &D[j], &J[j], omega, gamma, beta);
+
+    }
+
+  }
+
+  double complex amplitude = 0.0 + 0.0*I;
+  for(i=0; i<pow(2,N); i++) { // the bras
+    for(j=0; j<pow(2,N); j++) {
+      // check to see if second arguments are modified!!! They shouldn't be!
+      double complex newamplitude = conj(origGamma[i])*Gamma[j]*innerproduct(N, K[j], h[j], G[j], GBar[j], Q[j], D[j], J[j], N, origK[i], origh[i], origG[i], origGBar[i], origQ[i], origD[i], origJ[i]);
+      amplitude = amplitude + newamplitude;
+    }
+  }
+
+  printf("amplitude:\n");
+  if(creal(amplitude+0.00000001)>0)
+    printf("%lf %c %lf I\n", cabs(creal(amplitude)), cimag(amplitude)>0?'+':'-' , cabs(cimag(amplitude)));
+  else
+    printf("%lf %c %lf I\n", creal(amplitude), cimag(amplitude)>0?'+':'-' , cabs(cimag(amplitude)));
+
+  return 0;
+
+}
+
+
+
+int readPaulicoeffs(int *omega, int *alpha, int *beta, int *gamma, int *delta, int numqubits)
+{
+    
+  int newomega, newalpha, newbeta, newgamma, newdelta;
+  int i;
+
+  if(scanf("%d", &newomega) != EOF) {
+    *omega = newomega;
+    for(i=0; i<numqubits; i++) {
+      if(scanf("%d %d %d %d", &newalpha, &newbeta, &newgamma, &newdelta) == EOF) {
+       printf("Error: Too few input coeffs!\n");
+       exit(0);
+      }
+      if(newalpha+newbeta+newgamma+newdelta > 1) {
+       printf("Error: Too many coefficients are non-zero at Pauli %d!\n", i);
+       exit(0);
+      }
+      alpha[i] = newalpha; beta[i] = newbeta; gamma[i] = newgamma; delta[i] = newdelta;
+    }
+    return 1;
+  } else
+    return 0;
+    
+}
+
+
+
+
+
+
+