3

我目前正在尝试使用 Microsoft SEAL 库实现矩阵乘法方法。我创建了一个vector<vector<double>>作为输入矩阵并用CKKSEncoder. 然而,编码器将整个向量打包成一个向量,Plaintext所以我只有一个vector<Plaintext>,这让我失去了 2D 结构(当然我会有一个vector<Ciphertext>后加密)。拥有一维向量允许我完全访问行而不访问列。

我设法在编码之前转置矩阵。这允许我将第一个矩阵的行和第二个矩阵的列(转置形式的行)按分量相乘,但我无法将结果向量的元素加在一起,因为它被打包成一个密文。我只需要弄清楚如何使向量点积在 SEAL 中工作以执行矩阵乘法。我错过了什么还是我的方法错了?

4

2 回答 2

2

KyoohyungHan 在问题中建议:https ://github.com/microsoft/SEAL/issues/138可以通过旋转输出向量并重复求和来解决旋转问题。

例如:

// my_output_vector is the Ciphertext output

vector<Ciphertext> rotations_output(my_output_vector.size());

for(int steps = 0; steps < my_output_vector.size(); steps++)
{
    evaluator.rotate_vector(my_output_vector, steps, galois_keys, rotations_output[steps]);
}

Ciphertext sum_output;
evaluator.add_many(rotations_output, sum_output);
于 2020-02-17T13:59:12.580 回答
-1

向量的向量与数组的数组(二维,矩阵)不同。

虽然一维vector<double>.data()指向连续的内存空间(例如,您可以这样做memcpy),但每个“子向量”都分配自己的独立内存缓冲区。因此vector<vector<double>>.data()没有意义,不能用作矩阵。

在 C++ 中,二维数组array2D[W][H]array[W*H]. 因此,两者都可以由相同的例程处理(当它有意义时)。考虑以下示例:

void fill_array(double *array, size_t size, double value) {
    for (size_t i = 0; i < size; ++i) {
        array[i] = value;
    }
}

int main(int argc, char *argv[])
{
    constexpr size_t W = 10;
    constexpr size_t H = 5;
    double matrix[W][H];
    // using 2D array as 1D to fill all elements with 5.
    fill_array(&matrix[0][0], W * H, 5);
    for (const auto &row: matrix) {
        for (const auto v : row) {
            cout << v << '\t';
        }
        cout << '\n';
    }

    return 0;
}

在上面的示例中,您可以double matrix[W][H];替换vector<double> matrix(W * H);matrix.data()输入fill_array(). 但是,您不能声明vector(H) 的vector(W)。

PS有很多数学向量和矩阵的C++实现。如果您不想处理 C 样式的数组,可以使用其中之一。

于 2020-02-13T08:58:54.537 回答