归一化向量


28

为了正常化的载体是将它扩展到1的长度(单位矢量),同时保持方向一致。

例如,如果我们想正常化的矢量3个组件,ü,我们会先找到它的长度:

| u | = sqrt(u x 2 + u y 2 + u z 2

...然后按此值缩放每个分量,以获得长度为1的向量。

û= u÷| u |


挑战

您的任务是编写一个程序或函数,给定一个带符号的整数的非空列表,将其解释为向量并将其标准化。例如,这应该适用于任意数量的维度(测试用例四舍五入到小数点后两位):

[20]           -> [1]
[-5]           -> [-1]
[-3, 0]        -> [-1, 0]
[5.5, 6, -3.5] -> [0.62, 0.68, -0.40]
[3, 4, -5, -6] -> [0.32, 0.43, -0.54, -0.65]
[0, 0, 5, 0]   -> [0, 0, 1, 0]

规则:

  • 您可以假设输入列表将:
    • 至少有一个非零元素
    • 仅包含您语言标准浮点范围内的数字
  • 您的输出至少 应精确到两位小数。如果您的语言在内部存储数据,则也可以返回“无限精度”的分数/符号值。
  • 提交的内容应为执行I / O的完整程序或功能。函数提交可以返回新列表,也可以就地修改给定列表。
  • 允许内置向量函数/类。此外,如果您的语言具有支持任意数量维的向量类型,则可以将其中之一作为输入。

这是一场比赛,因此您应该力求实现最短的解决方案(以字节为单位)。


对于每个可能的输入,它是否必须至少具有两个小数位(对于任何标准类型的浮点值是不可能的)或仅针对您提供的示例?例如,Steadybox的答案为您的所有测试提供2个小数位精度,但他使用整数作为平方和,这对于几乎所有输入而言都是不正确的(例如[0.1,0.1])。
克里斯多夫(Christoph)

...现在我们只需要等待一个将内置规范函数映射到一个字符的lang ...
vaxquis

@Christoph
FlipTack

@FlipTack,但是这基本上排除了所有语言,因为浮点的指数大于尾数,这意味着它们并不总是具有足够的精度来保留小数位。
克里斯多夫(Christoph)

为什么第4个示例中的6和第5个示例中的-6不分别归一化为1和-1?
桅杆

Answers:


15

05AB1E,4个字节

码:

nOt/

在线尝试!

说明

n     # Square each element of the input
 O    # Sum all elements
  t   # Take the square root of the sum
   /  # Divide each element by the square root of the sum

9
n0t我预期的是
YSC

10

JavaScript(ES6),31个字节

a=>a.map(n=>n/Math.hypot(...a))

测试用例



9

J,8个字节

%+/&.:*:

在线尝试!

如果向量至少为2维,则 6个字节%|@j./有效。


喜欢获得震撼力的方法。
cole

1
@cole延长1个字节:%1%:@#.*:
FrownyFrog

6
您能否为J中的未初始化项添加解释?
MechMK1

%(除以)+ /(总和)&.:(下)*:(正方形)。+总结两件事。+ /汇总事物列表。&.:通过先应用以下操作,然后再应用其反操作来修改前一操作。%通常带有两个参数,但是(%f)是x到x%(fx)之间的函数。大多数操作员会自动处理列表。
罗曼·奥戴斯基

并且根据相同的原理,通过将这样的数字加到每个分量的总和为零的“归一化”向量的函数是“-+ /%#”。
罗曼·奥戴斯基



6

C, 73  70字节

感谢@Christoph节省了一个字节!

s,i;f(v,n)float*v;{for(s=0;i++<n;)s+=*v**v++;for(;--i;)*--v/=sqrt(s);}

在线尝试!


+1。s=0,i=0而不是s=i=0保存一个
xanoetux

我喜欢使用,s[-i]但遗憾的*--v/=sqrt(s);是短了1个字节。
克里斯多夫(Christoph)

1
@xanoetux谢谢,但是我需要初始化函数内部的变量,因为函数需要可重用。此外,为全局变量,s并且i会自动初始化为0(原来我不需要初始化i函数中,因为函数总是会留下它的值为0)
Steadybox

1
@Christoph谢谢!我最初是从函数中打印值的,所以我需要v[-i]以正确的顺序获取值。
Steadybox '17



3

CJam,9个字节

{_:mhzf/}

在线尝试!

说明

_    e# Duplicate input.
:mh  e# Fold hypothenuse-length over the vector. This gives the norm, unless the vector
     e# has only one component, in which case it just gives that component.
z    e# Abs. For the case of a single negative vector component.
f/   e# Divide each vector component by the norm.

3

TI-Basic,6个字节

Ans/√(sum(Ans2

与一起运行{1,2,3}:prgmNAME,其中{1,2,3}要归一化的向量在哪里。

将向量中的每个元素除以其元素平方和的平方根。


我们得到了相同的答案!
kamoroso94 '17

@ kamoroso94糟糕!我张贴此消息时没有看到您的消息。如果您要将答案中的说明添加到答案中,则将其删除。
Pizzapants184

不,我将删除我的。您在答案中付出了更多努力:P
kamoroso94 '17

3

R,23个字节

function(v)v/(v%*%v)^.5

在线尝试!

v%*%v计算v与自身的点积。
该函数将对长度为2或更大的向量发出警告。



2

MATL,5个字节

t2&|/

在线尝试!

我不确定这是最短的方法。首先,我们重复输入,然后选择的第二输出类型|(其是absnormdeterminant)。最后,我们将输入除以范数。

替代7字节:

t2^sX^/




2

C ++(gcc),70个字节

由输入std::valarray<float>。覆盖原始向量。

#import<valarray>
int f(std::valarray<float>&a){a/=sqrt((a*a).sum());}

在线尝试!


我只是时不时地潜入代码高尔夫,但是在给定“ #import”的情况下,这不是无效的C ++吗?
phresnel

@phresnel #import至少也可以与GCC,Clang和MinGW一起使用。但是,是的,它不是标准的C ++。
Steadybox '17

@phresnel我忘记指定gcc。固定。
Colera Su


2

APL(Dyalog)13 12 10字节

@Adám节省了1个字节

@ngn节省了2个字节

⊢÷.5*⍨+.×⍨

在线尝试!

怎么样?

  ÷  .5*⍨  +.  ×⍨
u  ÷       Σ   u²

火车少:⊢÷.5*⍨(+/×⍨)
亚当

@Adám非常感谢!我已经尝试了几个小时,无法坐上火车
Uriel

我们应该为此做些事情,因为这实际上并不难。如果您具有单声道功能(最右边的功能除外),请在其左侧开始一个括号(如果不是派生的,则使用a )。除此之外,只是交换{⍵÷.5*⍨+/×⍨⍵}→交通{⍵÷.5*⍨(+/(×⍨⍵))}→交通⊢÷.5*⍨(+/(×⍨⊢))→交通⊢÷.5*⍨(+/(×⍨))→交通⊢÷.5*⍨(+/×⍨)
亚当

(+/×⍨)->+.×⍨
ngn


1

C#(.NET Core),51 + 64 = 115字节

v=>v.Select(d=>d/Math.Sqrt(v.Select(x=>x*x).Sum()))

在线尝试!

+64个字节 using System;using System.Collections.Generic;using System.Linq;

C#(.NET Core),94 + 13 = 107字节

v=>{var m=0d;foreach(var x in v)m+=x*x;for(int i=0;i<v.Length;)v[i++]/=Math.Sqrt(m);return v;}

在线尝试!

+13个字节 using System;

非Linq方法

去高尔夫

v=>{
    var m=0d;
    foreach (var x in v)
        m+=x*x;

    for (int i=0; i < v.Length;)
        v[i++] /= Math.Sqrt(m);

    return v;
}


1

,10字节

9个字节的代码,-p标志+1 。

g/RT$+g*g

将向量作为单独的命令行参数。 在线尝试!

怎么运行的

      g*g  Arglist, multiplied by itself itemwise
    $+     Sum
  RT       Square root
g/         Divide arglist itemwise by that scalar
           Result is autoprinted (-p flag to format as list)

1

Pyth,5个字节

cR.aQ

在线尝试: 测试套件

说明:

cR.aQQ   implicit Q at the end
c        divide
 R   Q   each element of the input
  .aQ    by the L2 norm of the input vector


1

Ruby,39 35字节

->v{v.map{|x|x/v.sum{|x|x*x}**0.5}}

-G 4个字节。


1
通过使用节省一些字节sum{...},而不是map{...}.sum
GB

0

APL NARS 12个字符

f←{⍵÷√+/⍵*2}

您不必计算f← 字节数,因为没有它就可以使用dfns。顺便问一下,NARS中是否只有一个字节?我不熟悉,所以问一下
Uriel

@Uriel Nars Apl我知道会用Unicode编写,因此字节数应为12x2
RosLuP

0

Google表格,65个字节

=ArrayFormula(TextJoin(",",1,If(A:A="","",A:A/Sqrt(Sumsq(A:A)))))

输入列表在列中A,每个单元格有一个条目。这是电子表格通常使用列表的方式。不幸的是,这通常会导致,0,0,0,0,0,....结尾处的列表很长,因此我们必须忽略具有If Blank then Blank else Math逻辑的内容。

如果全部在一个单元中,则解决方案将是95个字节:

=ArrayFormula(TextJoin(",",1,If(Split(A1,",")="","",Split(A1,",")/Sqrt(Sumsq(Split(A1,","))))))

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.