Kurs FORTRANU | ||
---|---|---|
Předcházející | Další |
Pole jsou neuvěřitelně silný programovací prostředek. Umožnují jako jediné objekty provádět rozsáhle operace nad jejími prvky najednou a tak umožňují využití počítačů naplno. Je to samozřejmě společně s jiným velmi silným prostředkem cykly. Fortran ovšem umožňuje zacházet s poli mnohem elegantněj.
LU rozklad je určený na řešení soustav lineárních rovnic. Na rozdíl od Gaussovy eliminace je ovšem přímo vyvinuta na použití maticových operací. Uvedeme jeho modul Croutuv rozklad.
Zajimavé je použití proměnné ix. Ta není viditelná pro vnejší svět mimo modulu. Slouží na uložení mezivýsledků indexů při přehazování řádků během pivotování. Pro většinu použití není potřeba a proto je viditelná pouze uvnitř modulu. Pokud je z nějakých důvodů potřeba jej přece jen použít pak je na její získání třeba uvedena subroutina getix. Důležité je, správně alokovat a dealokovat pamět tak aby v průběhu běhu programu nezůstávaly v paměti její nepoužitelné zbytečné kusy.
Module Crout integer, allocatable, private :: ix(:) contains subroutine lu (n,a,d) implicit none integer :: n, i, k, k1 real :: d,a(:,:),s(n),piv deallocate(ix) allocate(ix(n)) d = 0.0 do k = 1, n piv = 0.0 ! Vypocet L do i = k, n a(i,k) = a(i,k) - sum(a(i,1:k-1)*a(1:k-1,k)) if( abs( a(i,k) ) > piv )then k1 = i piv = abs( a(i,k) ) endif enddo ! Singularni matice if( piv == 0.0 ) return ! Vymena radku if( k /= k1 )then s = a(k,:) a(k,:) = a(k1,:) a(k1,:) = s endif ix(k) = k1 ! Vypocet U do j = k + 1, n a(k,j) = (a(k,j) - sum(a(k,1:k-1)*a(1:k-1,j)))/a(k,k) enddo enddo d = 1.0 end subroutine subroutine lusol(n,a,b) Integer :: n, i, k real :: a(:,:),b(:),s if( .not. allocated(ix) ) stop 'Matrix not factorized.' ! prehozeni indexu do i = 1, n - 1 if( ix(i) /= i )then s = b(i) b(i) = b(ix(i)) b(ix(i)) = s endif enddo ! zpetna substitice do spodni matice do i = 1, n b(i) = (b(i) - sum(a(i,1:i-1)*b(1:i-1)) / a(i,i) enddo do i = n - 1, 1, -1 b(i) = b(i) - sum(a(i,i+1:n)*b(i+1:n)) enddo end subroutine subroutine getix(n,ixx) real :: ixx(:) ixx(1:n) = ix(1:n) end subroutine ! jaka bude inverze? end module
Předcházející | Domů | Další |
Pole | Čtení tabulek a obrázků |