Armadillo C ++:具有模量计算的线性组合 [英] Armadillo C++ : Linear Combination with modulus calculations

查看:131
本文介绍了Armadillo C ++:具有模量计算的线性组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to extract linear combinations from matrices but by performing combinations in modulus.

让我们考虑计算模数5,然后添加以下内容:

Let us consider the calculation modulus 5, we then have the following for the addition:

 + |  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

所以让我们举个例子: 让我们考虑以下矩阵:

So let us take an example: Let us consider the following matrix:

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

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

Then we can obtain the triangulation matrix by applying a LU decomposition (https://en.wikipedia.org/wiki/LU_decomposition) (or a Gaussian Elimination), which is the following:

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

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

and finally, the matrix that I want to extract, which is the one storing the linear combinations:

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

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

So basically, the algorithm should work as follows:

 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方法来获取下三角矩阵,但计算是在实数中进行的.


Alright, so now we have the context, let me explain the problem. I started to do it using the Armadillo library (http://arma.sourceforge.net/), but I did not find any solution on the library to perform the calculus on a mathematical Field p. I easily found the LU method to obtain the lower-triangle matrix, but the calculations are performed in the real.

#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",但在实际演算中.因此,您获得:

With the following, you obtain the lower-triangle matrix 'L' but in the real calculus. Thus you obtain:

 T' =  1   0
       1/2 1

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

编辑 Armadillo库无法执行此操作.我开发了自己的模分解LU分解,但那里仍然有一个bug.我在这里线性组合C ++模量中提出了一个新问题,希望可以解决. /p>

EDIT The Armadillo library is not able to do it. I developed my own LU decomposition in modulus but there is still a bug there. I asked a new question here Linear Combination C++ in modulus, hoping to solve it.

推荐答案

首先:删除using namespace,如果这样做,代码可能变得完全不可读.

First of all: drop the using namespaces, code can become completely unreadable if you do that.

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

I haven't used Armadillo yet. But I have looked at the documentation, and it seems templated to me.

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

Now things are getting a bit wild. The type you use, arma::mat seems to be a typedef on arma::Mat<double>.

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

The high-level function arma::lu isn't properly documented. It obviously does an LU-decomposition, but I don't know if the function is templated. If it is, i.e., you cannot just call it with double mats but also other types, you might have a shot using a custom type representing the field (since 5 is prime, otherwise you'd be completely lost) of calculations modulo 5. Meaning you write a class, let's call it IntMod5 and define all required operators for this class, meaning all operators that IntMod5 uses. For example, you'd need to define operator/(), e.g. by making a table of inverses of 4 of the 5 elements of the field (0 has none), i.e. 1->1, 2->3, 3->2, 4->4, and define

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

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

This is just one example, you likely need to define all arithmetic operators, binary and unary, and possibly more such as comparison (LU decomposition might use finding good pivot elements). If you're lucky and the library is written in a way that it works for any field, not just floating point, you have a chance.

在完成所有工作之前,您应该使用简单的类,简单地包装double并检查arma::Matarma::lu是否进行了任何类型检查以将您拒之门外.

Before you go through all the work, you should use a trivial class simply wrapping double and check if arma::Mat or arma::lu do any type checks blocking you out.

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

If either of these fails, you'll likely have to write your own LU decomposition modulo 5 or find another library that supports it.

这篇关于Armadillo C ++:具有模量计算的线性组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