犰狳C++:带有模量计算的线性组合



我想从矩阵中提取线性组合,但要通过模数执行组合。

让我们考虑计算模数 5,然后我们有以下内容进行加法:

+ |  0 1 2 3 4
--+-----------
0 | 0 1 2 3 4
1 | 1 2 3 4 0
2 | 2 3 4 0 1
3 | 3 4 0 1 2 
4 | 4 0 1 2 3

和这个乘法表:

* | 0 1 2 3 4
--+-----------
0 | 0 0 0 0 0
1 | 0 1 2 3 4
2 | 0 2 4 1 3
3 | 0 3 1 4 2
4 | 0 4 3 2 1

因此,让我们举个例子: 让我们考虑以下矩阵:

E = 2 1 3 2 0
4 3 0 1 1

然后我们可以通过应用LU分解(https://en.wikipedia.org/wiki/LU_decomposition((或高斯消除(来获得三角测量矩阵,如下所示:

T = 1 0 0 0 0 
2 1 0 0 0 

最后,我要提取的矩阵,即存储线性组合的矩阵:

CL = 3 2 3 0 3
0 1 1 3 4
0 0 1 0 0 
0 0 0 1 0
0 0 0 0 1

所以基本上,算法应该按如下方式工作:

Input: a matrix E with n rows and m columns, and p, a prime number.
* We perform a Gaussian elimination/LU decomposition to obtain the lower-triangulation matrix T. 
But all the calculus are done modulo 'p'. 
Output: T (with the same size as E, n rows m columns). 
CL (with a size m rows, m columns), 
which is basically the identity matrix on which we 
applied all the modifications that were performed on E to obtain T.

好了,现在我们有了背景,让我解释一下这个问题。 我开始使用犰狳库(http://arma.sourceforge.net/(来做这件事,但我在库上没有找到任何解决方案来对数学场p执行微积分。我很容易找到获得下三角形矩阵的LU方法,但计算是在真实中进行的。

#include <iostream>
#include <armadillo>
using namespace arma;
using namespace std;
int main(int argc,char** argv)
{
mat A = mat({{2,1,3,2,0},{4,3,0,1,1}});
mat L, U, P;
lu(L, U, P, A);
cout << L << endl;
return 0;
}

通过以下内容,您可以获得下三角形矩阵"L",但在实数中。因此,您将获得:

T' =  1   0
1/2 1

是否有任何技术可以以模数方式执行计算?

编辑犰狳图书馆无法做到这一点。我开发了自己的模数 LU 分解,但那里仍然存在一个错误。我在这里问了一个新问题 线性组合 C++模数,希望能解决它。

首先:删除using namespaces,如果你这样做,代码可能会变得完全不可读。

我还没有用过犰狳。但是我已经查看了文档,对我来说似乎是模板化的。

现在事情变得有点疯狂了。您使用的类型arma::mat似乎是arma::Mat<double>上的 typedef .

高级函数arma::lu未正确记录。它显然进行了 LU 分解,但我不知道该函数是否是模板化的。如果是,即你不能只用double垫子来调用它,还可以用其他类型的来调用它,你可能会使用表示计算模 5 的字段的自定义类型(因为 5 是素数,否则你会完全丢失(。这意味着您编写了一个类,我们将其称为IntMod5并定义该类所需的所有运算符,即 IntMod5 使用的所有运算符。例如,您需要定义operator/(),例如,通过制作字段的 5 个元素中的 4 个元素的逆表(0 没有(,即 1->1、2->3、3->2、4->4,并定义

IntMod5 operator/(const IntMod5& o) const
{
return IntMod5((this->value*inverse(o.value))%5);
}

这只是一个例子,您可能需要定义所有算术运算符,二进制和一元,可能还有更多,例如比较(LU 分解可能需要找到好的枢轴元素(。如果你很幸运,并且库的编写方式适用于任何领域,而不仅仅是浮点数,你就有机会。

在完成所有工作之前,您应该使用一个简单的类,简单地包装双精度,并检查arma::Matarma::lu是否执行阻止您的任何类型检查。

如果其中任何一个失败,您可能需要编写自己的 LU 分解模 5 或找到另一个支持它的库。

最新更新