Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 06. 04. 2015 15:33 — Editoval SuchSoft (06. 04. 2015 15:54)

SuchSoft
Příspěvky: 25
Reputace:   
 

Ako vytvoriť veľkú riedku kladne definitnú maticu?

Chcem poprosiť, potrebujem vytvoriť veľkú riedku kladne definitnú maticu (nazvime ju B) s vopred danou hustotou nenulových prvkov. Veľkosť do n=50000. Výborné by bolo, keby prvky boli celé čísla. Nejaký nápad, tip na lacný algoritmus/algoritmy, ako ju vytvoriť?
Skúšal som $AA^{T}$, ale tam je zasa podmienka, aby matica A bola regulárna. V tomto prípade mám 2 problémy, ako zabezpečiť žiadanú hustotu, a ako vytvoriť regulárnu maticu.

Zrejme bude nutné použiť iný spôsob vytvorenia matice B. Prosím o pomoc. Stačí ma naviesť správnym smerom. ;)

Základnou úlohou je vypočítať $Ax=b$, to jest vyriešiť sústavu lineárnych rovníc (LR). Mám ju riešiť pomocou Conjugate Gradient method (CG), a porovnanie aj Jacobiho alebo Gauss-Siedelovou metódou.

Ešte mám otázku, ako zistím, že sústava LR má práve jedno riešenie, t. j. že hodnosť matice sa rovná rádu matice?
Ideálny by bol nejaký lacnejší algoritmus, hlavne čo sa týka spotreby pamäte počítača. Budem to robiť v C#.

Veľká vďaka.

Offline

 

#2 07. 04. 2015 01:12 — Editoval Brano (07. 04. 2015 01:21)

Brano
Příspěvky: 2650
Reputace:   229 
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

Sustava ma prave jedno riesenie ak je matica regularna, mam napad ako zabezpecit regularitu pri danej hustote prvkov, ale kladnu definitnost zatial neviem.

Ak si zoberies uplne lubovolnu maticu $A$, tak potom

$I+\lambda A$ bude regulana ak zoberies dostatocne male $\lambda>0$ konretne potrebujes $\lambda<|A|^{-1}$ ale potom je regularna aj matica $\lambda^{-1}I+A$ - co je vyhodnejsie ak chces mat cele cisla. T.j. moj navod je takyto

zober si uplne lubovolu maticu $A$ (s danou hustotou nenulovych prvkov ako potrebujes) vypocitaj jej Frobeniovu normu
$|A|=\sqrt{\sum_{i,j}a_{ij}^2}$
a zvol si nejake cele cislo $k>|A|$ a potom poloz $B=kI+A$ - hustota nenulovych prvkov sa ti moze zmenit maximalne o $1/n$ - kde n je rozmer matice, co by snad pre velke $n$ nemusel byt problem.

BTW: aku hustotu nenulovych prvkov priblizne potrebujes.

Offline

 

#3 07. 04. 2015 02:06 — Editoval Brano (07. 04. 2015 02:07)

Brano
Příspěvky: 2650
Reputace:   229 
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

napadlo ma nieco ine/podobne:

pre lubovolny vektor $v$ je matica $A=I+v.v^T$ kladne definitna a teda aj regularna. Teda ak $v$ ma k - nenulovych prvkov a n - vsetkych prvkov, tak $A$ bude mat $k^2-k+n$ nenulovych prvkov cize hustotu nenulovych bude mat $\frac{k^2-k+n}{n^2}$ tak to k si mozes doladit ako chces a podla toho si vygeneruj vektor $v$ lubovolne a vyrob z neho $A$

$a_{ij}=\begin{cases}v_i^2+1,\ i=j\\v_iv_j,\quad i\not=j\end{cases}$

Offline

 

#4 07. 04. 2015 12:31 — Editoval SuchSoft (07. 04. 2015 13:29)

SuchSoft
Příspěvky: 25
Reputace:   
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

Ahoj, veľká vďaka, že si mi napísal, zatiaľ tomu rozumiem len čiastočne, ale dumám nad tým. Možno sem teraz napíšem aj blbosť, ale to vyplýva z prvej vety tohto príspevku.
Hustotu chcem mať takú, aby v matici bolo maximálne do 20 miliónov prvkov, teda qôli obmedzeniam veľkosti RAM pamäti počítača. T. j. pri matici n=50000 by bola hustota max. 0.8 %, pri n=10000 max. 20 %. Programujem to tak, že indexy mám v ushort, teda v 16-bitovej premennej, takže maximálne bude n=65536. ;)

