c++ - 在求解 2*2 实矩阵的特征向量时阐明机器 epsilon 的影响
问题描述
代码来自opencv中的函数eigen2x2。
对于具有以下形式的实矩阵:
求解其特征值:
double u = (a + c)*0.5;
double v = std::sqrt((a - c)*(a - c)*0.25 + b*b);
double l1 = u + v; //the 1st eigenvalue
double l2 = u - v; // the 2nd eigenvalue
然后求解对应于 的特征向量l1
,这意味着求解以下系统:
中的代码eigen2x2
如下:
double x = b;
double y = l1 - a;
double e = fabs(x);
if (e + fabs(y) < 1e-4)
{
y = b;
x = l1 - c;
e = fabs(x);
if (e + fabs(y) < 1e-4)
{
e = 1. / (e + fabs(y) + FLT_EPSILON);
x *= e, y *= e;
}
}
double d = 1. / std::sqrt(x*x + y*y + DBL_EPSILON);
double x1 = x*d; //I moderately changed variable name for simplicity.
double x2 = y*d;
其中x1
和x2
构成对应于 的特征向量l1
。
问题
据我了解,当矩阵接近零矩阵时,将执行以下代码:
e = 1. / (e + fabs(y) + FLT_EPSILON);
x *= e, y *= e;
那么它的作用是什么呢?是否允许踢出FLT_EPSILON
和后续DBL_EPSILON
?
解决方案
它们的存在是为了防止除以零(或除以子 epsilon 值)。相反,你会得到一个很大的浮动。
假设您的值大小适中,它应该对结果几乎没有影响;小于其他舍入效果。
安全地删除它需要编写大量单元测试的一些子集,找到最初添加它的文档案例,或者在不良行为安全(没有金钱声誉或生命危险)但值得注意的各种实时代码中广泛使用。单元测试需要涵盖一系列小的、零、非规范化值以及中等和大的值,包括白盒逆向工程以在每个中间步骤生成所述值(为了安全起见)。
我会把它们留在里面;它们看起来无害。
推荐阅读
- flutter - 用于空值的空值检查运算符。我没有收到验证消息
- javascript - 创建和调度事件 javascript。代码执行简单委托
- python - 将控制选项卡从一个 UI 插入到另一个 UI
- c - 错误的 int 输出?
- java - 任务是在 O(n log n) 中创建一个代码,我写的这段代码的时间复杂度是多少?
- android - 如何在 libgdx 中导入 tensorflow lite?
- python - 使用 Vault API 创建 Gmail 导出
- sqlite - Tkinter 树视图将引用的表显示为子表
- python - 如何在解析的 xml 中查找特定元素?
- asp.net-web-api - 如何使用邮递员在正文中发送 xml