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; }
quantum_reg quantum_state_collapse( int pos, int value, quantum_reg reg ) { int i, j, k; int size = 0; double d = 0.000000000000; unsigned long long lpat = 0, rpat = 0, pos2 = (long long)1 << pos; quantum_reg out; i = 0; for ( ; i < reg.size; i++ ) { if ( ( ( reg.node[ i ].state & pos2 ) != 0 && value != 0 ) || ( ( reg.node[ i ].state & pos2 ) == 0 && value == 0 ) ) { d += quantum_prob_inline( reg.node[ i ].amplitude ); size++; } //i++; } out.width = reg.width - 1; out.size = size; out.node = calloc( size, sizeof( quantum_reg_node ) ); if ( out.node == 0 ) quantum_error( 2 ); quantum_memman( size << 4 ); out.hashw = reg.hashw; out.hash = reg.hash; i = 0; j = 0; for ( ; i < reg.size; i++ ) { if ( ( ( reg.node[ i ].state & pos2 ) != 0 && value != 0 ) || ( ( reg.node[ i ].state & pos2 ) == 0 && value == 0 ) ) { k = 0; rpat = 0; for ( ; k < pos; k++ ) { rpat += (long long)1 << k; //k++; } rpat &= reg.node[ i ].state; k = 63; lpat = 0; for ( ; pos < k; k-- ) { lpat += (long long)1 << k; //k--; } lpat &= reg.node[ i ].state; out.node[ j ].state = rpat | ( lpat >> 1 ); if ( (bit)( 0 ) ) { } out.node[ j ].amplitude = reg.node[ i ].amplitude / sqrt( d ); j++; } //i++; }
void quantum_reduced_density_op( int pos, quantum_density_op *rho ) { int i, j; double p0 = 0.000000000000, ptmp; unsigned long long pos2; quantum_reg rtmp; rho->prob = realloc( rho->prob, rho->num << 3 ); if ( rho->prob == 0 ) quantum_error( 2 ); rho->reg = realloc( rho->reg, rho->num * 40 ); if ( rho->reg == 0 ) quantum_error( 2 ); quantum_memman( rho->num * 24 ); pos2 = (long long)1 << pos; i = 0; for ( ; i < rho->num; i++ ) { ptmp = rho->prob[ i ]; rtmp.width = rho->reg[ i ].width; rtmp.size = rho->reg[ i ].size; rtmp.hashw = rho->reg[ i ].hashw; rtmp.node = rho->reg[ i ].node; rtmp.hash = rho->reg[ i ].hash; p0 = 0.000000000000; j = 0; for ( ; j < rho->reg[ i ].size; j++ ) { if ( ( rho->reg[ i ].node[ j ].state & pos2 ) == 0 ) { p0 += quantum_prob_inline( rho->reg[ i ].node[ j ].amplitude ); } //j++; } rho->prob[ i ] = ptmp * p0; rho->prob[ rho->num + i ] = ptmp * ( 1.000000000000 - p0 ); rho->reg[ i ] = quantum_state_collapse( pos, 0, rtmp ); rho->reg[ rho->num + i ] = quantum_state_collapse( pos, 1, rtmp ); quantum_delete_qureg_hashpreserve( &rtmp ); //i++; } rho->num <<= 1; return; }
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; }
void quantum_print_qureg( quantum_reg reg ) { int i = 0, j; for ( ; i < reg.size; i++ ) { printf( "% f %+fi|%lli> (%e) (|", quantum_real( reg.node[ i ].amplitude ), quantum_imag( reg.node[ i ].amplitude ), reg.node[ i ].state, quantum_prob_inline( reg.node[ i ].amplitude ) ); j = reg.width - 1; for ( ; j >= 0; j-- ) { if ( ( j % 4 ) == 3 ) putchar( 32 ); printf( "%i", (int)( reg.node[ i ].state >> (unsigned char)( j ) ) & 1 ); //j--; } puts( ">)" ); //i++; } putchar( 10 ); return; }
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; }