Pochopil som to správne?

A=I+vv^{T}
v=(1 2 3)
neviem, ako sa v Latexe píše matica, takže
a11=1^2+1
a12=1*2
a13=1*3
a21=2*1
a22=2^2+1
a23=2*3
a31=3*1
a32=3*2
a33=3^2+1

takže
    (2 2 3)
A=(2 5 6)
    (3 6 10)

som ju skontroloval v mojej aplikácii, je kladne definitná. Len ja som zle pochopil z literatúry. Myslel som si, že aii musí byť väčší alebo rovný ako súčet ostatných prvkov v riadku resp. v stlpci. A zrejme postačuje ak je väčší alebo rovný najväčšiemu prvku v riadku, či stĺpci.

Obdivujem Ťa, excelentný nápad :)
Som ja so svojimi vedomosťami ešte ďaleko od toho, aby som tak do toho videl ako Ty, aby som niečo takéto dal.

Opýtam sa, ak mám užívateľom zadanú maticu a chcem skontrolovať, či je kladne definitná, stačí ak overím symetrickosť a potom pomocou Choleského rozkladu, zistím, že nevznikne žiaden prvok na diagonále, ktorý by bol rovný nule alebo mal imaginárnu zložku? Stačí len tieto 2 veci overiť? Dík.

Ehm, asi som sa pomýlil, myslím, že stačí len overiť pomocou Choleského rozkladu, veď ak je kladne definitná, je aj symetrická a aj regulárna, že?

Ale čo ak mám užívateľom zadanú maticu a chcem vedieť, či má práve jedno riešenie, teda h(A) = n, či ako sa zapisuje že hodnosť matice A je rovná stupňu matice. Viem, že je singulárny rozklad, SVD, ale neviem ho použiť, hľadal som niekde postup, ale asi je to pre mňa príliš komplikované. Je nutné pri SVD vypočítať vlastné čísla $\lambda$? Lebo niekde to používajú a niekde nie, teda je asi viacero verzií. Hľadám takú, ktorá je čo najviac numericky stabilná. Ak poznáš literatúru, kde je SVD algoritmus normálne uvedený, privítam to. Ešte raz veľký dík.

(Som Ti napísal do "reputácie", ale omylom som tam napísal "matematická" namiesto "lineárna") :-o

Offline

 

#5 07. 04. 2015 13:26 — Editoval SuchSoft (07. 04. 2015 13:45)

SuchSoft
Příspěvky: 25
Reputace:   
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

Takže idem vytvoriť algoritmus, bude vypadať nejako takto:

v[n]={n náhodných prvkov}
A[n,n]
for j = 0 to j < n
   for i = j to i < n
      if (i == j) then A[i,i] = v[i] * v[i] + 1;
      else A[i,j] = v[i]*v[j]; A[j,i] = A[i,j];
next i,j

Ale pre symetrické matice aj tak budem zapisovať len horný trojuholník, takže za tým "else" vynechám " A[j,i] = A[i,j];" ;)
Resp. aj tak to ešte budem musieť prerobiť, nakoľko pôjde o veľmi riedke matice, takže budem zapisovať len nenulové prvky. Ale najprv to chcem vyskúšať na menších maticiach s klasickým zápisom.
A ešte odskúšam tú hustotu nenulových prvkov, aj keď logicky to sedí ten vzorec (k*k-k+n)/n*n

Ešte raz díky.

Offline

 

#6 07. 04. 2015 16:22 — Editoval Brano (07. 04. 2015 16:33)

Brano
Příspěvky: 2650
Reputace:   229 
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

co sa tyka nejakych efektivnych algoritmov na overovanie kladnej definitnosti, tak neviem poradit - vyzera, ze ta choleskeho dekompozicia funguje iba na symetricke matice, ale uprimne .. moc sa v tom nevyznam (to je z mojho pohladu uz numericka matematika)

ono plati ze ak je matica pozitivne definitna tak je aj regularna (co je pre stvorcove matice to iste ako, ze hodnost je rovna rozmeru), btw regularnost sa da testovat aj tak, ze vypocitas determinant a pozries sa ci je rozny od nuly - ale to moze byt pre obrovske matice problematicke

avsak pozor kladne definitna matica nemusi byt nutne symetricka.

ten sposob na generovanie co ma napadol vsak vyrobi vzdy symetricku maticu, ale to som predpokladal, ze by nemusel byt problem.

