矩阵排名第一吗?


21

给定一个整数矩阵,测试它是否为秩一,这意味着每一行都是同一向量的倍数。例如,在

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

每行是的倍数1 0 -10 5

相同的定义也适用于列代替行。另外,如果矩阵像一个乘法表,则它是排名第一的矩阵:

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

我们已经分配了行标签r[i]和列标签,c[j]因此每个矩阵条目M[i][j]都是对应标签的乘积M[i][j] = r[i] * c[j]

输入:

整数矩阵作为您选择的2D容器。例如,列表列表,2D数组或类似列表。除非数组格式要求,否则不应将width或height作为附加输入。

矩阵可以是非正方形的。它将至少有一个非零条目-您不必处理空矩阵或零矩阵。

您可以假设整数不会引起溢出问题。

输出:

秩一矩阵的一致性值,其他矩阵的一致性值。

内建:

不得使用任何内置函数来计算等级或直接检查等级1。您可以使用其他内置函数(例如特征值,分解等),但是我建议不要使用内置函数的答案来完成大部分工作。

测试用例:

排名第一:

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

不排名第一:

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

排行榜:


2
出于好奇,使用内置MatrixRank@#==1&
函数


2
一个美丽的定理是,有限维矩阵的列级等于行级。
Leaky Nun

3
我们是否需要担心浮点精度问题?例如,他们可能使1级矩阵看起来像2级
Luis Mendo

@LuisMendo您确实必须处理精度问题,例如1.0000000001的特征值,但可以假设矩阵不大且没有专门选择进行错误分类。
xnor

Answers:


13

果冻,6个字节

ẸÐfÆrE

在线尝试!

怎么运行的

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

精确

Ær使用数值方法,因此其结果通常不精确。例如,代表多项式6-5x +x²的输入[6,-5,1] 得出3.00000000000000041.9999999999999998。但是,将多项式的所有系数乘以相同的非零常数会导致同样不精确的根。例如,获得相同的根为[6,-5,1][6×10 100,-5×10 100,10 100 ]Ær

应该注意的是,浮点数复杂类型的有限精度导致错误。例如,Ær将获得相同的根为[1,1][10 100,10 100 + 1] 。由于我们可以假设矩阵不大,并且没有专门选择被错误分类,所以应该没问题。


5
多项式的所有系数乘以相同的非零常数会得到同样不精确的根。这是一个绝妙的方法
Luis Mendo

8

Haskell,50个字节

r获取Integers 列表的列表,False如果矩阵的排名为1,True则返回,否则返回。

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

在线尝试!

怎么运行的

  • 生成所有成对的行ab(包括相等的行),并为每对生成xy遍历相应的元素。
  • 将行b乘以x并将行a乘以y。当且仅当结果始终相等时,矩阵才会排名第一。
  • 由于成对是按两个顺序生成的,<因此可以用来检查是否存在不等式。测试结果列表与组合or,以给出True是否存在任何非比例行。

7

Mathematica,51 33字节

RowReduce@#~Count~Except@{0..}<2&

输入项

[{{2,0,-20,10},{-3,0,30,-15},{0,0,0,0}}]

来自user202729的-14个字节从junghwanmin
保存的另外 3个字节


我建议,除了构造长度等于的表之外First@#,您还可以计算,0First@#因为0与所有内容的乘积均为0,并且乘法是可列出的。您也可以考虑使用Tr[1^<list>]来计算列表的长度。
user202729

非常好。我会编辑!
J42161217

代替0#&@@#{0..}也可以。然后Infix工作,因此最终代码可能是RowReduce@#~Count~{0..}==Tr[1^#]-1&,节省了2个字节。
JungHwan Min

实际上,Except可以用来摆脱Tr东西。-3个字节:RowReduce@#~Count~Except@{0..}==1&
JungHwan Min

我认为减少行的矩阵保证为非零(因为原始矩阵为非零),因此计数结果将为正整数,因此<2可以代替==1
user202729

4

JavaScript(ES6),68 67 65字节

这个基于Neil的05AB1E答案,并且比我最初的方法效率更高。

返回第false1位,true否则返回。

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

测试用例


原始答案,84个字节

返回第false1位,true否则返回。

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

测试用例

怎么样?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

在代码末尾执行减法会导致许多不同的情况,下面总结如下:

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

一旦获得真实值,测试就会失败:这发生在矩阵的任意行y中,在a(i,y)a(i,r)之间遇到两个不同的比率(0/0除外)时,其中r是非零行的索引。


