范德蒙行列式


25

给定一个n值向量,(x1,x2,x3,...,xn)返回相应范德蒙德矩阵的行列式

该行列式可以写为:

formula

细节

您的程序/函数必须接受允许可变长度的任何方便格式的浮点数列表,并输出指定的行列式。

您可以假设输入和输出都在您的语言支持的值的范围内。如果您的语言不支持浮点数,则可以采用整数。

一些测试案例

请注意,每当有两个相等的条目时,行列式将为0相应的Vandermonde矩阵中有两个相等的行。感谢@randomra指出了这个丢失的测试用例。

[1,2,2,3]            0 
[-13513]             1
[1,2]                1
[2,1]               -1
[1,2,3]              2
[3,2,1]             -2
[1,2,3,4]           12
[1,2,3,4,5]        288
[1,2,4]              6
[1,2,4,8]         1008
[1,2,4,8,16]  20321280
[0, .1, .2,...,1]   6.6586e-028
[1, .5, .25, .125]  0.00384521
[.25, .5, 1, 2, 4]  19.3798828

我们可以假设输入的长度至少为2吗?
PurkkaKoodari'3

@ Pietu1998不,请参阅第一个测试用例。
Alex A.

3
重要的测试用例::[1,2,2,3] => 0数组中的两个相等元素,xi-xi仅通过与比较来测试代码是否检查自差()0
randomra

@randomra谢谢,我完全忘了包括其中之一。每当两个条目相等时,行列式将为0,因为同一行有两次。
瑕疵的

1
@flawr从您的规格中可以清楚地看到预期的输出。我建议使用测试用例,这样,没有准备好相等数量的答案就可以更轻松地发现他们的错误。
randomra

Answers:


9

果冻,6个字节

œc2IFP

œc2获取所有组合而无需替换长度2。I计算这些对中每个对的差异列表,得到一个类似的列表[[1], [2], [3], ..., [1]]。我们把F食物拿走P产品。

在这里尝试!


8

Ruby,49个 47字节

->x{eval(x.combination(2).map{|a,b|b-a}*?*)||1}

这是一个lambda函数,该函数接受实值一维数组,并根据输入的类型返回浮点数或整数。要调用它,请将其分配给变量,然后执行f.call(input)

我们使用来.combination(2)获得大小为2的所有组合,并使用来获得每一对的差异.map {|a, b| b - a}。我们将结果数组连接到由分隔的字符串中*,然后eval返回结果。如果输入的长度为1,nil则为,这在Ruby中是false,因此||1在这种情况下,我们可以最后返回1。请注意,这在乘积为0时仍然有效,因为无论何种原因,Ruby中0都是正确的。

在线验证所有测试用例

多亏了Doorknob,节省了2个字节!


7

Mathematica,30个字节

1##&@@(#2-#&@@@#~Subsets~{2})&

这是一个匿名函数。