inak cele to vychadza z takejto uvahy:

pozorovanie 1: sucet kladne semi-definitnych matic je kladne semi-definitna matica, avsak ak je z nich apon jedna kladne definitna, tak vysledok bude kladne definitna matica.

pozorovanie 2: pre lubovolnu maticu $A$ je $AA^T$ kladne semi-definitna a symetricka

pozorovanie 3: lubovolna diagonalne matica, ktora ma vsetky prvny na diagonale kladne je kladne definitna.

takze najjednoduchsia moznost bola zobrat $I+vv^T$ lebo vektor je taka jednoducha matica a jednotkova je zase taka co najjednoduchsia diagonalna

ale mohol by si zobrat aj trebars $D+AA^T+B$
kde D je diagonalna s kladnymi clenmi na diag., A je lubovolna a B je lubovolna antisymetricka
(totizto antisymetricke matice su kladne semi-definitne) - a takto by si vedel vygenerovat aj nesymetricke matice
len si musis dat pozor na to co sa deje s tou hustotou nenulovych prvkov.

Offline

 

#7 09. 04. 2015 11:12 — Editoval SuchSoft (09. 04. 2015 11:16)

SuchSoft
Příspěvky: 25
Reputace:   
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

Ahoj, veľmi si mi pomohol. Funguje to, len to má jeden háčik, tvorí to matice, ktoré majú veľmi veľa vektorov, ktoré sú súčasťou jednotkovej matice I. T. j. vektor má samé nuly, len na diagonále je jednička. Vo svojej podstate tieto riadky a stĺpce (s rovnakým indexom) môžem vyhodiť a ostane mi matica s nenulovými prvkami. Tie riadky a stĺpce, čo som vyhodil, boli už vlastne vyriešené niektoré neznáme $x_{n}$, ktoré nemajú vplyv na zvyšok sústavy rovníc.

Zistil som, že ak použijem viac vektorov a vytvorím viac takýchto matíc a tieto vynásobím, resp. ich ani nemusím násobiť, stačí keď ich sčítam a pri každom sčítaní odčítam jednotkovú maticu. Dostanem symetrickú kladne definitnú a dúfam, že aj regulárnu maticu, ktorá má menej vektorov, ktoré majú samé nuly a na diagonále jedničku.
Podmienkou je, že v týchto dvoch vektoroch sa nesmú nenulové prvky prelínať, myslím tým, že platí: $\Sigma(|v_{1i}*v_{2i}|)=0$

napríklad, ak použijem na vytvorenie dvoch matíc tieto vektory:
$\vec{2,0,0,0,3,1,0}$
$\vec{0,3,1,1,0,0,2}$

Tak mi vzniknú dve matice A1 a A2, ktoré majú 13 a 19 prvkov.
Ak tieto matice vynásobím $A_{1}*A_{2}$ alebo ich takto sčítam (je to ekvivalentné):
$A_{1}+A_{2}-I$
vnikne matica, ktorá má 13 + 19 - n prvkov, takže 25 prvkov.

Ak by som vytvoril vhodný počet vektorov s vhodnými počtami nenulových prvkov, mohol by som dosiahnúť približne takú hustotu, akú potrebujem a matica by nemala riadky typu $x_{i} = vysledok$. Problém je len ten, že neviem z toho vytvoriť rovnicu, aby som vedel nejakým spôsobom vypočítať, koľko vektorov a s koľkými nenulovými prvkami vytvoriť.
Jedno je isté, súčet všetkých nenulových prvkov vektorov musí byť rovný n, kde n je počet všetkých prvkov v tých vektoroch. Tak dosiahnem, že nebudú v matici riadky, ktoré nemajú žiaden vplyv na ostatné, t. j. $x_{i} = vysledok$.

Asi sa na to pozerám dosť komlikovaným spôsobom, asi sa to dá dosiahnúť nejako jednoduchšie. Vieš, prosím Ťa, pomôcť? Díky.

Offline

 

#8 09. 04. 2015 14:31 — Editoval Brano (09. 04. 2015 14:37)

Brano
Příspěvky: 2650
Reputace:   229 
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

cize chces nieco taketo:

$D+vv^T+ww^T$

(D je diagonalna - nemusi byt nutne jednotkova staci ak ma kladne prvky)
v - ma k nenulovych prvkov a n-k nulovych
w - ma n-k nenulovych prvkov a k nulovych
a to tak, ze sa tie prekryvaju nuly jedneho s nenulami druheho

