Language agnostic 如何规范化零向量

Language agnostic 如何规范化零向量,language-agnostic,math,vector,Language Agnostic,Math,Vector,假设您有一个函数“normalize”,它接受一个数字列表(表示一个向量)作为输入并返回规范化向量。当向量全为零或其分量之和为零时,结果应该是什么?(0,0,0)应该(0,0,0)标准化,可能加上警告(或异常)。 从数学上讲,我想它是没有定义的。从数学上讲,零向量是不能标准化的。其长度将始终保持0 对于给定的向量v=(v1,v2,…,vn)我们有:| v | | sqrt(v1^2+v2^2+…+vn^2)。让我们记住,规范化向量是具有| | v | |=1的向量 所以对于v=0我们有:|0 |

假设您有一个函数“normalize”,它接受一个数字列表(表示一个向量)作为输入并返回规范化向量。当向量全为零或其分量之和为零时,结果应该是什么?

(0,0,0)应该(0,0,0)标准化,可能加上警告(或异常)。

从数学上讲,我想它是没有定义的。

从数学上讲,零向量是不能标准化的。其长度将始终保持
0

对于给定的向量v=(v1,v2,…,vn)我们有:
| v | | sqrt(v1^2+v2^2+…+vn^2)
。让我们记住,规范化向量是具有
| | v | |=1
的向量

所以对于
v=0
我们有:
|0 | |=sqrt(0^2+0^2+…+0^2)=0
。你永远无法将其正常化


同样重要的是要注意,为确保一致性,不应返回
NaN
或任何其他空值。
v=0
的规范化形式确实是
v=0

好吧,你必须除以零,这是你做不到的,所以我认为大多数语言都会有某种NaN值

参考资料:

  • (还必须为向量拾取任意方向)
  • (使用Python)

与0/0非常相似。应该抛出异常或返回NaN。

根据我遇到的向量范数的任何定义,零向量已经被规范化了,所以这是一种处理的情况


对于分量和为零的向量,这取决于你使用的范数的定义。对于普通的旧L2范数(原点和向量之间的欧几里德距离),计算标准化向量的标准公式应该可以很好地工作,因为它首先将各个分量平方。

甚至比Yuval建议的还要糟糕

从数学上讲,给定一个向量x,你要寻找一个新的向量x/| | x||

其中| |.| |是范数,您可能认为它是欧几里德范数

||.| |=sqrt(点(v,v))=sqrt(和)

这些都是浮点数,所以仅仅防止被零除是不够的,如果x_i都很小,那么也会出现浮点问题(它们可能会下溢,并且会丢失大小)

基本上,这一切归结为,如果你真的需要能够正确处理小向量,你将不得不做更多的工作

如果小矢量和零矢量在应用程序中没有意义,可以根据矢量的大小进行测试,并采取适当的措施

(请注意,一旦开始处理浮点数,而不是实数,那么在可表示范围的大端和小端进行平方运算和平方根数(或它们的总和)都会有问题)

一句话:在所有情况下正确地进行数值计算比最初看起来要复杂得多

例如,以一种幼稚的方式完成此(规范化)操作时,我脑海中浮现出潜在的问题

  • 所有组件(x_i)都太小
  • 任何单个分量过大(大于最大可表示值的平方根)都将返回无穷大。这将通过sqrt从组件上切割可用震级
  • 如果大组件与小组件的比率太大,如果不小心,可能会丢失小组件的方向
  • 等等

正如已经多次提到的那样,不能规范化零向量。因此,您的选择是:

  • 返回零向量
  • 还楠
  • 除了返回结果(如果成功)外,还返回一位,指示向量是否成功规格化
  • 抛出异常
  • 选项4不是很好,因为某些语言(如C)没有异常,规范化向量通常出现在非常低级的代码中。抛出异常代价相当高,任何可能希望处理零/小向量情况的代码在发生这种情况时都会受到不必要的性能影响

    选项1的问题是返回值没有单位长度,因此它可能会在调用代码中无声地引入错误,并假定生成的向量具有单位长度

    选项2和选项1有一个类似的问题,但因为“非”通常比“零”更明显,所以它可能更容易显示

    我认为选项3是最好的解决方案,尽管它确实使界面更加复杂。而不是说

    vec3 = myVec.normalize();
    
    你现在必须说

    vec3 result;
    bool success = myVec.normalize(&result);
    if(success)
        // vector was normalized
    else
        // vector was zero (or small)
    

    给定一个向量v,对其进行归一化意味着保持其方向,并通过将其乘以精心选择的因子使其成为单位长度

    这对于零向量显然是不可能的,因为它实际上没有方向,或者因为它的长度不能通过将它乘以某个因子来改变(它总是等于零)


    我建议,无论你想用你的向量做什么,并且需要对这个向量进行规范化的过程,都不能很好地定义零向量。

    从数学上讲,零向量不能被规范化。这是我们在计算几何中称之为“退化情况”的一个例子,这是一个巨大的主题,让几何算法设计者非常头疼。 我可以想象以下解决问题的方法

  • 对于零向量的情况,你没有什么特别之处。如果您的向量类型具有浮点类型的坐标,那么您将在结果中获得零或无限坐标(由于被零除)
  • 您抛出了一个
    退化案例\u异常
  • 将布尔值
    is\u degenerate\u case
    输出参数引入到过程中
  • 就我个人而言,我在代码中到处都使用3方法。它的优点之一是不会让程序员忘记处理退化情况

    注意,由于fl的范围有限