Apakah matriks peringkat-satu?


21

Diberikan matriks bilangan bulat, uji apakah itu peringkat-satu, artinya setiap baris adalah kelipatan dari vektor yang sama. Misalnya, dalam

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

setiap baris adalah kelipatan 1 0 -10 5.

Definisi yang sama juga berfungsi dengan kolom menggantikan baris. Atau, sebuah matriks adalah peringkat-satu jika itu seperti tabel perkalian:

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

Kami telah menetapkan label baris r[i]dan label kolom c[j]sehingga setiap entri matriks M[i][j]adalah produk dari label terkait M[i][j] = r[i] * c[j].

Memasukkan:

Matriks integer sebagai wadah 2D pilihan Anda. Misalnya, daftar daftar, array 2D, atau yang serupa. Anda tidak boleh mengambil lebar atau tinggi sebagai input tambahan kecuali format array mengharuskannya.

Matriksnya mungkin non-kuadrat. Ini akan memiliki setidaknya satu entri bukan nol - Anda tidak harus berurusan dengan matriks kosong atau nol.

Anda dapat mengasumsikan bilangan bulat tidak akan menyebabkan masalah melimpah.

Keluaran:

Nilai yang konsisten untuk matriks peringkat-satu, dan nilai konsisten yang berbeda untuk matriks lainnya.

Built-in:

Anda tidak boleh menggunakan bawaan apa pun untuk menghitung peringkat atau langsung memeriksa peringkat satu. Anda dapat menggunakan built-in lainnya seperti nilai eigen, dekomposisi, dll, tetapi saya mendorong jawaban upvot yang tidak memiliki built-in melakukan sebagian besar pekerjaan.

Kasus uji:

Peringkat satu:

[[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]]

Bukan peringkat satu:

[[-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]]

Papan peringkat:


2
Bagi yang penasaran, respons Mathematica menggunakan builtin akan terlihat seperti ini (16 byte):MatrixRank@#==1&
JungHwan Min


2
Teorema yang indah adalah bahwa peringkat kolom sama dengan peringkat baris untuk matriks dimensi hingga.
Leaky Nun

3
Apakah kita harus khawatir tentang masalah presisi float? Mereka mungkin membuat matriks peringkat-1 tampaknya peringkat 2 misalnya
Luis Mendo

@LuisMendo Anda harus menangani masalah presisi seperti nilai eigen dari 1,0000000001, tetapi dapat mengasumsikan bahwa matriksnya tidak besar dan tidak secara khusus dipilih untuk diklasifikasikan secara salah.
xnor

Jawaban:


13

Jelly , 6 byte

ẸÐfÆrE

Cobalah online!

Bagaimana itu bekerja

ẸÐ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.

Presisi

Ærmenggunakan metode numerik, jadi hasilnya biasanya tidak eksak. Misalnya, input [6, -5, 1] , yang merepresentasikan polinomial 6 - 5x + x² , menghasilkan akar 3.0000000000000000004 dan 1.999999999999999898 . Namun, mengalikan semua koefisien polinomial dengan konstanta tidak nol yang sama menghasilkan akar yang sama-sama tidak eksak. Misalnya, Ærmendapatkan akar yang sama untuk [6, -5, 1] dan [6 × 10 100 , -5 × 10 100 , 10 100 ] .

Perlu dicatat bahwa ketepatan float dan tipe kompleks yang terbatas dapat menyebabkan kesalahan. Misalnya, Ærakan mendapatkan akar yang sama untuk [1, 1] dan [10 100 , 10 100 + 1] . Karena kita dapat mengasumsikan bahwa matriksnya tidak besar dan tidak secara khusus dipilih untuk diklasifikasi secara keliru , maka itu boleh saja.


5
mengalikan semua koefisien polinomial dengan hasil konstanta tidak nol yang sama pada akar yang sama-sama tidak eksak. Itu adalah pendekatan yang brilian
Luis Mendo

8

Haskell , 50 byte

rmengambil daftar daftar Integers dan mengembalikan Falsejika matriks memiliki peringkat satu, Truejika tidak.

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

Cobalah online!