potom bude vysladna matica kladne definitna (a teda samozrejme aj regularna) a nebude mat ziaden trivialny (s iba jednym nenulovym cislom) riadok ci stlpec.

Pocet nenulovych prvkov bude $k^2-k+(n-k)^2-(n-k)+n=n^2-2nk+2k^2\ge n^2/2$ takze hustota bude aspon 0.5 co velmi nevyhovuje tvojim podmienkam, takze na to treba ist trochu inak

keby si ale zobral viac vektorov povedzme $p$ a to $v_1$ az $v_p$ s tym ze pocty nenulovych prvkov by mali zaradom $k_1>1$ az $k_p>1$ a to zase tak aby na i-tej pozicii mal prve jeden z nich nenulovy prvok a ostatne nulove
napr.
( 1, 2, 0, 0, 0, 0)
( 0, 0,-1,-2, 0, 0)
( 0, 0, 0, 0, 1,-1)
tak potom matica $A=D+v_1v_1^T+...+v_pv_p^T$
bude kladne definitna a bez trivialnych riadkov a pocet nenulovych prvkov bude mat
$k_1^2-k_1+k_2^2-k_2+...+k_p^2-k_p+n=k_1^2+k_2^2+...+k_p^2$
pricom minimum dosiahneme ak $k_i=n/p$ co zodpoveda potom vyslednej hustute $1/p$

teda v tvojom pripade n=50000 by si potreboval 125 takychto vektorov a kazdy so 400 nenulovymi prvkami a budes mat vyslednu hustotu 0.008 aku si chcel

este poznamenajme, ze vlastne vsetky tie vektory mozes napchat do jedneho pola velkosti n x 2
v[i,j] kde v[i,0] je nenulove cislo a v[i,1] je cislo od 1 do p ktore ti povie o ktory vektor sa vlastne jedna
a tu diagonalnu (ak by si chcel nieco ine ako jednotkovu) tak tiez napchas do pola D velkosti n

for (i=0,i<n,i++){
A[i,i]=D[i]+v[i,0]^2
for(j=i+1,j<n,j++)
    if (v[i,1]==v[j,1]) then A[i,j]=A[j,i]=v[i,0]*v[j,0]
    else A[i,j]=A[j,i]=0
}

Offline

 

#9 09. 04. 2015 21:40 — Editoval SuchSoft (10. 04. 2015 08:48)

SuchSoft
Příspěvky: 25
Reputace:   
 

Re: Ako vytvoriť veľkú riedku kladne definitnú maticu?

Neviem, čo Ti mám napísať, nekonečná vďaka. Bolo mi jasné, že bude treba viac tých vektorov, ak to nechcem mať husté, a aj to mi napadlo, že to vo svojej podstate môžem uložiť do jednorozmerného poľa, teda vektora. Len som sa nevedel vysomáriť z toho, nevedel som ako zostaviť vzorec.

Ešte raz díky.

Ešte sa chcem opýtať.

Prosím Ťa, čo si myslíš, ktorý je najjednoduchší spôsob, ako overiť, či je matica regulárna alebo nie? Podľa toho, čo som si naštudoval, tak mi vychádza SVD, ale ten sa mi zdá dosť komplikovaný, a navyše sa neviem dopátrať k algoritmu, ako SVD previesť. Problém je, že skoro v každom zdroji sú nejaké odlišnosti, trošku som z toho zmätený.

Tak zasa ďakujem.


PS: Ešte doplním, mne vlastne stačí, ak si vytvorím jeden vektor, ktorý naplním náhodnými hodnotami v rozsahu, aký potrebujem (teda okrem nuly), potom to môžem spraviť tak, že prvých 400, bude prvý vektor, druhých 400 bude druhý vektor, aj tak ďalej, až stodvadsiatychpiatych 400 bude posledný vektor. Takže mi stačí jednorozmerné pole. Myslím si, snáď sa nemýlim, že je to jedno, ako budú nenulové prvky rozmiestnené vo vektoroch. Díky.

PS2: A ešte doplním, hlavnú diagonálu spravím oddelene - $v_{i}*v_{i}$
To ale nechám na zajtra, lebo už som dosť unavený. Vďaka.

PS3: Keď som zaspával mi napadlo, že to prvé PS nie je dobrý nápad, lebo by matica mala nerovnomernú hustotu, t. j., čím nižší ktorýkoľvek z indexov i, j, tým vyššia hustota nenulových prvkov. :-o Takže to spravím tak, ako si mi poradil.

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson