/** * \brief Creates a new \ref sc_dp_qc * * \param[in] args The args structure as filled from the command line * \param[in] recipe The recipe the \ref sc_dp_qc will use for computation */ SC_DP_QC *create_sc_dp_qc(ARGS *args, RECIPE_ADV *recipe) { SC_DP_QC *sc_dp_qc; QC *qc; int i, j, d, n; QUBIT ***q_arr; sc_dp_qc = (SC_DP_QC *)my_malloc(sizeof(SC_DP_QC)); sc_dp_qc->d = d = args->d; sc_dp_qc->n = n = 2*d - 1; sc_dp_qc->ems = args->ems; sc_dp_qc->t1 = double_time(); sc_dp_qc->num_checks = 0; sc_dp_qc->last_X_check = 0; sc_dp_qc->last_Z_check = 0; sc_dp_qc->num_X_changes = 0; sc_dp_qc->num_Z_changes = 0; // Create a new dp_qc for the sc_dp_qc sc_dp_qc->dp_qc = dp_create_dp_qc_adv(args->s0, args->s1, DE_HT_FACTOR * n * n, STICK_HT_FACTOR * d * d, args->p, args->t_delete, recipe, args->ems); // Create an n by n Pauli frame sc_dp_qc->frame = (int **)my_2d_calloc(n, n, sizeof(int)); // Create an n by n array of qubits sc_dp_qc->q_arr = q_arr = (QUBIT ***)my_2d_calloc(n, n, sizeof(QUBIT *)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { q_arr[i][j] = qc_create_and_insert_qubit(sc_dp_qc->dp_qc->qc, i, j, 0, QUBIT_HT_SIZE); } } // Allocate space for boundaries, and then create and insert them // The location of boundaries is irrelevant, but a sensible choice is good for debugging qc = sc_dp_qc->dp_qc->qc; sc_dp_qc->boundaries = (BALL **)my_malloc(8 * sizeof(BALL *)); sc_dp_qc->bdy_s1_pr = create_boundary_set(qc, sc_dp_qc->boundaries, 0, PRIMAL_BOUNDARY, -1, 0, 0); sc_dp_qc->bdy_s2_pr = create_boundary_set(qc, sc_dp_qc->boundaries, 1, PRIMAL_BOUNDARY, -2, 0, 0); sc_dp_qc->bdy_t1_pr = create_boundary_set(qc, sc_dp_qc->boundaries, 2, PRIMAL_BOUNDARY, -1, 1, 0); sc_dp_qc->bdy_t2_pr = create_boundary_set(qc, sc_dp_qc->boundaries, 3, PRIMAL_BOUNDARY, -2, 1, 0); sc_dp_qc->bdy_s1_du = create_boundary_set(qc, sc_dp_qc->boundaries, 4, DUAL_BOUNDARY, -1, 0, 0); sc_dp_qc->bdy_s2_du = create_boundary_set(qc, sc_dp_qc->boundaries, 5, DUAL_BOUNDARY, -2, 0, 0); sc_dp_qc->bdy_t1_du = create_boundary_set(qc, sc_dp_qc->boundaries, 6, DUAL_BOUNDARY, -1, 1, 0); sc_dp_qc->bdy_t2_du = create_boundary_set(qc, sc_dp_qc->boundaries, 7, DUAL_BOUNDARY, -2, 1, 0); qc->get_boundary = get_boundary; qc->boundaries = (void *)sc_dp_qc->boundaries; // Create the Primal and Dual syndrome and set arrays create_initial_syndrome_and_set_arrays(sc_dp_qc, PRIMAL, d, d-1, sc_dp_qc->bdy_s1_pr, sc_dp_qc->bdy_s2_pr); create_initial_syndrome_and_set_arrays(sc_dp_qc, DUAL, d-1, d, sc_dp_qc->bdy_s1_du, sc_dp_qc->bdy_s2_du); return sc_dp_qc; }
/** * \brief Copies a \ref sc_dp_qc * * \param[in] sc_dp_qc The \ref sc_dp_qc to be copied * * \return The newly copied \ref sc_dp_qc */ SC_DP_QC *copy_sc_dp_qc(SC_DP_QC *sc_dp_qc) { SC_DP_QC *sc_dp_qc2; int i, j; int is, js; int d, n; d = sc_dp_qc->d; n = sc_dp_qc->n; sc_dp_qc2 = (SC_DP_QC *)my_malloc(sizeof(SC_DP_QC)); // Copy values from sc_dp_qc to sc_dp_qc2 *sc_dp_qc2 = *sc_dp_qc; // Copy the dp_qc sc_dp_qc2->dp_qc = dp_copy_dp_qc(sc_dp_qc->dp_qc); // Copy the frame sc_dp_qc2->frame = (int **)my_2d_calloc(n, n, sizeof(int)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { sc_dp_qc2->frame[i][j] = sc_dp_qc->frame[i][j]; } } // Copy the qubits sc_dp_qc2->q_arr = (QUBIT ***)my_2d_calloc(n, n, sizeof(QUBIT *)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { sc_dp_qc2->q_arr[i][j] = sc_dp_qc->q_arr[i][j]->copy; } } // Copy the PRIMAL syndrome and set arrays sc_dp_qc2->syn_arr_pr = (SYNDROME ***)my_2d_calloc(d, d-1, sizeof(SYNDROME *)); sc_dp_qc2->set_arr_pr = (SET ****)my_3d_calloc(d, d-1, 2, sizeof(SET *)); for (is = 0; is < d; is++) { for (js = 0; js < d-1; js++) { sc_dp_qc2->syn_arr_pr[is][js] = sc_dp_qc->syn_arr_pr[is][js]->copy; sc_dp_qc2->set_arr_pr[is][js][0] = sc_dp_qc->set_arr_pr[is][js][0]->copy; sc_dp_qc2->set_arr_pr[is][js][1] = sc_dp_qc->set_arr_pr[is][js][1]->copy; } } // Copy the DUAL syndrom and set arrays sc_dp_qc2->syn_arr_du = (SYNDROME ***)my_2d_calloc(d-1, d, sizeof(SYNDROME *)); sc_dp_qc2->set_arr_du = (SET ****)my_3d_calloc(d-1, d, 2, sizeof(SET *)); for (is = 0; is < d-1; is++) { for (js = 0; js < d; js++) { sc_dp_qc2->syn_arr_du[is][js] = sc_dp_qc->syn_arr_du[is][js]->copy; sc_dp_qc2->set_arr_du[is][js][0] = sc_dp_qc->set_arr_du[is][js][0]->copy; sc_dp_qc2->set_arr_du[is][js][1] = sc_dp_qc->set_arr_du[is][js][1]->copy; } } return sc_dp_qc2; }
/** * \brief Creates the initial; syndrome and set arrays * * Creates an array of syndromes with a new syndrome created at each point. It * then creates initial sets associated with the first round of measurements. * * \param[in] scp_dp_qc The \ref sc_dp_qc to build the \ref syndrome and \ref set arrays in * \param[in] type The type of arrays to make (PRIMAL, DUAL) * \param[in] imax The size of the i dimension * \param[in] jmax The size of the j dimension * \param[in] bdy_s1 The first space boundary to connect to * \param[in] bdy_s2 The second space boundary to connect to */ void create_initial_syndrome_and_set_arrays(SC_DP_QC *sc_dp_qc, int type, int imax, int jmax, SET *bdy_s1, SET *bdy_s2) { int seti, setj; int is, js, bs, bmax; SYNDROME ***syn_arr; SET ****set_arr; syn_arr = (SYNDROME ***)my_2d_calloc(imax, jmax, sizeof(SYNDROME *)); set_arr = (SET ****)my_3d_calloc(imax, jmax, 2, sizeof(SET *)); for (is = 0; is < imax; is++) { for (js = 0; js < jmax; js++) { // Create and insert a new syndrome into the syndrome array syn_arr[is][js] = qc_create_syndrome(); qc_insert_syndrome(sc_dp_qc->dp_qc->qc, syn_arr[is][js]); // Calculate the coordinate relative to the full frame if (type == PRIMAL) { seti = (is << 1); setj = (js << 1) + 1; bs = js; bmax = jmax; } else { seti = (is << 1) + 1; setj = (js << 1); bs = is; bmax = imax; } if (bs == 0) { // Create a set with the first boundary set_arr[is][js][1] = qc_create_set(type, seti, setj, 1, bdy_s1); set_arr[is][js][0] = qc_create_set(type, seti, setj, 2, bdy_s1); } else if (bs == bmax-1) { // Create a set with the second boundary set_arr[is][js][1] = qc_create_set(type, seti, setj, 1, bdy_s2); set_arr[is][js][0] = qc_create_set(type, seti, setj, 2, bdy_s2); } else { // Create a set with no boundary set_arr[is][js][1] = qc_create_set(type, seti, setj, 1, NULL); set_arr[is][js][0] = qc_create_set(type, seti, setj, 2, NULL); } // Insert the new set into the set array, and associate the set with a syndrome qc_insert_set(sc_dp_qc->dp_qc->qc, set_arr[is][js][1]); qc_associate_syndrome(set_arr[is][js][1], syn_arr[is][js]); qc_insert_set(sc_dp_qc->dp_qc->qc, set_arr[is][js][0]); } } // Store the set and syndrome arrays in the sc_dp_qc if (type == PRIMAL) { sc_dp_qc->syn_arr_pr = syn_arr; sc_dp_qc->set_arr_pr = set_arr; } else { sc_dp_qc->syn_arr_du = syn_arr; sc_dp_qc->set_arr_du = set_arr; } }