EncryptedColVector LinearAlgebra::extract_col()

in src/hit/api/linearalgebra/linearalgebra.cpp [517:558]


    EncryptedColVector LinearAlgebra::extract_col(const EncryptedMatrix &enc_mat_b_trans, int col) {
        EncodingUnit unit = enc_mat_b_trans.encoding_unit();

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

        // compute which unit row the desired column is in
        int unit_row = col / unit.encoding_height();
        // row_in_unit is the row within the encoding unit that contains the masked row
        int row_in_unit = col % unit.encoding_height();

        // create the column mask encoding unit
        for (size_t i = 0; i < enc_mat_b_trans.num_slots(); i++) {
            if (i / unit.encoding_width() == row_in_unit) {
                row_mask[i] = 1;
            } else {
                row_mask[i] = 0;
            }
        }

        vector<CKKSCiphertext> isolated_row_cts(enc_mat_b_trans.num_horizontal_units());
        parallel_for(enc_mat_b_trans.num_horizontal_units(), [&](int j) {
            isolated_row_cts[j] = eval.multiply_plain(enc_mat_b_trans.cts[unit_row][j], row_mask);
            eval.rescale_to_next_inplace(isolated_row_cts[j]);
            // we now have isolated the k^th row of B^T. To get an encoding of the k^th column of B
            // we need to replicate this row across all rows of the encoding unit

            // An easy way to do this is to invoke sum_rows,
            // but it requires some packing and unpacking.
            // [Note: sum_rows nominally spawns new threads, but this matrix only has a
            //  single unit, so no additional threads are created.
            // First, compute the j^th component of the k^th column of B
            // Then place it in isolated_row_cts
            isolated_row_cts[j] = sum_rows_core(
                EncryptedMatrix(unit.encoding_height(), unit.encoding_width(), unit,
                                vector<vector<CKKSCiphertext>>{vector<CKKSCiphertext>{isolated_row_cts[j]}}),
                0, false);
        });
        return EncryptedColVector(enc_mat_b_trans.width(), unit, isolated_row_cts);
    }