Bagaimana itu bekerja

  • Menghasilkan semua pasangan baris adan b(termasuk baris yang sama), dan untuk setiap pasangan, memungkinkan xdan ymenjalankan elemen yang sesuai.
  • Mengalikan baris bdemi baris xdan baris ademi baris y. Matriks akan memiliki peringkat satu jika dan hanya jika hasilnya selalu sama.
  • Karena pasangan dihasilkan di kedua pesanan, <dapat digunakan untuk memeriksa apakah ada ketimpangan. Daftar hasil pengujian digabungkan dengan or, memberi Truejika ada baris yang tidak proporsional.

7

Mathematica, 51 33 byte

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

Memasukkan

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

-14 byte dari user202729
3 byte lagi disimpan dari junghwanmin


Saya menyarankan agar, alih-alih membangun tabel dengan panjang sama dengan First@#, Anda dapat menghitung 0First@#karena 0 dikalikan dengan semuanya adalah 0, dan perkalian adalah daftar. Anda juga dapat mempertimbangkan menggunakan Tr[1^<list>]untuk menghitung panjang daftar.
user202729

sangat bagus. Saya akan mengedit!
J42161217

Alih-alih 0#&@@#, {0..}akan bekerja juga. Dan kemudian Infixberfungsi, sehingga kode akhir bisa RowReduce@#~Count~{0..}==Tr[1^#]-1&, menghemat 2 byte.
JungHwan Min

Sebenarnya, Exceptbisa digunakan untuk menyingkirkan Trbarang. -3 byte:RowReduce@#~Count~Except@{0..}==1&
JungHwan Min

Saya pikir baris-mengurangi matriks dijamin bukan nol (karena matriks asli bukan nol), dengan demikian hasil hitungan akan menjadi bilangan bulat positif, sehingga <2dapat digunakan sebagai pengganti ==1.
user202729

4

JavaScript (ES6), 68 67 65 byte

Yang ini didasarkan pada jawaban 05AB1E Neil dan secara signifikan lebih efisien daripada pendekatan asli saya.

Pengembalian falseuntuk peringkat satu dan truesebaliknya.

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

Uji kasus


Jawaban asli, 84 byte

Pengembalian falseuntuk peringkat satu dan truesebaliknya.

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))

Uji kasus

Bagaimana?

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()

Pengurangan yang dilakukan pada akhir kode dapat menyebabkan berbagai situasi, yang dirangkum di bawah ini:

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

Tes gagal segera setelah kami mendapatkan nilai kebenaran: ini terjadi ketika kami menemukan dua rasio yang berbeda (selain 0/0 ) antara a (i, y) dan a (i, r) di setiap baris y dari matriks, di mana r adalah indeks dari baris yang tidak nol.


Huh, saya sendiri hanya ingin tahu ...
Neil

@Neil Apakah Anda ingin mempostingnya sebagai jawaban baru? Kabari saja.
Arnauld


3

Jelly , 12 byte

ẸÐfµ÷"ЀZE€Ẹ

Cobalah online!

Penjelasan

ẸÐ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?

Penjelasan mungkin sedikit salah karena ini adalah interpretasi saya tentang golf miles dari algoritma asli saya

-5 byte berkat mil


... Kode Anda kecanduan uang. (Aku mulai deja vu ...)
totallyhuman

@icrieverytim Hai setidaknya jumlah tanda dolar kurang dari setengah panjang kode kali ini! : P
HyperNeutrino

1
@icrieverytim memperbaiki bug dan sekarang lebih sedikit tanda dolar: P
HyperNeutrino

Saya percaya ini harus bekerja juga untuk 12 byte ẸÐfµ÷"ЀZE€Ẹ TIO
mil

@miles Oh bagus! Pendekatan untuk Anda agak berbeda (saya pikir?) Sehingga Anda dapat memposting itu sebagai jawaban Anda sendiri yang Anda inginkan :)
HyperNeutrino

3

05AB1E , 16 byte

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

Cobalah online! Menggunakan properti tabel perkalian yang sudut-sudut yang berlawanan dari persegi panjang apa pun memiliki produk yang sama. Penjelasan:

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 (seri TI-83), 28 27 28 byte (62 karakter)

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

