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