Apakah Matriksnya Positif-Jelas?


19

pengantar

Hari ini kita akan menangani kutukan siswa aljabar linear tahun pertama: ketegasan matriks! Tampaknya ini belum memiliki tantangan, jadi mari kita mulai:

Memasukkan

  • A Matriks simetris dalam format apa pun yang nyaman (Anda tentu saja juga dapat mengambil bagian atas atau bawah dari matriks)n×n A
  • Secara opsional: ukuran matriksn

Apa yang harus dilakukan?

Tantangannya sederhana: Diberikan matriks bernilai nyata Matriks memutuskan apakah itu pasti positif dengan mengeluarkan nilai kebenaran jika demikian dan nilai palsu jika tidak.n×n

Anda dapat mengasumsikan built-in Anda benar-benar berfungsi secara tepat dan karenanya tidak harus memperhitungkan masalah numerik yang dapat mengarah pada perilaku yang salah jika strategi / kode "terbukti" harus menghasilkan hasil yang benar.

Yang menang?

Ini adalah , jadi kode terpendek dalam byte (per-bahasa) menang!


Apa itu Matriks definitif positif?

Rupanya ada 6 formulasi yang setara ketika sebuah matriks simetris adalah positif-pasti. Saya akan mereproduksi tiga yang lebih mudah dan merujuk Anda ke Wikipedia untuk yang lebih kompleks.

  • Jika maka adalah pasti-positif. Ini dapat dirumuskan ulang sebagai: Jika untuk setiap vektor bukan nol (standar) produk titik dan adalah positif maka adalah pasti-positif.vRn{0}:vTAv>0Av v A v A

    vvAvA
  • Biarkan menjadi nilai eigen dari , jika sekarang (itu saja nilai eigen adalah positif) maka adalah positif-pasti. Jika Anda tidak tahu apa nilai eigennya, saya sarankan Anda menggunakan mesin pencari favorit Anda untuk mengetahuinya, karena penjelasan (dan strategi perhitungan yang diperlukan) terlalu lama untuk dimuat dalam pos ini.λii{1,,n}A i { 1 , , n } : λ i > 0 AAi{1,,n}:λi>0A
  • Jika Cholesky-penguraian dari ada, yaitu terdapat matriks yang lebih rendah-segitiga sehingga maka adalah positif-pasti. Perhatikan bahwa ini setara dengan "false" yang dikembalikan lebih awal jika pada suatu saat perhitungan root selama algoritma gagal karena argumen negatif.ALLLT=AA

Contohnya

Untuk hasil yang benar

(100010001)

(1000020000300004)

(521211113)

(1222502030)

(7.152.452.459.37)

Untuk output falsey

(setidaknya satu nilai eigen adalah 0 / positif semi-pasti)

(322240202)

(nilai eigen memiliki tanda yang berbeda / tidak terbatas)

(100010001)

(semua nilai eigen lebih kecil dari 0 / negatif pasti)

(100010001)

(semua nilai eigen lebih kecil dari 0 / negatif pasti)

(230350001)

(semua nilai eigen lebih kecil dari 0 / negatif pasti)

(7.152.452.459.37)

(tiga positif, satu nilai eigen negatif / tidak terbatas)

(7.152.451.233.52.459.372.713.141.232.7106.23.53.146.20.56)



Anda perlu memberikan definisi yang lebih baik tentang apa yang seharusnya kita cari daripada mengasumsikan kita semua dapat membaca notasi matematika (atau semua tahu apa itu "nilai eigen"). Contoh yang dikerjakan akan bermanfaat juga.
Shaggy

9
@ Shaggy Saya pikir tantangannya lebih baik tanpa semua latar belakang untuk menyumbatnya. Ada banyak penjelasan tentang nilai eigen di tempat lain, dan pos ini sudah sangat besar.
Wheat Wizard

1
Tantangannya akan lebih bagus jika Anda tidak membatasi input ke matriks simetris .
polfosol ఠ_ఠ

1
Maksud saya hanya memeriksa tanda nilai eigen juga membosankan. Selera berbeda, saya tahu;)
polfosol ఠ_ఠ

Jawaban:


11

C, 108 byte

Terima kasih -1 byte untuk Logern
-3 byte berkat ceilingcat

f(M,n,i)double**M;{for(i=n*n;i--;)M[i/n][i%n]-=M[n][i%n]*M[i/n][n]/M[n][n];return M[n][n]>0&(!n||f(M,n-1));}

Cobalah online!

Melakukan eliminasi Gaussian dan memeriksa apakah semua elemen diagonal positif (kriteria Sylvester). Argumen nadalah ukuran dari matriks minus satu.


Mungkin menyimpan karakter dengan float, bukan double?
Jens


Anda dapat mencukur karakter lain jika Anda menjatuhkan i=0for loop, membuat panggilan rekursif f(M,n-1,0)dan panggilan awal dengan 0 sebagai arg ketiga.
Jens

@ Jens 1. Menggunakan float bukannya double dapat dengan cepat menyebabkan kesalahan pembulatan yang nyata, jadi saya tidak berpikir satu byte yang disimpan tidak sia-sia. 2. Menginisialisasi variabel melalui argumen tambahan tampak seperti menipu saya.
nwellnhof

