EncryptedRowVector LinearAlgebra::extract_row()

in src/hit/api/linearalgebra/linearalgebra.cpp [561:599]


    EncryptedRowVector LinearAlgebra::extract_row(const EncryptedMatrix &enc_mat_a_trans, int row) {
        EncodingUnit unit = enc_mat_a_trans.encoding_unit();

        // create a mask for the k^th column of A^T, which is the k^th row of A
        // col_mask is a single encoding unit which will be replicated for every
        // vertical unit of the encoding of A^T
        vector<double> col_mask(enc_mat_a_trans.num_slots());

        // compute which unit column the desired row is in
        int unit_col = row / unit.encoding_width();
        // col_in_unit is the column within the encoding unit that contains the masked column
        int col_in_unit = row % unit.encoding_width();

        // create the column mask encoding unit
        for (size_t i = 0; i < enc_mat_a_trans.num_slots(); i++) {
            if (i % unit.encoding_width() == col_in_unit) {
                col_mask[i] = 1;
            } else {
                col_mask[i] = 0;
            }
        }

        vector<CKKSCiphertext> isolated_col_cts(enc_mat_a_trans.num_vertical_units());
        parallel_for(enc_mat_a_trans.num_vertical_units(), [&](int i) {
            isolated_col_cts[i] = eval.multiply_plain(enc_mat_a_trans.cts[i][unit_col], col_mask);
            eval.rescale_to_next_inplace(isolated_col_cts[i]);
            // we now have isolated the k^th column of A^T. To get an encoding of the k^th row of A
            // we need to replicate this column across all columns of the encoding unit

            // first step is to shift the column to the left
            if (col_in_unit != 0) {
                eval.rotate_left_inplace(isolated_col_cts[i], col_in_unit);
            }

            // now replicate this column to all other columns of the unit
            rot(isolated_col_cts[i], unit.encoding_width(), 1, false);
        });
        return EncryptedRowVector(enc_mat_a_trans.height(), unit, isolated_col_cts);
    }