quantum_reg quantum_new_qureg( unsigned long long initval, int width ) { quantum_reg reg; char *c; reg.width = width; reg.size = 1; reg.hashw = width + 2; reg.node = calloc( 1, sizeof( quantum_reg_node ) ); if ( reg.node == 0 ) quantum_error( 2 ); quantum_memman( 16 ); reg.hash = calloc( 1 << reg.hashw, sizeof( int ) ); if ( reg.hash == 0 ) quantum_error( 2 ); quantum_memman( 4 << reg.hashw ); reg.node->state = initval; reg.node->amplitude = 1.000000000000; c = getenv( "QUOBFILE" ); if ( c != 0 ) { quantum_objcode_start( ); quantum_objcode_file( c ); atexit( &quantum_objcode_exit ); } quantum_objcode_put( 0, initval ); return reg; }
MAX_UNSIGNED quantum_measure(quantum_reg reg) { double r; int i; if(quantum_objcode_put(MEASURE)) return 0; /* Get a random number between 0 and 1 */ r = quantum_frand(); for (i=0; i<reg.size; i++) { /* If the random number is less than the probability of the given base state - r, return the base state as the result. Otherwise, continue with the next base state. */ r -= quantum_prob_inline(reg.node[i].amplitude); if(0.0 >= r) return reg.node[i].state; } /* The sum of all probabilities is less than 1. Usually, the cause for this is the application of a non-normalized matrix, but there is a slim chance that rounding errors may lead to this as well. */ return -1; }
int quantum_bmeasure(int pos, quantum_reg *reg) { int i; int result=0; double pa=0, r; MAX_UNSIGNED pos2; quantum_reg out; if(quantum_objcode_put(BMEASURE, pos)) return 0; pos2 = (MAX_UNSIGNED) 1 << pos; /* Sum up the probability for 0 being the result */ for(i=0; i<reg->size; i++) { if(!(reg->node[i].state & pos2)) pa += quantum_prob_inline(reg->node[i].amplitude); } /* Compare the probability for 0 with a random number and determine the result of the measurement */ r = quantum_frand(); if (r > pa) result = 1; out = quantum_state_collapse(pos, result, *reg); quantum_delete_qureg_hashpreserve(reg); *reg = out; return result; }
int quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg) { int i, j; int size=0, result=0; double d=0, pa=0, r; MAX_UNSIGNED pos2; quantum_reg out; if(quantum_objcode_put(BMEASURE_P, pos)) return 0; pos2 = (MAX_UNSIGNED) 1 << pos; /* Sum up the probability for 0 being the result */ for(i=0; i<reg->size; i++) { if(!(reg->node[i].state & pos2)) pa += quantum_prob_inline(reg->node[i].amplitude); } /* Compare the probability for 0 with a random number and determine the result of the measurement */ r = quantum_frand(); if (r > pa) result = 1; /* Eradicate all amplitudes of base states which have been ruled out by the measurement and get the absolute of the new register */ for(i=0;i<reg->size;i++) { if(reg->node[i].state & pos2) { if(!result) reg->node[i].amplitude = 0; else { d += quantum_prob_inline(reg->node[i].amplitude); size++; } } else { if(result) reg->node[i].amplitude = 0; else { d += quantum_prob_inline(reg->node[i].amplitude); size++; } } } /* Build the new quantum register */ out.size = size; out.node = calloc(size, sizeof(quantum_reg_node)); if(!out.node) { printf("Not enough memory for %i-sized qubit!\n", size); exit(1); } quantum_memman(size * sizeof(quantum_reg_node)); out.hashw = reg->hashw; out.hash = reg->hash; out.width = reg->width; /* Determine the numbers of the new base states and norm the quantum register */ for(i=0, j=0; i<reg->size; i++) { if(reg->node[i].amplitude) { out.node[j].state = reg->node[i].state; out.node[j].amplitude = reg->node[i].amplitude * 1 / (float) sqrt(d); j++; } } quantum_delete_qureg_hashpreserve(reg); *reg = out; return result; }