为什么C ++将范数定义为欧几里德范数的平方

时间:2009-08-28 18:42:24

标签: c++ math

这可能听起来像是一个修辞问题,但我在此提出这两个原因:

  1. 我花了一些时间才弄清楚C ++ std :: norm()与Matlab / Octave有什么不同,所以其他人可能会在这里偶然发现它。
  2. 我觉得奇怪的是将norm()函数定义为与通常被认为是标准(或L2范数,或欧几里德范数等等)不同(尽管密切相关)的东西。 / LI>

    具体而言,C ++标准库将复数定义norm()为模数(或绝对值)的平方,其中当复数为时,模数为sqrt(a ^ 2 + b ^ 2)形式a + i * b。

    这违背了我对规范的理解,当指定为欧几里德范数(对应于此处使用的模数)时,是平方和的平方根。我会参考Mathworld's definition of the complex modulus

    这是其他人遇到过的吗?我发现它是将一些信号处理代码从Octave移植到C ++的结果,而我发现引用这种差异的唯一其他地方是在GCC邮件列表上(由于1-link限制而无法发布链接)。 / p>

2 个答案:

答案 0 :(得分:13)

单词“norm”的C ++用法相当令人困惑,因为大多数人只是在向量空间的上下文中遇到过规范。如果您将复数视为实数上的向量空间,这绝对不是常态。为了公平对待C ++,std :: norm()函数确实计算了从复数到实数的所谓Field Norm

幸运的是,有一个std :: abs()函数可以满足您的需求。

答案 1 :(得分:5)

顺便提一下,欧几里得范数的平方可以作为优化,特别是在游戏物理中;如果你想比较幅度/距离,或者由于任何其他原因不需要线性,那么你可以使用平方距离而不是实际距离,并避免计算平方根。

norm(v1) < norm(v2)         instead of   abs(v1) < abs(v2)
norm(v) < CONSTANT_SQUARED  instead of   abs(v) < CONSTANT

(使用abs()是另一个答案中提到的幅度的事实)