由Mathematica扩展,等效于(1 ##1 & ) @@ Apply[#2 - #1 & , Subsets[#1, {2}], {1}] &1##&是等价的Times(感谢技巧页面),它适用于输入列表中由生成的每对不同的元素Subsets[list, {2}]。请注意,Subsets这不会检查元素的唯一性。


5

J,13个字节

-/ .*@(^/i.)#

这是一个单子函数,它接受一个数组并返回一个数字。像这样使用它:

  f =: -/ .*@(^/i.)#
  f 1 2 4
6

说明

我显式构造了与输入数组关联的Vandermonde矩阵,然后计算其行列式。

-/ .*@(^/i.)#   Denote input by y
            #   Length of y, say n
         i.     Range from 0 to n - 1
       ^/       Direct product of y with the above range using ^ (power)
                This gives the Vandermonde matrix
                 1 y0     y0^2     ... y0^(n-1)
                 1 y1     y1^2     ... y1^(n-1)
                   ...
                 1 y(n-1) y(n-1)^2 ... y(n-1)^(n-1)
-/ .*           Evaluate the determinant of this matrix

我以为空白在J方面并不重要...
Conor O'Brien

@CᴏɴᴏʀO'Bʀɪᴇɴ行列式是一种特殊情况,需要一个空格,因为.它也是修饰符。同为:自身。
Zgarb

哦! 这很酷。
Conor O'Brien

@CᴏɴᴏʀO'Bʀɪᴇɴ实际上,我认为这正是使J变得不酷的原因。j表示用于记,即点或小环(APL的),如为J草草 ......令人难以置信的重载.:(这又是视觉上同两个堆叠.s)作出Ĵ难以阅读(对我来说)。点旁边的空格确定含义时还需要多少钱!J .必须是所有计算历史上最重载的符号:我算出53的不同含义.和43(如果算作_9:to 则全部为61 9:)的不同含义:。kk ;-)
亚当

@Nᴮᶻ可能有助于您想到。作为自己的令牌;因此,在没有空格的情况下,它可能会被误认为另一个操作员。但是,如果J不适合您,那是可以理解的。
科纳·奥布赖恩

4

玛特 9

!G-qZRQpp

在线尝试!

这将计算所有差异的矩阵,然后仅将零件保留在主对角线以下,进行其他输入,1以免影响产品。下三角函数使不需要的元素0,而不是1。因此,我们减去1,取下三角部分,然后加1回来。然后,我们可以取所有条目的乘积。

t     % take input. Transpose
G     % push input again
-     % subtract with broadccast: matrix of all pairwise differences
q     % subtract 1
ZR    % make zero all values on the diagonal and above
Q     % add 1
p     % product of all columns
p     % product of all those products

不幸的是,但2Xn!dp似乎仅在单个值大于或等于2时才起作用。我自己写
这篇文章

@FryAmTheEggman Awww。你是对的。感谢您的单挑!
Luis Mendo

是的,我认为这就是问题所在。我会考虑在您Xn进行类似检查时尝试添加包装器之类的方法if size(arg) == [1,1] ...。我实在太懒了,无法从源头上看,但是(希望如此)应该没有那么困难。
FryAmTheEggman

@FryAmTheEggman实际上,我不确定这是问题所在(这就是为什么我快速编辑评论)。如果第一个输入是一个数字,那么第二个输入应该是10,然后,如果第一个输入被解释为数组或数字,则没有区别。真正的问题是,第二个输入不能超过数组的大小。“从1个元素中选择2个元素有多少种方法”。在这种情况下,数组/数字的区别很重要:如果第一个输入是一个数组return [](空数组),如果它是一个数字return 0。我想我会回来[],因为这会p迫使其他解释
Luis Mendo

@FryAmTheEggman我想我会将函数分为两个版本。再次感谢!
路易斯·门多

3

Pyth,15 13 12 11字节

*F+1-M.c_Q2
         Q    take input (in format [1,2,3,...])
        _     reverse the array: later we will be subtracting, and we want to
                subtract earlier elements from later elements
      .c  2   combinations of length 2: this gets the correct pairs
    -M        map a[0] - a[1] over each subarray
  +1          prepend a 1 to the array: this does not change the following
                result, but prevents an error on empty array
*F            fold over multiply (multiply all numbers in array)

感谢@FryAmTheEggman@ Pietu1998每个字节!


1
*空数组F上确实应该1
lirtosiast

3

Mathematica,32个字节

Det@Table[#^j,{j,0,Length@#-1}]&

我很惊讶没有找到Vandermonde的内置组件。可能因为自己做起来很容易。

这个明确地构造了一个虚拟机的转置,并采用了它的行列式(当然和原始的相同)。事实证明,此方法比使用我所知道的任何公式都要短得多。


3

Haskell,34个字节

f(h:t)=f t*product[x-h|x<-t]
f _=1

递归解决方案。当新元素h放在最前面时,表达式将乘以列表中x-h每个元素的乘积x。感谢Zgarb提供1个字节。


2

Matlab,26个字节

(非竞争)

内建函数的直接使用。请注意(再次),Matlab vander创建了范德蒙德矩阵,但行的顺序发生了翻转。

@(v)det(fliplr(vander(v)))

2
为什么不竞争?
Alex A.

3
因为我是提出挑战的人,所以我只想提供此信息,以便人们可以尝试自己的示例。
瑕疵的

Det(翻转行)=(-1)^ n Det(原始)吗?
hYPotenuser

我不太确定,因为无论何时切换两列或两行,行列式切换都将符号化。
瑕疵的

@hYPotenuser-将n替换为n + 1。您要做的就是将矩阵P乘以全零,除了从左下角到右上角的对角线(因此,您需要det(P * vander(v))= det(P)det(vander(v ))。通过沿第一列进行扩展,您将看到det(P)=(-1)^(n + 1)。
蝙蝠侠

2

Rust,86个字节

|a:Vec<f32>|(0..a.len()).flat_map(|x|(x+1..a.len()).map(move|y|y-x)).fold(1,|a,b|a*b);

生锈,像往常一样冗长...

稍后会进行解释(尽管非常简单)。


2

Perl,38 41字节

包括+1 -p

在STDIN的一行上给出数字。所以例如运行

perl -p vandermonde.pl <<< "1 2 4 8"

使用邪恶的正则表达式获取双循环:

vandermonde.pl

$n=1;/(^| ).* (??{$n*=$'-$&;A})/;*_=n

2

JavaScript(ES6),61个字节

a=>a.reduce((p,x,i)=>a.slice(0,i).reduce((p,y)=>p*(x-y),p),1)

我尝试了数组理解(Firefox 30-57),它长了5个字节:

a=>[for(i of a.keys(p=1))for(j of Array(i).keys())p*=a[i]-a[j]]&&p

无聊的嵌套循环可能会更短。


1

Haskell,53个字节

 f x=product[x!!j-x!!i|j<-[1..length x-1],i<-[0..j-1]]

用法示例:f [1,2,4,8,16]->20321280

遍历索引ji嵌套循环,列出位置j和的元素差异列表i。制作列表中所有元素的乘积。

原来更长的其他变体:

f x=product[last l-i|l<-scanl1(++)$pure<$>x,i<-init l],54字节

import Data.List;f i=product[y-x|[x,y]<-subsequences i],55字节


1

CJam,16个字节

1l~{)1$f-@+:*\}h

在回应Simmons的帖子时,尽管CJam缺少组合运算符,是的,有可能做得更好:)

-1个字节感谢@MartinBüttner。

在线试用 | 测试套件

1                   Push 1 to kick off product
 l~                 Read and evaluate input V
   {          }h    Do-while loop until V is empty
    )                 Pop last element of V
     1$               Copy the prefix
       f-             Element-wise subtract each from the popped element
         @+           Add the current product to the resulting array
           :*         Take product to produce new product
             \        Swap, putting V back on top

0

CJam,32个字节

1q~La\{1$f++}/{,2=},{~-}%~]La-:*

我确定有人可以在CJam中更好地打高尔夫球...主要问题是我看不到获取子集的好方法,因为它占用了我的大部分字节。生成功率集(使用MartinBüttner的想法),然后选择长度为2的元素。



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.