【问题标题】:MATLAB: MEX matrix division gives different result than m-fileMATLAB:MEX 矩阵除法给出与 m 文件不同的结果
【发布时间】:2014-12-10 22:18:09
【问题描述】:

我使用 MATLAB 的编码器工具创建了矩阵指数函数的 MEX 版本,用于另一组函数。问题是,MEX 版本给出的结果与原始 m 文件不同。

经过调试,我认为是这个原因,是因为MEX文件和m文件不做矩阵除法(\)相同。或者 MEX 文件首先存在问题。导致矩阵除法所在行的所有变量在两边都是等价的。

这是出现问题的行:

F = (V-U)\(2*U) + I

其中 I 是 V 和 U 大小的单位矩阵。

MEX 文件进行矩阵除法时出现差异的原因是什么,我该如何解决这个问题?这行代码可以不用除法重写吗?

【问题讨论】:

  • 哇.. 这确实很奇怪。虽然这很慢,但请尝试这样做:F = inv(V-U)*(2*U) + I。执行<\> 本质上是取左侧的逆矩阵并乘以右侧。 <\> 运算符通常用于非方阵,以便找到线性方程组的最小二乘解。
  • @rayryeng 我试过这个,不幸的是它不起作用。但是 inv(A) 不会导致矩阵除法吗? inv(A) = A\eye(size(A)) 是否有其他方法可以做到这一点?
  • 不一定。 inv(A) 自己计算逆矩阵。有一种不同的算法来计算逆矩阵,而不是调用 <\> 运算符。这两个答案有多大不同?
  • 这很有趣,因为数字非常小,而且结果矩阵的某些元素是准确的。但一些不正确的可能会有高达 100% 以上的百分比变化
  • 这很奇怪。您是否尝试过使用VU 的已知值以及知道F 的结果是什么并比较这两种方法?

标签: matlab matrix mex equation-solving matlab-coder


【解决方案1】:

MATLAB 在 2014a 版本中对 EXPM 算法进行了细微更改。 MATLAB Coder 实现是独立的,并且尚未对代码生成算法进行相应的更改,因此可能存在一些差异。新的实现是(V - U)\(2*U) + I,而旧的实现是(V - U)\(V + U)。这些在数学上是等效的,但通常会给出不同的舍入行为。

AFAIK,MATLAB 与 MATLAB Coder 中线性系统的解决方案质量没有系统差异。核心算法本质上是等价的,四舍五入的差异预计会从各种模糊的来源蔓延。在给定情况下,对于 MATLAB 或 MATLAB Coder,残差可能更小。如果解决方案的差异很大,则表明正在解决的问题是病态的。如果您愿意,我可以对此进行更多解释,但每本数值分析教科书都对此进行了介绍。你能提供一个具体的例子吗?当您的问题在 MATLAB 中解决时,您至少可以找出 cond(V - U) 在那里返回的内容吗?

【讨论】:

  • 有趣。我不知何故错过了 OP 提到矩阵指数的点,所以我没有与 EXPM 建立联系。我记得 Cleve Moler 不久前关于这个主题的blog post。变化与此有关吗?
  • 我快速搜索了一下,似乎Octave 实现了相同的scale-and-square Padé approximation 方法,而Python/SciPy 引用了较新的2009 paper by Nick Higham
  • 对 MATLAB EXPM 函数的更改是由于遇到控制理论应用中出现的边缘情况而促成的。但是,这一更改确实使 EXPM 能够在 Cleve 在他的博客文章中谈到的示例中获得正确答案。
【解决方案2】:

通过这样的操作生成 C 代码没有问题。

这是我试过的一个测试功能:

myfcn.m

function F = myfcn(U,V)
    I = eye(size(U));
    F = (V-U)\(2*U) + I;
end

这是我们将用来验证结果的测试脚本:

test_myfcn.m

U = rand(5);
V = rand(5);
F = myfcn(U,V);

我首先启动代码生成工具 (ccoder),创建一个新项目集以生成 MEX 文件,然后添加之前的 myfnc.m 函数作为入口点。然后我将两个输入变量类型定义为:

double (:Inf x :Inf)

它指定了一个双精度类型的无限大小的 MxN 矩阵。

最后我们可以构建项目了。这会产生myfcn_mex.mexw64

测试原始 M 函数和生成的 MEX 函数,我得到几乎相同的结果(不同之处在于机器 epsilon 的顺序):

>> F = myfnc(U,V);
>> FF = myfcn_mex(U,V);
>> norm(F-FF)
ans =
   1.4391e-14

【讨论】:

  • 问题不在于差异很小,而在于实际答案的百分比变化很大。这种差异导致我在中使用此 MEX 文件的功能/程序出现问题
  • @GBoggs:“百分比变化”是什么意思?那是相对误差吗?请举一个具体的例子。永远记住浮点数有局限性。例如在 MATLAB(以及可能使用 IEEE-754 的任何其他编程语言)中:1.2 - 0.2 - 11.2 - 1 - 0.2 不同。由于生成的 C 代码遵循不同的执行步骤,因此无法保证您将获得与原始 MATLAB 函数的结果完全相同的副本。
  • 我的意思是:100*(mex_out - out)./out,是百分比变化。而对于我这个函数的应用,这个百分比变化可以达到100%以上的差异,这太大了
  • @GBoggs:这又回到了floating-point limitations 的问题上。您从 MATLAB 获得的答案并不比您从生成的 C 代码中获得的答案更正确。从某种意义上说,它们都是“错误的”,因为最终你不能用有限的位数表示无限量的精度,并且这些舍入误差会随着时间的推移而累积......甚至更多这些误差会根据评估算法步骤的顺序(MATLAB 代码执行的过程与 C 代码求解线性系统的过程不同)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
相关资源
最近更新 更多