am1x

lab22b

Feb 29th, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Fortran 5.06 KB | Fixit | 0 0
  1. module methods
  2.     implicit none
  3.     contains
  4.    
  5.     function f(x) result(y) !Функция исходная(с пограшностями) !ОК
  6.         real(8), intent(in) ::  x
  7.         real(8) :: y
  8.         !y = x**2d0 + 1d0 - (4d0*datan(1d0)/2d0 - x - (x**3d0)/6d0)
  9.         y = x**2d0 + 1d0 - dacos(x)
  10.         !y = x**2d0
  11.     end function
  12.    
  13.     function e(x,n) result(y) !Базисная функция !ОК
  14.         integer, intent(in) :: n
  15.         real(8), intent(in) ::  x
  16.         real(8) :: y
  17.         y = x**real(n-1,8)
  18.         !y = dcos(real(n-1,8)*dacos(x))
  19.     end function
  20.    
  21.     function pf(res,x,n) result(y) !Вычисление приближения в точке !ОК
  22.         integer, intent(in) :: n
  23.         real(8), intent(in) ::  x
  24.         integer :: i
  25.         real(8), dimension(:) :: res(n)
  26.         real(8) :: y
  27.         y=0d0
  28.         do i = 1,n
  29.             y = y + res(i)*e(x,i)
  30.         end do
  31.     end function
  32.     subroutine cholesky1(A,b,n,res) !Разложение Холецкого
  33.         real(8),dimension(:,:) :: A
  34.         real(8),dimension(:) :: b, res
  35.         real(8), allocatable :: y1(:)
  36.         real(8) :: sum
  37.         integer, intent(in) :: n
  38.         integer :: i,j,P
  39.         integer :: info
  40.         allocate(y1(n))
  41.         !L = 0d0
  42.         !L = A
  43.         !do i = 1, n !i столбец
  44.             !do j = i, n !j строка
  45.                 !Вычисление суммы
  46.                 !sum = 0d0
  47.                 !do p = 1, i-1
  48.                     !sum = sum + A(i,p)*A(j,p)
  49.                 !end do
  50.                 !Разложение                
  51.                 !if (j==i)  then
  52.                     !A(i,i) = dsqrt(A(i,i) - sum)
  53.                 !else
  54.                     !A(j,i) = (A(j,i) - sum)/A(i,i)
  55.                 !end if
  56.             !end do
  57.         !end do
  58.         call DPOTRF("L", n, A, n,info)
  59.         write(*,*) "info", info
  60.         do i = 1,n-1
  61.             A(i,i+1:) = 0d0
  62.         end do
  63.         !Решаем Ly = b
  64.         y1 = 0d0
  65.         do i = 1,n
  66.             do j = 1, i-1
  67.                 b(i) = b(i) - A(i,j)*y1(j)
  68.             end do
  69.             y1(i) = b(i)/A(i,i)
  70.         end do
  71.         !Решаем (L**T)x = y
  72.         A = transpose(A)
  73.         res = 0d0
  74.         do i = n,1,-1
  75.             do j = n, i+1,-1
  76.                 y1(i) = y1(i) - A(i,j)*res(j)
  77.             end do
  78.             res(i) = y1(i)/A(i,i)
  79.         end do
  80.         !write(*,*) "RESULT", norm2(MATMUL(A,res) - b)
  81.         deallocate(y1)
  82.     end subroutine
  83.    
  84.     subroutine gengrid(grid,n,a,b) !Генерация равномерной сетки !ОК
  85.         integer, intent(in) :: n
  86.         real(8),intent(in) :: a, b
  87.         real(8), dimension(:,:) :: grid(n,4)
  88.         real(8) :: AA
  89.         integer :: i
  90.         !Генерация сеток
  91.         grid = 0d0
  92.         do i = 1,n
  93.             grid(i,1) = (b-a)*real(i,8)/real(n-1,8) + a - (b-a)/real(n-1,8)
  94.             grid(i,2) = f(grid(i,1))
  95.         end do
  96.         grid(:,3) = grid(:,2)
  97.        
  98.         !Выбросы(промахи)
  99.         !AA = dabs(maxval(grid(:,2)) - minval(grid(:,2))) !Амплитуда
  100.         !grid(1,3) = grid(1,3)*2d0*AA
  101.         !grid(2,3) = grid(2,3)*3d0*AA
  102.         !grid(4,3) = grid(4,3)*4d0*AA
  103.     end subroutine
  104.    
  105.     subroutine MNK(grid,w,n,m,res) !метод наименьших квадратов с конкректным весами.
  106.         integer, intent(in) :: n, m !n - число узлов m - степень строящегося полинома
  107.         integer :: i,j,k
  108.         real(8), dimension(:,:) :: grid(n,4)
  109.         real(8), dimension(:) :: w(n), res(n) !ВЕСА и решение
  110.         real(8), allocatable :: A(:,:), b(:)
  111.         allocate(A(m,m),b(m))
  112.         !Составление матрицы СЛАУ с весами
  113.         b = 0d0
  114.         A = 0d0
  115.         do k = 1, m
  116.             do i = 1,n
  117.                 b(k) = b(k) + w(i)*grid(i,3)*e(grid(i,1),k)
  118.             end do
  119.             do j = 1,m
  120.                 do i = 1,n
  121.                     A(k,j) = A(k,j) + w(i)*e(grid(i,1),j)*e(grid(i,1),k)
  122.                 end do
  123.             end do
  124.         end do
  125.         !write(*,"(3f14.7)") (A(i,:),i=1,m)
  126.         call cholesky1(A,b,m,res) !Решение СЛАУ
  127.         deallocate(A, b)
  128.     end subroutine
  129.    
  130.     subroutine coefget(grid,res,m,n)
  131.         integer, intent(in) :: n, m !n - число узлов m - степень строящегося полинома
  132.         integer :: i,j,k
  133.         real(8), dimension(:,:) :: grid(n,4)
  134.         real(8), dimension(:) :: w(n), res(n) !ВЕСА и решение
  135.         real(8), allocatable :: epsi(:)
  136.         real(8) :: eps
  137.         allocate(epsi(n))
  138.         eps = 1e-14
  139.        
  140.         w = 1d0
  141.         do while(maxval(epsi) > eps)
  142.             res = 0d0
  143.             call MNK(grid,w,n,m,res)
  144.             do i = 1,n
  145.                 epsi(i) = dabs(grid(i,3) - pf(res,grid(i,3),n))
  146.                 w(i) = 1d0/(epsi(i)*2d0 + eps)
  147.             end do
  148.         end do
  149.         deallocate(epsi)
  150.     end subroutine
  151. end module
Add Comment
Please, Sign In to add comment