行列は1位ですか?


21

整数の行列が与えられたら、それがランク1であるかどうかをテストします。これは、すべての行が同じベクトルの倍数であることを意味します。たとえば、

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

すべての行はの倍数です1 0 -10 5

同じ定義は、行の代わりに列でも機能します。あるいは、乗算表のような行列はランク1です。

 *    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配列など。配列形式で必要とされない限り、幅または高さを追加の入力として使用しないでください。

行列は非正方形の場合があります。少なくとも1つの非ゼロエントリがあります。空またはゼロの行列を処理する必要はありません。

整数がオーバーフローの問題を引き起こさないと仮定できます。

出力:

ランク1マトリックスの一貫した値、および他のマトリックスの異なる一貫した値。

ビルトイン:

組み込みのランクを計算したり、ランク1を直接チェックしたりすることはできません。固有値や分解などの他のビルトインを使用することもできますが、ほとんどの作業を行うビルトインを持たない回答を推奨します。

テストケース:

ランク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]]

ランク1ではない:

[[-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
不思議なことに、組み込み関数を使用したMathematicaの応答は次のようになります(16バイト):MatrixRank@#==1&
JungHwan Min


2
美しい定理は、列のランクが有限次元行列の行のランクに等しいということです。
リーキー修道女

3
フロート精度の問題を心配する必要がありますか?たとえば、ランク1のマトリックスがランク2のように見える場合があります
ルイスメンドー

@LuisMendo 1.0000000001の固有値などの精度の問題を処理する必要がありますが、マトリックスが大きくなく、誤分類に特に選択されていないことを想定できます。
XNOR

回答:


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.0000000000000004および1.9999999999999998になります。ただし、多項式のすべての係数にゼロ以外の同じ定数を掛けると、等しく不正確な根になります。例えば、のために同じ根を取得[6、-5、1]及び[6×10 100、-5×10 100 10 100 ]Ær

float型とcomplex型の精度が限られていると、エラーが発生する可能性があることに注意してください。例えば、Ærのために同じ根を得ることになる[1、1]及び[10 100、10 100 + 1] 。以来、私たちは行列をとることができる大規模なものではなく、具体的に誤って分類されるために選択されていない、それは問題ないはずです。


5
多項式のすべての係数に同じ非ゼロ定数を乗算すると、等しく不正確な根が得られますこれは素晴らしいアプローチです
ルイスメンドー

8

Haskell、50バイト

rIntegers のリストのリストを取得しFalse、行列のランクが1のTrue場合はそれ以外の場合は返します。

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

オンラインでお試しください!

使い方

  • 行のすべてのペアを生成aし、b(同じ行を含む)、及び各ペアについて、できx及びy対応する要素を通ります。
  • 乗算行bによってx、行aによってy。結果が常に等しい場合にのみ、マトリックスのランクは1になります。
  • ペアは両方の順序で生成<されるため、不平等があるかどうかを確認するために使用できます。テスト結果のリストはと結合されorTrue非比例行があるかどうかを示します。

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バイト保存


の長さと等しい長さのテーブルを作成する代わりに、0はすべてと乗算し、乗算はリストFirst@#可能な0First@#ので、計算できることをお勧めします。またTr[1^<list>]、リストの長さの計算に使用することを検討することもできます。
user202729

編集します!
J42161217

代わりに0#&@@#{0..}あまりにも動作します。そしてInfix動作するので、最終的なコードはRowReduce@#~Count~{0..}==Tr[1^#]-1&2バイト節約できます。
ジョンファンミン

実際にExceptは、Trものを取り除くために使用することができます。-3バイト:RowReduce@#~Count~Except@{0..}==1&
ジョンファンミン

行削減行列は非ゼロであることが保証されていると思います(元の行列は非ゼロであるため)。したがって、カウント結果は正の整数に<2なるため、の代わりに使用できます==1
user202729

4

JavaScript(ES6)、68 67 65バイト

これは、ニールの05AB1Eの回答に基づいており、元のアプローチよりもはるかに効率的です。

falseランク1および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バイト

falseランク1および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

テストは、我々はtruthy値を取得するとすぐに失敗した:我々は(以外の二つの別個の比率発生したときにこれが発生した0/0との間を)(I、Y)(I、R)任意の行におけるY行列のrは、ゼロ以外の行のインデックスです。


フー、私は自分が…
ニール

@Neil新しい回答として投稿しますか?私に知らせて。
アーナウルド


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
マイルで

@マイルズいいね!あなたのアプローチは少し異なります(私は思う?)ので、あなたが望むあなた自身の答えとしてそれを投稿することができます:)
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₁2番目の行に格納しᶫXます。次にmax(abs(ᶫX場合は、ゼロになるᶫXゼロのみで構成されており、それ以外の場合は正の値、not(行列はランク1、そうでなければ0である場合、1に変更します。

1行の行列の場合、ᶫXはに設定され{0}、行列の存在しない2行目を調べようとしても変更されません。


スコット・ミルナーのおかげで-1バイト

1行の行列の次元エラーを修正するための+1バイト。 1行しかない行列から2行目を抽出しようとするとMatr►list( コマンドが文句を言うことがわかります。ただし、マトリックスから最初と2番目の行の両方を抽出しようとすると、サイレントに失敗します。


1
Prompt [A]代わりにを使用してバイトを保存できますAns→[A]
スコットミルナー

@ScottMilnerありがとう!ClrListinitializeのようなものを使用する場合、おそらくどちらかを回避する方法がありますがᶫX、より少ないスペースで動作するようにはなりません。
ミシャラヴロフ

Matr►list(リストが存在しない場合でもリストを上書きし、5バイトを節約するため、2行目を削除します。
kamoroso94

1
@ kamoroso94 2行目のポイントは、リストが存在しないときにリストを作成しないことです。2行目のポイントは、マトリックスに1行しかない場合に2行目のデフォルト値を作成することです。2行目を削除すると、1xN行列のコードがクラッシュします。
ミシャラヴロフ

2
@ kamoroso94 L1をYではなくᶫYに置き換える必要があります。そうでない場合、計算機は「行列のY番目の行をᶫXに抽出」し、「最初の行をᶫYに抽出し、2番目の行をᶫXに抽出する」とは考えません。
ミシャラヴロフ

3

Brachylog、27バイト

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

オンラインでお試しください!

「各長方形の向かい合う角の積は等しくなければならない」というニールのアプローチを使用します。クロス積はコストがかかり、全体で10バイトかかりますが、これは主に質問の真実と偽について2つの一貫した出力が規定されているため、私が試みた部門ベースのアプローチよりもまだ短いです-偽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∋⟩ᶠ/ᵐ²=ᵐ}

オンラインでお試しください!



1

SageMath、40バイト

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

オンラインで試す

この匿名関数はFalse、行列がランク1の場合に返され、Trueそうでない場合に返されます。

この関数は、M入力として行列を取り、それを縮小された行階層形式(M.rref())に変換しany、最初の行がゼロ以外の行をテストします。次に、その値が乗算されますM.nrows()>1(マトリックスに複数の行がありますか?)。


1

Pythonの393の 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マイナー(非ゼロの行列式を持つp×pサブマトリックス)は、そのサブマトリックスの行と列が線形独立であり、したがって、これらの行と完全な行列の列は(完全な行列で)線形に独立しているため、行と列のランクは少なくとも行列式のランクと同じ大きさです」 Wikipediaより

注:user71546のコメントのおかげで2バイト削られました。


1
91 -短い関数の引数に列挙を置くので、の必要性を排除する場合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))
Shieru Asakoto

@ user71546ありがとう!できた!
ルカシティ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.