Menghitung bentuk eselon baris dari matriks [A], menyimpan baris pertama (yang akan dibuang) di L₁dan baris kedua di ᶫX. Maka max(abs(ᶫXakan menjadi nol jika ᶫXhanya terdiri dari nol, dan nilai positif sebaliknya, yang not(berubah menjadi 1 jika matriksnya adalah peringkat satu, 0 sebaliknya.

Untuk matriks 1-baris, ᶫXdisetel ke {0}dan kemudian tidak berubah ketika kami mencoba melihat baris kedua dari matriks yang tidak ada.


-1 byte terima kasih kepada Scott Milner

+1 byte untuk memperbaiki kesalahan dimensi untuk matriks 1-baris. Ternyata Matr►list( perintah mengeluh jika Anda mencoba untuk mengekstrak baris kedua dari sebuah matriks dengan hanya satu baris; namun, jika Anda mencoba mengekstrak baris pertama dan kedua dari matriks, ia akan gagal secara diam-diam.


1
Anda dapat menyimpan byte dengan Prompt [A]alih - alih Ans→[A].
Scott Milner

@ScottMilner Terima kasih! Mungkin ada cara untuk menghindarinya jika kita menggunakan sesuatu ClrListuntuk menginisialisasi ᶫX, tetapi saya belum cukup berhasil melakukannya di ruang yang lebih sedikit.
Misha Lavrov

Singkirkan baris kedua, karena Matr►list(akan menimpa daftar, meskipun tidak ada, dan Anda akan menghemat 5 byte.
kamoroso94

1
@ kamoroso94 Inti dari baris kedua bukan untuk membuat daftar ketika itu tidak ada: titik dari baris kedua adalah untuk membuat nilai default untuk baris kedua ketika matriks hanya memiliki satu baris. Jika Anda menyingkirkan baris kedua, kode macet untuk matriks 1xN.
Misha Lavrov

2
@ kamoroso94 Kita harus mengganti L1 dengan ᶫY, bukan Y; jika tidak, kalkulator akan berpikir "mengekstrak baris Y-th dari matriks ke ᶫX", bukan "mengekstrak baris pertama ke ᶫY, dan baris kedua ke ᶫX".
Misha Lavrov

3

Brachylog , 27 byte

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

Cobalah online!

Menggunakan pendekatan Neil tentang "produk dari sudut yang berlawanan dari setiap kotak harus sama". Produk silang mahal dan membutuhkan 10 byte penuh, tetapi ini masih lebih pendek daripada pendekatan berbasis divisi yang saya coba, terutama karena penetapan dua output yang konsisten untuk kebenaran dan kepalsuan dalam pertanyaan - membuat kepalsuan hanya menjadi false., dan tidak kadang-kadang kesalahan divide-by-zero, menggunakan terlalu banyak byte.

{⊇Ċ}ᶠ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.)

Pendekatan alternatif berdasarkan pembagian elemen-bijaksana ( 30 byte ):

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

Cobalah online!


2

Jelly , 9 byte

ẸÐf÷g/$€E

Cobalah online!

ẸÐ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 byte

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

Cobalah online

Fungsi anonim ini kembali Falsejika matriksnya adalah peringkat satu, dan Truesebaliknya.

Fungsi ini mengambil matriks Msebagai input, mengubahnya menjadi bentuk eselon baris tereduksi ( M.rref()), dan menguji untuk anybaris yang melewati yang pertama menjadi bukan nol. Kemudian, nilai itu dikalikan dengan M.nrows()>1(apakah matriks memiliki lebih dari satu baris?).


1

Python 3 , 93 91 byte

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))

Cobalah online!

Bagaimana itu bekerja

Cek apakah ada 2-minor yang memiliki penentu nol. Jika hal ini terjadi, peringkat harus setidaknya 2: "P-minor non-vanishing (p × p submatrix dengan determinan non-nol) menunjukkan bahwa baris dan kolom dari submatrix tersebut bebas linear, dan dengan demikian baris dan kolom dari matriks penuh adalah bebas linier (dalam matriks penuh), sehingga peringkat baris dan kolom setidaknya sama besar dengan peringkat penentu "(dari Wikipedia )

Catatan: mencukur dua byte berkat komentar pengguna71546.


1
91 - lebih pendek jika memasukkan enumerate ke dalam argumen fungsi dan dengan demikian menghilangkan kebutuhan 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 Terima kasih! Selesai!
Luca Citi

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.