c++ - Armadillo 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 模数分解,但那里仍然存在错误。我在这里问了一个新问题Linear Combination C++ in modules,希望能解决。
解决方案
首先:去掉using namespace
s,如果你这样做,代码会变得完全不可读。
我还没用过犰狳。但是我查看了文档,对我来说似乎是模板。
现在事情变得有点疯狂。您使用的类型arma::mat
似乎是arma::Mat<double>
.
高级功能arma::lu
没有正确记录。它显然做了一个 LU 分解,但我不知道该函数是否是模板化的。如果是这样,即,您不能只用double
mats 来调用它,也可以用其他类型来调用它,您可能会使用表示模 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 分解可能使用寻找好的枢轴元素)。如果您很幸运,并且该库的编写方式适用于任何领域,而不仅仅是浮点,那么您就有机会。
在完成所有工作之前,您应该使用一个简单的类来简单地包装 double 并检查是否arma::Mat
或arma::lu
执行任何类型检查阻止您。
如果其中任何一个失败,您可能必须编写自己的 LU 分解模 5 或找到另一个支持它的库。
推荐阅读
- arrays - 比较两个数组 Ruby 2.0
- sapui5 - 应用内可扩展性和并行可扩展性之间的区别?
- ios - iOS 13 UIWindowScene 如何锁定方向?
- android - Kotlin:将 LongArray 定义为 Notification.Builder.setVibrate(LONG_ARRAY)
- php - 如何在php中删除字符串末尾附近的分配字符?
- bash - 将文件的附加数据实时复制到另一个文件
- php - PHPunit 单个 ok/failed 结果
- python - 如何运行我所有的 python 脚本抛出代理
- javascript - 为什么渲染数据不显示?
- javascript - 遍历动态的嵌套对象