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; }
quantum_reg quantum_kronecker( quantum_reg *reg1, quantum_reg *reg2 ) { int i, j; quantum_reg reg; reg.width = reg2->width + reg1->width; reg.size = reg2->size * reg1->size; reg.hashw = ( reg2->size * reg1->size ) + 2; reg.node = calloc( reg.size, sizeof( quantum_reg_node ) ); if ( reg.node == 0 ) quantum_error( 2 ); quantum_memman( reg.size << 4 ); reg.hash = calloc( 1 << reg.hashw, sizeof( int ) ); if ( reg.hash == 0 ) quantum_error( 2 ); quantum_memman( 4 << reg.hashw ); i = 0; for ( ; i < reg1->size; i++ ) { j = 0; for ( ; j < reg2->size; j++ ) { reg.node[ j + ( reg2->size * i ) ].state = reg2->node[ j ].state | ( reg1->node[ i ].state << reg2->width ); reg.node[ j + ( reg2->size * i ) ].amplitude = reg2->node[ j ].amplitude * reg1->node[ i ].amplitude; //j++; } //i++; } return reg; }
quantum_matrix quantum_density_matrix( quantum_density_op *rho ) { int i, j, k, l1, l2, dim = 1 << rho->reg->width; quantum_matrix m; if ( dim < 0 ) quantum_error( 3 ); m = quantum_new_matrix( dim, dim ); k = 0; for ( ; k < rho->num; k++ ) { quantum_reconstruct_hash( &rho->reg[ k ] ); i = 0; for ( ; i < dim; i++ ) { j = 0; for ( ; j < dim; j++ ) { l1 = quantum_get_state( i, rho->reg[ k ] ); l2 = quantum_get_state( j, rho->reg[ k ] ); if ( l1 >= 0 && l2 >= 0 ) { m.t[ i + ( m.cols * j ) ] += rho->reg[ k ].node[ l2 ].amplitude * rho->prob[ k ] * quantum_conj( rho->reg[ k ].node[ l1 ].amplitude ); } //j++; } //i++; } //k++; } return m; }
quantum_matrix quantum_mmult( quantum_matrix A, quantum_matrix B ) { int i, j, k; quantum_matrix C; if ( A.cols != B.rows ) quantum_error( 4 ); C = quantum_new_matrix( B.cols, A.rows ); i = 0; for ( ; i < B.cols; i++ ) { j = 0; for ( ; j < A.rows; j++ ) { k = 0; for ( ; k < B.rows; k++ ) { C.t[ i + ( C.cols * j ) ] += B.t[ i + ( B.cols * k ) ] * A.t[ k + ( A.cols * j ) ]; //k++; } //j++; } //i++; } return C; }
quantum_density_op quantum_new_density_op( int num, float *prob, quantum_reg *reg ) { int i; quantum_density_op rho; int *phash; int hashw; rho.num = num; rho.prob = calloc( num, sizeof( float ) ); if ( rho.prob == 0 ) quantum_error( 2 ); rho.reg = calloc( num, sizeof( quantum_reg ) ); if ( rho.reg == 0 ) quantum_error( 2 ); quantum_memman( num * 24 ); rho.prob[0] = prob[0]; phash = reg->hash; hashw = reg->hashw; rho.reg->width = reg->width; rho.reg->size = reg->size; rho.reg->hashw = reg->hashw; rho.reg->node = reg->node; rho.reg->hash = reg->hash; reg->size = 0; reg->width = 0; reg->node = 0; reg->hash = 0; i = 1; for ( ; i < num; i++ ) { rho.prob[ i ] = prob[ i ]; rho.reg[ i ].width = reg[ i ].width; rho.reg[ i ].size = reg[ i ].size; rho.reg[ i ].hashw = reg[ i ].hashw; rho.reg[ i ].node = reg[ i ].node; rho.reg[ i ].hash = reg[ i ].hash; rho.reg[ i ].hash = phash; rho.reg[ i ].hashw = hashw; reg[ i ].size = 0; reg[ i ].width = 0; reg[ i ].node = 0; reg[ i ].hash = 0; //i++; } return rho; }
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; }
quantum_matrix quantum_new_matrix( int cols, int rows ) { quantum_matrix m; m.rows = rows; m.cols = cols; m.t = calloc( rows * cols, sizeof( float _Complex ) ); if ( m.t == 0 ) quantum_error( 2 ); quantum_memman( ( rows * cols ) << 3 ); return m; }
void quantum_copy_qureg( quantum_reg *src, quantum_reg *dst ) { dst->width = src->width; dst->size = src->size; dst->hashw = src->hashw; dst->node = src->node; dst->hash = src->hash; dst->node = calloc( dst->size, sizeof( quantum_reg_node ) ); if ( dst->node == 0 ) quantum_error( 2 ); quantum_memman( dst->size << 4 ); if ( dst->hashw != 0 ) { dst->hash = calloc( 1 << dst->hashw, sizeof( int ) ); if ( dst->hash == 0 ) quantum_error( 2 ); quantum_memman( 4 << dst->hashw ); } memcpy( dst->node, src->node, src->size << 4 ); return; }
void quantum_objcode_start() { opstatus = 1; allocated = 1; objcode = malloc(OBJCODE_PAGE * sizeof(char)); if(!objcode) quantum_error(QUANTUM_ENOMEM); quantum_memman(OBJCODE_PAGE * sizeof(char)); }
void quantum_decohere( quantum_reg *reg ) { float u, v, s, x; float *nrands; float angle; int i, j; quantum_gate_counter( 1 ); if ( quantum_status != 0 ) { nrands = calloc( reg->width, sizeof( float ) ); if ( nrands == 0 ) quantum_error( 2 ); quantum_memman( reg->width << 2 ); i = 0; for ( ; i < reg->width; i++ ) { do { u = ( quantum_frand( ) * (double)( 2 ) ) - 1.000000000000; v = ( quantum_frand( ) * (double)( 2 ) ) - 1.000000000000; s = ( u * u ) + ( v * v ); } while ( (bit)( 0 ) ); if ( (bit)( 0 ) ) { } x = sqrt( ( log( s ) * -2.000000000000 ) / s ) * u; x *= sqrt( quantum_lambda + quantum_lambda ); nrands[ i ] = x / 2.000000000000; //i++; } i = 0; for ( ; i < reg->size; i++ ) { angle = 0.0; j = 0; for ( ; j < reg->width; j++ ) { if ( reg->node[ i ].state & ( (long long)1 << j ) ) angle += nrands[ j ]; else angle -= nrands[ j ]; //j++; } reg->node[ i ].amplitude *= quantum_cexp( angle ); //i++; } free( nrands ); quantum_memman( reg->width * -4 ); } return; }
quantum_reg quantum_new_qureg_size( int n, int width ) { quantum_reg reg; reg.width = width; reg.size = n; reg.hashw = 0; reg.hash = 0; reg.node = calloc( n, sizeof( quantum_reg_node ) ); if ( reg.node == 0 ) quantum_error( 2 ); quantum_memman( n << 4 ); return reg; }
quantum_reg quantum_matrix2qureg( quantum_matrix *m, int width ) { quantum_reg reg; int i, j, size = 0; if ( m->cols != 1 ) quantum_error( 65536 ); reg.width = width; i = 0; for ( ; i < m->rows; i++ ) { if ( 0 != 1 || 1 == 0 ) size++; //i++; } reg.size = size; reg.hashw = width + 2; reg.node = calloc( size, sizeof( quantum_reg_node ) ); if ( reg.node == 0 ) quantum_error( 2 ); quantum_memman( size << 4 ); reg.hash = calloc( 1 << reg.hashw, sizeof( int ) ); if ( reg.hash == 0 ) quantum_error( 2 ); quantum_memman( 4 << reg.hashw ); i = 0; j = 0; for ( ; i < m->rows; i++ ) { if ( 0 != 1 || 1 == 0 ) { reg.node[ j ].state = i; reg.node[ j ].amplitude = m->t[ i ]; j++; } //i++; } return reg; }
void quantum_objcode_run(char *file, quantum_reg *reg) { int i, j, k, l; FILE *fhd; unsigned char operation; unsigned char buf[OBJBUF_SIZE]; MAX_UNSIGNED mu; double d; fhd = fopen(file, "r"); if(!fhd) { fprintf(stderr, "quantum_objcode_run: Could not open %s: ", file); perror(0); return; } for(i=0; !feof(fhd); i++) { for(j=0; j<OBJBUF_SIZE; j++) buf[j] = 0; operation = fgetc(fhd); switch(operation) { case INIT: if(!fread(buf, sizeof(MAX_UNSIGNED), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } mu = quantum_char2mu(buf); *reg = quantum_new_qureg(mu, 12); break; case CNOT: case COND_PHASE: if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } j = quantum_char2int(buf); if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } k = quantum_char2int(buf); switch(operation) { case CNOT: quantum_cnot(j, k, reg); break; case COND_PHASE: quantum_cond_phase(j, k, reg); break; } break; case TOFFOLI: if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } j = quantum_char2int(buf); if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } k = quantum_char2int(buf); if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } l = quantum_char2int(buf); quantum_toffoli(j, k, l, reg); break; case SIGMA_X: case SIGMA_Y: case SIGMA_Z: case HADAMARD: case BMEASURE: case BMEASURE_P: case SWAPLEADS: if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } j = quantum_char2int(buf); switch(operation) { case SIGMA_X: quantum_sigma_x(j, reg); break; case SIGMA_Y: quantum_sigma_y(j, reg); break; case SIGMA_Z: quantum_sigma_z(j, reg); break; case HADAMARD: quantum_hadamard(j, reg); break; case BMEASURE: quantum_bmeasure(j, reg); break; case BMEASURE_P: quantum_bmeasure_bitpreserve(j, reg); break; case SWAPLEADS: quantum_swaptheleads(j, reg); break; } break; case ROT_X: case ROT_Y: case ROT_Z: case PHASE_KICK: case PHASE_SCALE: if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } j = quantum_char2int(buf); if(!fread(buf, sizeof(double), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } d = quantum_char2double(buf); switch(operation) { case ROT_X: quantum_r_x(j, d, reg); break; case ROT_Y: quantum_r_y(j, d, reg); break; case ROT_Z: quantum_r_z(j, d, reg); break; case PHASE_KICK: quantum_phase_kick(j, d, reg); break; case PHASE_SCALE: quantum_phase_scale(j, d, reg); break; } break; case CPHASE_KICK: if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } j = quantum_char2int(buf); if(!fread(buf, sizeof(int), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } k = quantum_char2int(buf); if(!fread(buf, sizeof(double), 1, fhd)) { quantum_error(QUANTUM_FAILURE); break; } d = quantum_char2double(buf); quantum_cond_phase_kick(j, k, d, reg); break; case MEASURE: quantum_measure(*reg); break; case NOP: break; default: fprintf(stderr, "%i: Unknown opcode 0x(%X)!\n", i, operation); return; } } fclose(fhd); }
int quantum_objcode_put(unsigned char operation, ...) { int i, size = 0; va_list args; unsigned char buf[80]; double d; MAX_UNSIGNED mu; if(!opstatus) return 0; va_start(args, operation); buf[0] = operation; switch(operation) { case INIT: mu = va_arg(args, MAX_UNSIGNED); quantum_mu2char(mu, &buf[1]); size = sizeof(MAX_UNSIGNED) + 1; break; case CNOT: case COND_PHASE: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); size = 2 * sizeof(int) + 1; break; case TOFFOLI: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); i = va_arg(args, int); quantum_int2char(i, &buf[2*sizeof(int)+1]); size = 3 * sizeof(int) + 1; break; case SIGMA_X: case SIGMA_Y: case SIGMA_Z: case HADAMARD: case BMEASURE: case BMEASURE_P: case SWAPLEADS: i = va_arg(args, int); quantum_int2char(i, &buf[1]); size = sizeof(int) + 1; break; case ROT_X: case ROT_Y: case ROT_Z: case PHASE_KICK: case PHASE_SCALE: i = va_arg(args, int); d = va_arg(args, double); quantum_int2char(i, &buf[1]); quantum_double2char(d, &buf[sizeof(int)+1]); size = sizeof(int) + sizeof(double) + 1; break; case CPHASE_KICK: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); d = va_arg(args, double); quantum_double2char(d, &buf[2*sizeof(int)+1]); size = 2 * sizeof(int) + sizeof(double) + 1; break; case MEASURE: case NOP: size = 1; break; default: quantum_error(QUANTUM_EOPCODE); } if((position+size) / OBJCODE_PAGE > position / OBJCODE_PAGE) { allocated++; objcode = realloc(objcode, allocated * OBJCODE_PAGE); if(!objcode) quantum_error(QUANTUM_ENOMEM); quantum_memman(OBJCODE_PAGE * sizeof(char)); } for(i=0; i<size; i++) { objcode[position] = buf[i]; position++; } return 1; }