module methods implicit none contains function f(x) result(y) !Функция исходная(с пограшностями) !ОК real(8), intent(in) :: x real(8) :: y !y = x**2d0 + 1d0 - (4d0*datan(1d0)/2d0 - x - (x**3d0)/6d0) y = x**2d0 + 1d0 - dacos(x) !y = x**2d0 end function function e(x,n) result(y) !Базисная функция !ОК integer, intent(in) :: n real(8), intent(in) :: x real(8) :: y y = x**real(n-1,8) !y = dcos(real(n-1,8)*dacos(x)) end function function pf(res,x,n) result(y) !Вычисление приближения в точке !ОК integer, intent(in) :: n real(8), intent(in) :: x integer :: i real(8), dimension(:) :: res(n) real(8) :: y y=0d0 do i = 1,n y = y + res(i)*e(x,i) end do end function subroutine cholesky1(A,b,n,res) !Разложение Холецкого real(8),dimension(:,:) :: A real(8),dimension(:) :: b, res real(8), allocatable :: y1(:) real(8) :: sum integer, intent(in) :: n integer :: i,j,P integer :: info allocate(y1(n)) !L = 0d0 !L = A !do i = 1, n !i столбец !do j = i, n !j строка !Вычисление суммы !sum = 0d0 !do p = 1, i-1 !sum = sum + A(i,p)*A(j,p) !end do !Разложение !if (j==i) then !A(i,i) = dsqrt(A(i,i) - sum) !else !A(j,i) = (A(j,i) - sum)/A(i,i) !end if !end do !end do call DPOTRF("L", n, A, n,info) write(*,*) "info", info do i = 1,n-1 A(i,i+1:) = 0d0 end do !Решаем Ly = b y1 = 0d0 do i = 1,n do j = 1, i-1 b(i) = b(i) - A(i,j)*y1(j) end do y1(i) = b(i)/A(i,i) end do !Решаем (L**T)x = y A = transpose(A) res = 0d0 do i = n,1,-1 do j = n, i+1,-1 y1(i) = y1(i) - A(i,j)*res(j) end do res(i) = y1(i)/A(i,i) end do !write(*,*) "RESULT", norm2(MATMUL(A,res) - b) deallocate(y1) end subroutine subroutine gengrid(grid,n,a,b) !Генерация равномерной сетки !ОК integer, intent(in) :: n real(8),intent(in) :: a, b real(8), dimension(:,:) :: grid(n,4) real(8) :: AA integer :: i !Генерация сеток grid = 0d0 do i = 1,n grid(i,1) = (b-a)*real(i,8)/real(n-1,8) + a - (b-a)/real(n-1,8) grid(i,2) = f(grid(i,1)) end do grid(:,3) = grid(:,2) !Выбросы(промахи) !AA = dabs(maxval(grid(:,2)) - minval(grid(:,2))) !Амплитуда !grid(1,3) = grid(1,3)*2d0*AA !grid(2,3) = grid(2,3)*3d0*AA !grid(4,3) = grid(4,3)*4d0*AA end subroutine subroutine MNK(grid,w,n,m,res) !метод наименьших квадратов с конкректным весами. integer, intent(in) :: n, m !n - число узлов m - степень строящегося полинома integer :: i,j,k real(8), dimension(:,:) :: grid(n,4) real(8), dimension(:) :: w(n), res(n) !ВЕСА и решение real(8), allocatable :: A(:,:), b(:) allocate(A(m,m),b(m)) !Составление матрицы СЛАУ с весами b = 0d0 A = 0d0 do k = 1, m do i = 1,n b(k) = b(k) + w(i)*grid(i,3)*e(grid(i,1),k) end do do j = 1,m do i = 1,n A(k,j) = A(k,j) + w(i)*e(grid(i,1),j)*e(grid(i,1),k) end do end do end do !write(*,"(3f14.7)") (A(i,:),i=1,m) call cholesky1(A,b,m,res) !Решение СЛАУ deallocate(A, b) end subroutine subroutine coefget(grid,res,m,n) integer, intent(in) :: n, m !n - число узлов m - степень строящегося полинома integer :: i,j,k real(8), dimension(:,:) :: grid(n,4) real(8), dimension(:) :: w(n), res(n) !ВЕСА и решение real(8), allocatable :: epsi(:) real(8) :: eps allocate(epsi(n)) eps = 1e-14 w = 1d0 do while(maxval(epsi) > eps) res = 0d0 call MNK(grid,w,n,m,res) do i = 1,n epsi(i) = dabs(grid(i,3) - pf(res,grid(i,3),n)) w(i) = 1d0/(epsi(i)*2d0 + eps) end do end do deallocate(epsi) end subroutine end module