在Matlab中找到线性整数方程的精确有理解

计算科学 线性代数 matlab 符号计算
2021-12-10 03:50:56

我有一个线性方程组

Ax=b
在哪里A是一个N×N具有整数值的矩阵,以及b是一个N×1具有整数值的向量。由于先验知识,我知道我保证存在一个合理的解决方案x这样x=A1b(以及该A有满秩)。

我现在正在 Matlab(或任何其他我可以重写为 Matlab 的语言)中寻找一种算法,它为给定的这个问题提供了精确的合理解决方案Ab,例如在表格中 x=rst, 在哪里rs是标量整数和t是一个N×1整数向量,或形式(Matlab 表示法)x=r./s,其中rsN×1整数向量。

我已经尝试过[r,s]=rat(A\b),它适用于足够简单的情况,但很快就会导致舍入问题(即r./s仅近似x,但我需要确切的解决方案)。使用符号计算有效;但是,我必须将程序编译为独立的,并且据我所知和尝试过,Matlab 编译器不支持符号工具箱。

一些统计数据:N应该被允许至少在100或更高。中的值A可以变得相当大,以至于我现在已经在使用int64. 我知道在某一时刻我会遇到数字问题,我只要尽可能推迟这类问题就足够了(我很感激任何解决方案,即使它只适用于较小的问题N)。但是,我需要精确的解决方案,而且我更喜欢错误消息而不是任何近似值,无论多么好。算法的运行时间是次要的,如果需要一个小时左右就可以了N=100(然而,更有效率是一个加号)。

3个回答

您可能会查找“完全无分数分解”方法。论文“具有核提取的奇异系统的广义无分数 LU 分解”包含伪代码。

我们有线性系统Ax=b, 在哪里AZn×nbZn. 我们希望找到合理的解决方案xQn. 计算矩阵的史密斯范式AMATLAB中:

[U, V, S] = smithForm(A) 

我们得到单模矩阵UV(即具有整数逆的整数矩阵)和对角矩阵S=UAV. 因此,Ax=b可以改写为SV1x=Ub. y:=V1x. 然后我们得到线性系统Sy=Ub,这很容易解决,因为S是对角线。由于两者SUb是整数值,解决方案将是一个有理向量。最后,我们计算x=Vy,这也是一个有理向量,因为V也是整数值。

该问题可以使用 Matlab 符号工具箱来解决:

N = 100; %Dimensionality
A = randi(1000, [N, N]);
assert(rank(A) == N);
B = randi(1000, [N, 1]);

As = sym(A);
Bs = sym(B);

tic
xs = linsolve(As, Bs); % is a rational number
toc

disp(xs);

xs表示为有理数的向量。linsolvei5 上的调用运行时间约为 9 秒。