@Logern saya menolak untuk menggunakan trik "hapus pernyataan pengembalian" dalam jawaban C. Tetapi terima kasih untuk byte lain yang disimpan.
nwellnhof

9

MATLAB / Oktaf , 19 17 12 byte

@(A)eig(A)>0

Cobalah online!

Function eig menyediakan nilai eigen dalam urutan naik, jadi jika nilai eigen pertama lebih besar dari nol, yang lainnya juga.


Anda dapat menghentikannya f=di awal - fungsi anonim umumnya diterima sebagai jawaban.
Delfad0r

Terima kasih atas tipnya!
Daniel Turizo

Bahkan jika itu vektor? Menarik
Daniel Turizo

1
+1. Saya telah menambahkan tautan untuk mencobanya secara online. Semoga kamu tidak keberatan. Perhatikan bahwa ini juga membuktikan bahwa nilai-nilai output meskipun array benar-benar dihitung sebagai nilai "kebenaran" atau "falsey" yang tepat sesuai dengan tautan @ Delfad0r yang diposting.
Tom Carpenter

2
Karena itu, gagal untuk kasus uji "falsey" pertama di TIO. Saya menduga karena masalah presisi - salah satu nilai Eigen keluar sebagai 8.9219e-17bukan 0.
Tom Carpenter

7

Jelly , 11 10 byte

ṖṖ€$ƬÆḊṂ>0

Menggunakan kriteria Sylvester .

Cobalah online!

Bagaimana itu bekerja

ṖṖ€$ƬÆḊṂ>0  Main link. Argument: M (matrix)

   $Ƭ       Do the following until a fixed point is encountered.
Ṗ             Pop; remove the last row of the matrix.
 Ṗ€           Pop each; remove the last entry of each row.
     ÆḊ     Take the determinants of the resulting minors.
       Ṃ    Take the minimum.
        >0  Test if the least determinant is positive, i.e., if all determinants are.


6

Haskell , 56 byte

f((x:y):z)=x>0&&f[zipWith(-)v$map(u/x*)y|u:v<-z]
f[]=1>0

Cobalah online!

Pada dasarnya sebuah port jawaban nwellnhof . Melakukan eliminasi gaussian dan memeriksa apakah elemen-elemen pada diagonal utama positif.

Gagal output falsey pertama karena kesalahan pembulatan, tetapi secara teoritis akan bekerja dengan presisi tak terbatas. Berkat saran Curtis Bechtel , sekarang semua hasilnya benar.


2
Anda dapat menambahkan inputs :: [[[Rational]]]untuk mendapatkan jawaban yang benar
Curtis Bechtel

4

Bahasa Wolfram (Mathematica) , 20 byte

0<Min@Eigenvalues@#&

Cobalah online!


Haruskah test case ke 4 salah?
tsh

@ tsh Diperbaiki, saya bodoh!
Tn. Xcoder

8
Lucu bagaimana Mathematica memiliki builtin untuk ini , tetapi namanya lebih panjang dari solusi Anda.
Federico Poloni

@FedericoPoloni: Bukankah solusi menggunakan NullSpace atau MatrixRank bahkan lebih pendek? Jika ruang kosong adalah nol maka matriksnya pasti positif.
Phil H

@ Philip Tidak, saya khawatir itu tidak bekerja dengan sendirinya. Misalnya, contoh falsey kedua (matriks diagonal dengan (1, -1,1)) memiliki peringkat 3, tetapi tidak pasti positif.
Federico Poloni




2

MATL , 6 byte

Dimungkinkan untuk melakukannya menggunakan byte yang lebih sedikit, @Mr. Xcoder berhasil menemukan jawaban MATL 5 byte !

YvX<0>

Penjelasan

Yv     compute eigenvalues
  X<   take the minimum
    0> check whether it is greather than zero

Cobalah online!


Gagal pada kasus uji falsy pertama. Lihat jawaban saya yang terhapus .
Tn. Xcoder

1
@ Mr.Xcoder Oh, Anda bahkan mengirim jawaban sebelum saya. Saya pikir Anda harus membatalkan penghapusan jawaban karena hanya tergantung pada masalah pembulatan. (Saya pikir Anda dapat mengharapkan jawaban untuk menggunakan aritmatika presisi terbatas - Saya pikir hanya bahasa CAS di sini yang menggunakan perhitungan yang tepat.)
flawr

Mengikuti saran Anda, saya telah membatalkannya .
Tn. Xcoder

1

Maple , 33 byte

(yaitu 2 sen saya)

with(LinearAlgebra):
IsDefinite(A)

Halo dan selamat datang di PPCG; Saya tidak terbiasa dengan Maple, apakah perlu baris baru?
Jonathan Frech

@ JonathanFrech Halo dan terima kasih. Bukan itu. Saya tidak menghitungnya btw.
polfosol ఠ_ఠ

Bagi saya jumlah byte Anda saat ini tampaknya mencerminkan karakter baris baru.
Jonathan Frech

@JonathanFrech Duh,
salahku

1
Nah ... sekarang kode Anda dan jumlah byte Anda tidak setuju.
Jonathan Frech

0

JavaScript (ES6),  99 95  88 byte

01

f=(m,n=0,R=m[n])=>R?f(m,n+1)&R[m.map((r,y)=>y<n&&R.map((v,x)=>r[x]-=v*r[n]/R[n])),n]>0:1

Cobalah online!

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.