Armadillo C ++:具有模量计算的线性组合

时间:2018-10-03 12:28:32

标签: c++ matrix linear-algebra linear armadillo

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

让我们考虑计算模数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.

好的,现在我们有了上下文,让我解释一下问题。 我开始使用Armadillo库(http://arma.sourceforge.net/)进行此操作,但是我没有在库中找到任何解决方案来对数学Field 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

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

编辑 Armadillo库无法执行此操作。我开发了自己的模分解LU分解,但那里仍然有一个bug。我在这里Linear Combination C++ in modulus问了一个新问题,希望能解决。

1 个答案:

答案 0 :(得分:1)

首先:删除//first block function xyz(){ this.callXyz=function(){ console.log('callXyz inner'); } } // second block xyz.prototype.callXyz=function(){ console.log('prototype function'); } ,如果这样做,代码可能变得完全不可读。

我还没有用过犰狳。但是我看了一下文档,似乎对我来说是模板。

现在事情变得有点疯狂了。您使用的类型using namespace似乎是arma::mat上的typedef。

未正确记录高级功能arma::Mat<double>。它显然会进行LU分解,但我不知道该函数是否已模板化。如果是这样,即您不能仅使用arma::lu垫子来调用它,也不能使用其他类型的垫子,那么您可能会使用自定义类型来代表场的拍摄(因为5是质数,否则您将完全迷失)模5的计算。这意味着您要编写一个类,将其称为double并定义该类所需的所有运算符,即IntMod5使用的所有运算符。例如,您需要定义IntMod5,例如通过创建一个字段的5个元素中的4个(0没有)的逆表,即1-> 1、2-> 3、3-> 2、4-> 4并定义

operator/()

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

在完成所有工作之前,您应该使用简单的类,简单地包装double并检查IntMod5 operator/(const IntMod5& o) const { return IntMod5((this->value*inverse(o.value))%5); } arma::Mat是否进行了任何类型检查以将您拒之门外。

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