Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program prak
  2.  
  3. real :: c, d, h, sigma, eps=0.0001, lmdb, sm
  4. integer :: N, n0, m=2, i, k, j
  5. real, allocatable, dimension (:) :: X, Y, polinom, gradient, V, tmp
  6. logical :: flag
  7.  
  8.     write (*, '(A)', ADVANCE='NO') 'c:  '
  9.     read *, c
  10.     write (*, '(A)', ADVANCE='NO') 'd:  '
  11.     read *, d
  12.     write (*, '(A)', ADVANCE='NO') 'N:  '
  13.     read *, N
  14.     write (*, '(A)', ADVANCE='NO') 'no:  '
  15.     read *, n0
  16.     print *,
  17.  
  18.     h=(d-c)/N
  19.     allocate (X(N+1))
  20.  
  21.     do i=1, N+1
  22.         X(i)=c+(i-1)*h
  23.     end do
  24.  
  25.     allocate (Y(N+1))
  26.     write (*, '(A)') 'function:'
  27.     write (*, '(A)') 'test 1) y = 6*x^3-0.533*x^2+0.88*x+2.4'
  28.     write (*, '(A)') 'prod 2) y = (1+x)*exp(-2*x)'
  29.     read *, i
  30.     print *,
  31.  
  32.     select case (i)
  33.         case(1)
  34.             call func_test (X, Y, N+1)
  35.         case(2)
  36.             call func_1 (X, Y, N+1)
  37.     end select
  38.  
  39.     allocate (polinom(n0+m))
  40.     allocate (gradient(n0+m))
  41.     allocate (V(n0+m))
  42.     allocate (tmp(n0+m))
  43.  
  44.  
  45.  
  46.     do k=n0, n0+m-1
  47.         i=0
  48.         flag=.true.
  49.         sigma=1000
  50.     do j=1, k+1
  51.         polinom(j)=0
  52.         gradient(j)=0
  53.         V(j)=0
  54.         tmp(j)=0
  55.     end do
  56.  
  57.     write (*, '(A15, i2)') 'n: ', k
  58.  
  59.         do while (sigma>eps)
  60.             tmp=polinom
  61.             i=i+1
  62.  
  63.             call get_V()
  64.  
  65.             lmdb = lambda()
  66.             polinom=polinom+lmdb*V
  67.             if (flag.eqv..true.) then
  68.                 flag=.false.
  69.             else
  70.                 sigma=get_sigma()
  71.             end if
  72.  
  73.             sm=0
  74.             do l=1, N+1
  75.                 sm = sm + (Y(l)-P(X(l), polinom))**2
  76.             end do
  77.             sm = sqrt(sm/(N+1))
  78.  
  79.             write(*,'(I6, A12, F14.8, A12, F14.8)') i, ': |grad(F)|=', sqrt(dot_product(gradient,gradient)), 'dev: ', sm
  80.  
  81.         end do
  82.  
  83.         print *,
  84.  
  85.         write (*, '(A2, A15, A15, A15, A15)') 'it', 'X(i)   ', 'Y(i)    ','P(i)    ','d    '
  86.  
  87.         do i=1, N+1
  88.             write (*, '(I2, F14.8, F14.8, F14.8, F14.8)') i-1, X(i), Y(i), P(X(i), polinom), abs(Y(i)-P(X(i), polinom))
  89.         end do
  90.  
  91.         print *,
  92.         write (*, '(A)') 'a0..an'
  93.         do i=0, k
  94.             write (*, '(A1, I2, A1, F12.6)') 'a',i, ' =', polinom(i+1)
  95.         end do
  96.         print *,
  97.  
  98.    end do
  99.  
  100.    deallocate (X)
  101.    deallocate (Y)
  102.    deallocate (polinom)
  103.    deallocate (V)
  104.    deallocate (gradient)
  105.    deallocate (tmp)
  106.  
  107.    read *,
  108.  
  109. contains
  110.  
  111.     real function P (point, array)
  112.  
  113.         real :: point
  114.         integer :: i
  115.         real, dimension (:) :: array
  116.  
  117.         P=0
  118.  
  119.         do i=0, k
  120.             P= array(k+1-i)+P*point
  121.         end do
  122.  
  123.     end function P
  124.  
  125.     subroutine get_gradient ()
  126.         integer :: i, j
  127.  
  128.         do j=1, k+1
  129.             gradient(j)=0
  130.             do i=1, N+1
  131.                 gradient(j)=gradient(j)+2*(X(i)**(j-1))*(P(X(i), polinom)-Y(i))
  132.             end do
  133.         end do
  134.  
  135.     end subroutine get_gradient
  136.  
  137.     real function G (array)
  138.         real, dimension (:) :: array
  139.         integer :: i
  140.  
  141.         G=0
  142.  
  143.         do i=1, N+1
  144.             G=G+(Y(i)-P(X(i), array))**2
  145.         end do
  146.  
  147.     end function G
  148.  
  149.     subroutine get_V ()
  150.         real :: tmp
  151.  
  152.         if (flag.eqv..TRUE.) then
  153.                 call get_gradient ()
  154.                 V=(-1)*gradient
  155.             else
  156.                 tmp=dot_product(gradient, gradient)
  157.                 call get_gradient ()
  158.                 V=(-1)*gradient+(dot_product(gradient, gradient)/tmp)*V
  159.         end if
  160.  
  161.     end subroutine get_V
  162.  
  163.     real function lambda ()
  164.         real :: m1, m2, m3
  165.  
  166.         m1=G(polinom-V)
  167.         m2=G(polinom)
  168.         m3=G(polinom+V)
  169.  
  170.         lambda=(m1-m3)/(2*(m1-2*m2+m3))
  171.  
  172.     end function lambda
  173.  
  174.     real function get_sigma ()
  175.         integer :: i
  176.         real :: q
  177.  
  178.         tmp=tmp-polinom
  179.         get_sigma=0
  180.  
  181.         do i=1, k+1
  182.             if (polinom(i)/=0) then
  183.                 q=abs(tmp(i)/polinom(i))
  184.                 if (q>get_sigma) then
  185.                     get_sigma=q
  186.                 end if
  187.             end if
  188.         end do
  189.  
  190.     end function get_sigma
  191.  
  192. end program prak
  193.  
  194. subroutine func_1 (X, Y, N)
  195.  
  196.     integer :: N, i
  197.     real, dimension (N) :: X, Y
  198.  
  199.     do i=1, N
  200.         Y(i)=(1+X(i))*exp(-2*X(i))
  201.     end do
  202.  
  203. end subroutine func_1
  204.  
  205. subroutine func_test (X, Y, N)
  206.  
  207.     integer :: N, i
  208.     real, dimension (N) :: X, Y
  209.  
  210.     do i=1, N
  211.         Y(i)=6*X(i)**3-0.533*X(i)**2+0.88*X(i)+2.4
  212.     end do
  213.  
  214. end subroutine func_test
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement