Membuat kuadrat-akar matriks kovarians positif-pasti (Matlab)


9

Motivasi : Saya sedang menulis estimator keadaan di MATLAB (filter Kalman tanpa pewangi), yang menyerukan pembaruan akar kuadrat (segitiga-atas) dari matriks kovarians pada setiap iterasi (yaitu, untuk matriks kovarian , memang benar bahwa ). Agar saya dapat melakukan perhitungan yang diperlukan, saya perlu melakukan Update dan Downdate Cholesky Rank-1 menggunakan fungsi MATLAB .SPP=SSTcholupdate

Masalah : Sayangnya, selama iterasi, matriks ini terkadang dapat kehilangan kepastian positif. Downdate Cholesky gagal pada matriks non-PD.S

Pertanyaan saya adalah : adakah cara sederhana dan dapat diandalkan dalam MATLAB untuk membuat positif-pasti?S

( atau lebih umum, apakah ada cara yang baik untuk membuat matriks kovarian tertentu pasti-positif?X )


Catatan :

  • S adalah peringkat penuh
  • Saya sudah mencoba pendekatan eigendecomposition (yang tidak berhasil). Ini pada dasarnya melibatkan menemukan , mengatur semua elemen negatif dari , dan merekonstruksi mana adalah matriks dengan hanya elemen positif.S=VDVTV,D=1×108S=VDVTV,D
  • Saya menyadari pendekatan Higham (yang diimplementasikan dalam R as nearpd), tetapi tampaknya hanya memproyeksikan ke matriks PSD terdekat. Saya memerlukan matriks PD untuk pembaruan Cholesky.

Saya pikir mungkin Anda ingin , di mana adalah kovarians, dan adalah faktor Cholesky. S=PPSP
shabbychef

Sebenarnya saya ingin (akar kuadrat, atau dalam hal ini, faktor Cholesky) pasti positif. Saya telah mengklarifikasi pertanyaannya; Terima kasih! S
Gilead

Saya mengalami masalah yang sama. Saya memang mencoba fungsi sqrtm (x) tetapi hanya berfungsi untuk beberapa iterasi. Apakah Anda menemukan solusinya?

Saya mencoba berbagai metode, tetapi akhirnya menggunakan trik standar (non-keras) untuk mengganggu diagonal, yaitu , di mana adalah konstanta yang cukup besar untuk membuat positif-pasti. Mungkin ada pendekatan yang lebih baik, tetapi yang ini cepat dan mudah. S+kIkS
Gilead

Agak terlambat, tetapi berputar adalah strategi yang bermanfaat untuk angka yang tidak stabil.
probabilityislogic

Jawaban:


4

Berikut adalah kode yang saya gunakan di masa lalu (menggunakan pendekatan SVD). Saya tahu Anda mengatakan Anda sudah mencobanya, tetapi selalu berhasil, jadi saya pikir saya akan mempostingnya untuk melihat apakah itu membantu.

function [sigma] = validateCovMatrix(sig)

% [sigma] = validateCovMatrix(sig)
%
% -- INPUT --
% sig:      sample covariance matrix
%
% -- OUTPUT --
% sigma:    positive-definite covariance matrix
%

EPS = 10^-6;
ZERO = 10^-10;

sigma = sig;
[r err] = cholcov(sigma, 0);

if (err ~= 0)
    % the covariance matrix is not positive definite!
    [v d] = eig(sigma);

    % set any of the eigenvalues that are <= 0 to some small positive value
    for n = 1:size(d,1)
        if (d(n, n) <= ZERO)
            d(n, n) = EPS;
        end
    end
    % recompose the covariance matrix, now it should be positive definite.
    sigma = v*d*v';

    [r err] = cholcov(sigma, 0);
    if (err ~= 0)
        disp('ERROR!');
    end
end

Terima kasih atas usaha Anda - sayangnya, itu tidak berhasil. (Aku melakukan sesuatu yang sangat mirip dalam program 3-line saya: [V,D] = eig(A); D(D <= 1e-10) = 1e-6; Apd = V*A*V';). Pendekatan ini mirip dengan yang dilakukan oleh Rebonato dan Jackel, dan tampaknya gagal untuk kasus-kasus patologis seperti milik saya.
Gilead

Itu terlalu buruk. Saya akan tertarik pada contoh matriks yang Anda temukan yang menyebabkan ini (dan metode lain yang Anda coba) gagal jika Anda punya waktu untuk mempostingnya. Ini adalah masalah yang menjengkelkan untuk terus berjalan, saya harap Anda menemukan solusi.
Nick

2

di Matlab:

help cholupdate

saya mendapat

CHOLUPDATE Rank 1 update to Cholesky factorization.
    If R = CHOL(A) is the original Cholesky factorization of A, then
    R1 = CHOLUPDATE(R,X) returns the upper triangular Cholesky factor of A + X*X',
    where X is a column vector of appropriate length.  CHOLUPDATE uses only the
    diagonal and upper triangle of R.  The lower triangle of R is ignored.

    R1 = CHOLUPDATE(R,X,'+') is the same as R1 = CHOLUPDATE(R,X).

    R1 = CHOLUPDATE(R,X,'-') returns the Cholesky factor of A - X*X'.  An error
    message reports when R is not a valid Cholesky factor or when the downdated
    matrix is not positive definite and so does not have a Cholesky factorization.

    [R1,p] = CHOLUPDATE(R,X,'-') will not return an error message.  If p is 0
    then R1 is the Cholesky factor of A - X*X'.  If p is greater than 0, then
    R1 is the Cholesky factor of the original A.  If p is 1 then CHOLUPDATE failed
    because the downdated matrix is not positive definite.  If p is 2, CHOLUPDATE
    failed because the upper triangle of R was not a valid Cholesky factor.

    CHOLUPDATE works only for full matrices.

    See also chol.

Saya menggunakan cholupdatetetapi pertanyaan saya adalah tentang membuat R(dalam hal ini) pasti positif. Saya memiliki kasus di mana Rnon-pd saya, dan cholupdate(R,X,'-')(downdate) gagal.
Gilead

1
semua algoritme online dari formulir ini (pembaruan & downdate) mengalami masalah presisi seperti ini. Saya memiliki masalah serupa dalam 1d yang menghasilkan estimasi negatif varians. Saran saya adalah untuk menjaga buffer melingkar dari vektor k terakhir diamati, dan ketika cholupdategagal, menghitung ulang kovarians berdasarkan buffer melingkar itu dan memakan biayanya. Jika Anda memiliki memori, dan dapat bertahan dengan waktu sesekali ketika ini terjadi, Anda tidak akan menemukan metode yang lebih baik dalam hal akurasi dan kemudahan implementasi.
shabbychef

Terima kasih, itu sesuatu untuk dipikirkan. Sayangnya, matriks kovarians saya mengalami begitu banyak transformasi sehingga tidak jelas pada titik mana saya harus melakukan perhitungan ulang dari buffer lingkaran. Namun demikian, jika semuanya gagal, saya harus dapat menggunakan matriks kovarians PD yang terakhir diketahui - dengan harapan itu tidak menghasilkan bias dalam perkiraan saya.
Gilead

2

Salah satu cara alternatif untuk menghitung factorisation Cholesky adalah dengan memperbaiki elemen diagonal S ke 1, dan kemudian memperkenalkan matriks diagonal D, dengan elemen positif.

Ini menghindari kebutuhan untuk mengambil akar kuadrat ketika melakukan perhitungan, yang dapat menyebabkan masalah ketika berhadapan dengan angka "kecil" (yaitu angka yang cukup kecil sehingga pembulatan yang terjadi karena operasi floating point penting). The halaman wikipedia memiliki apa ini disesuaikan algoritma terlihat seperti.

Jadi, bukannya P=SST Anda mendapatkan P=RDRT dengan S=RD12

Semoga ini membantu!


1
Terima kasih, itu adalah teknik yang berpotensi saya gunakan. Sepertinya sudah diterapkan di sini: infohost.nmt.edu/ ~ portchers
Gilead

1

Secara efektif faktorisasi Cholesky dapat gagal ketika matriks Anda tidak "benar-benar" pasti positif. Dua kasus muncul, atau Anda memiliki nilai eingen negatif, atau nilai eingen terkecil Anda adalah positif, tetapi mendekati nol. Kasus kedua harus secara teoretis memberikan solusi, tetapi sulit secara numerik. Jika baru saja intuitif tambahkan konstanta kecil ke diagonal dari matriks saya untuk menyelesaikan masalah. Tetapi cara ini tidak sulit karena hanya sedikit memodifikasi solusi. Jika Anda harus menghitung solusi akurasi yang sangat tinggi, coba riset tentang faktorisasi Cholesky yang dimodifikasi.


0

Jika Anda mencoba memperkirakan dengan P tidak pasti positif Anda meminta masalah dan algoritma tantangan, Anda harus menghindari situasi ini. Jika masalah Anda numerik: P pasti pasti tetapi nilai eigen numeriknya terlalu kecil - coba scalling baru untuk status Anda. Jika masalah Anda memang tidak pasti pasti positif - coba berbagai set variabel keadaan. Saya harap nasihatnya tidak terlambat Salam, Zeev

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.