h,我只是想知道自己...
尼尔

@Neil您想将其发布为新答案吗?请让我知道。
Arnauld


3

果冻,12字节

ẸÐfµ÷"ЀZE€Ẹ

在线尝试!

说明

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

解释可能有点不正确,因为这是我对原始算法的“打高尔夫球”的解释

-5字节归功于英里


...您的代码沉迷于金钱。(我正在收到deja vu ...)
完全是人间的

@icrieverytim嘿,这次至少美元符号的数量少于代码长度的一半!:P
HyperNeutrino

1
@icrieverytim修复了一个错误,现在美元符号更少了:P
HyperNeutrino

我相信这对于12个字节的ẸÐfµ÷"ЀZE€Ẹ TIO
英里

@miles哦,太好了!您的方法有所不同(我认为吗?),因此您可以将其发布为您自己想要的答案:)
HyperNeutrino

3

05AB1E,16个字节

2ãεø2ãε`R*`Q}W}W

在线尝试!使用任何矩形的对角具有相同乘积的乘法表属性。说明:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

TI-Basic(TI-83系列),28 27 28字节(62个字符)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

计算矩阵的行梯形形式[A],将其第一行(要丢弃)存储在中L₁,将其第二行存储在中ᶫX。然后max(abs(ᶫX将为零,如果ᶫX仅由零和正值否则,这not(如果矩阵是秩一,否则为0变为1。

对于1行矩阵,当我们尝试查看不存在的第二行矩阵时,ᶫX将其设置为{0},然后保持不变。


-1字节感谢Scott Milner

+1个字节可修复1行矩阵的尺寸错误。 如果您尝试从只有一行的矩阵中提取第二行,结果是Matr►list( 命令抱怨。但是,如果您尝试从矩阵中提取第一行和第二行,则将无提示地失败。


1
您可以使用Prompt [A]代替来保存一个字节Ans→[A]
Scott Milner

@ScottMilner谢谢!如果我们使用类似ClrListinitialize 的方法,可能有一种避免的方法ᶫX,但是我还没有获得在更少的空间中工作的方法。
Misha Lavrov

摆脱第二行,因为Matr►list(即使该列表不存在,它也会覆盖该列表,您将节省5个字节。
kamoroso94

1
@ kamoroso94第二行的要点是在不存在列表时不创建列表:第二行的要点是在矩阵只有一行时为第二行创建默认值。如果您摆脱第二行,则代码会因1xN矩阵而崩溃。
Misha Lavrov

2
@ kamoroso94我们必须将L1替换为ᶫY,而不是Y;否则,计算器将认为“将矩阵的第Y行提取为ᶫX”,而不是“将第一行提取为ᶫY,将第二行提取为ᶫX”。
Misha Lavrov

3

Brachylog,27个字节

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

在线尝试!

使用尼尔的方法“每个矩形的相对角的乘积应该相等”。叉积成本很高,需要10个完整字节,但这仍然比我尝试的任何基于除法的方法都要短,这主要是因为在问题中规定了对真理和谬论的两个一致的输出-使得谬论只是a false.,有时不是除零错误,使用太多字节。

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

基于逐元素划分的替代方法(30字节):

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

在线尝试!


2

果冻,9个字节

ẸÐf÷g/$€E

在线尝试!

ẸÐf         Discard zero rows
   ÷  $€    Divide each row by
    g/        its greatest common divisor
        E   Does this list have only one unique element?

1

SageMath,40个字节

lambda M:any(M.rref()[1:])*(M.nrows()>1)

在线尝试

False如果矩阵是秩一,则返回该匿名函数,True否则返回。

该函数将矩阵M作为输入,将其转换为简化的行梯形形式(M.rref()),然后测试any第一个之后的行是否为非零。然后,将该值乘以M.nrows()>1(矩阵是否有多于一行?)。


1

Python 3中93个 91字节

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

在线尝试!

怎么运行的

检查任何2个小数是否具有非零的行列式。如果是这种情况,那么等级必须至少为2:“无消失的p-minor(具有非零行列式的p×p子矩阵)表明该子矩阵的行和列是线性独立的,因此这些行和列完整矩阵的列是线性独立的(在完整矩阵中),因此行和列的等级至少与行列式等级一样大(来自 Wikipedia

注意:感谢user71546的注释,将其减少了两个字节。


1
f=lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
91-

@ user71546谢谢!完成了!
卡·花旗

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.