View difference between Paste ID: bLmP57mW and 4ZXMYJKJ
SHOW: | | - or go back to the newest paste.
1-
subroutine LU(n, m, A, P, Y)
1+
module global_vars
2-
    integer, intent(in) :: n, m
2+
    integer :: N = 100, l = 2
3-
    integer :: i, j, k, pivot, temp
3+
    real :: R = 10.0, V_0 = 2, a = 5.0, lk = 0.1, rk = 10.0, dk = 0.05, k
4-
    double precision :: pivotValue
4+
    save
5-
    integer, dimension(:), intent(inout) :: P
5+
end module
6-
    double precision, dimension(:), allocatable :: x
6+
   
7-
    double precision, dimension(:, :), intent(inout) :: A, Y
7+
function V(x)
8-
    allocate(x(n))
8+
    use global_vars
9-
    do i = 1, n
9+
    real :: V
10-
        !searching for max
10+
    real, intent(in) :: x
11-
        pivotValue = 0.0
11+
    if (x < a) then
12-
        pivot = -1
12+
        V = -V_0
13-
        do k = i, n
13+
    else
14-
            if (abs(A(k, i)) > pivotValue) then
14+
        V = 0.0
15-
                pivotValue = abs(A(k, i))
15+
16-
                pivot = k
16+
    return
17-
            end if
17+
end function
18-
        end do
18+
 
19-
        !is matrix invertible?
19+
recursive function jl(x, l) result(ans)
20-
        if (abs(pivotValue) < 1.0/10000) then
20+
    real, intent(in) :: x
21-
            print *, "matrix is invertiblle"
21+
    real :: ans
22-
        end if
22+
    integer, intent(in) :: l
23-
        !row swap
23+
    if (l == 0) then
24-
        !call dswap(1, P(i), 0, P(pivot), 0)
24+
        ans = sin(x) / x
25-
        temp = P(i)
25+
    else if (l == 1) then
26-
        P(i) = P(pivot)
26+
        ans = sin(x) / x**2 - cos(x) / x
27-
        P(pivot) = temp
27+
    else
28-
        call dswap(n, A(i,1:n), 1, A(pivot, 1:n), 1)
28+
        ans = (2 * (l - 1) + 1) * jl(x, l - 1) / x  - jl(x, l - 2)
29-
        do j = i + 1, n
29+
30-
            A(j, i) = A(j, i) / A(i, i)
30+
end function
31-
            do k = i + 1, n
31+
 
32-
                A(j, k) = A(j, k) - A(j, i) * A(i, k)    
32+
function jl_hat(x, l)
33-
            end do
33+
    real, intent(in) :: x
34-
        end do
34+
    integer, intent(in) :: l
35
    real :: jl, jl_hat
36-
    !A = L + U - I
36+
    jl_hat = jl(x, l) * x
37-
    !Gauss
37+
    return
38-
    do k = 1, m
38+
end function
39-
        !forward
39+
 
40-
        do i = 1, n
40+
recursive function nl(x, l) result(ans)
41-
            x(i) = Y(P(i), k)
41+
    real, intent(in) :: x
42-
            x(i) = x(i) - ddot(i-1, A(i,1:i-1), 1, x(1:i-1), 1)
42+
    real :: ans
43-
            !do j = 1, i - 1
43+
    integer, intent(in) :: l
44-
            !    x(i) = x(i) - A(i, j) * x(j)
44+
    if (l == 0) then
45-
            !end do
45+
        ans = -cos(x) / x
46-
        end do
46+
    else if (l == 1) then
47-
        !backward
47+
        ans = -cos(x) / x**2 - sin(x) / x
48-
        do i = n, 1, -1
48+
    else
49-
            if (i < n) then
49+
        ans = (2 * (l - 1) + 1) * nl(x, l - 1) / x  - nl(x, l - 2)
50-
                x(i) = x(i) - ddot(n-i, x(i+1:n), 1, A(i,i+1:n), 1)
50+
51-
            end if
51+
end function
52-
            !do j = i + 1, n
52+
 
53-
            !    x(i) = x(i) - A(i, j) * x(j)
53+
function nl_hat(x, l)
54-
            !end do
54+
    real, intent(in) :: x
55-
            x(i) = x(i) / A(i, i)
55+
    integer, intent(in) :: l
56-
        end do
56+
    real :: nl, nl_hat
57-
        !answer
57+
    nl_hat = nl(x, l) * x
58-
        do i = 1, n
58+
end function
59-
            Y(i, k) = x(i)
59+
 
60-
        end do
60+
function dfac(x)
61
    integer, intent(in) :: x
62-
    deallocate(x)
62+
    integer :: i, dfac
63
    dfac = mod(x, 2)
64-
64+
    i = dfac + 2
65-
program lu_decomposition
65+
    do while (i <= x)
66
        dfac = dfac * i
67-
    integer :: n, m, i, inp, outp
67+
        i = i + 2
68-
    integer, dimension(:), allocatable :: P, sP
68+
69-
    double precision, dimension(:,:), allocatable :: A, sA, tempY, Y, sY
69+
    return
70-
    interface
70+
end function
71-
        subroutine LU(n, m, A, P, Y)
71+
 
72-
            integer, intent(in) :: n, m
72+
function F(x, delta)
73-
            integer :: i, j, k, pivot, temp
73+
    use global_vars
74-
            double precision :: pivotValue
74+
    real :: nl, jl, jl_hat, nl_hat, F, V
75-
            integer, dimension(:), intent(inout) :: P
75+
    real, intent(in) :: x, delta
76-
            double precision, dimension(:), allocatable :: x
76+
    F = -V(x) * (cos(delta) * jl_hat(k * x, l) - sin(delta) * nl_hat(k * x, l))**2 / k
77-
            double precision, dimension(:, :), intent(inout) :: A, Y
77+
    return
78-
        end subroutine LU
78+
end function
79-
    end interface
79+
 
80-
    !input
80+
subroutine RungeKutta(h, N, Y)
81-
    inp = 42
81+
82-
    outp = 43
82+
    integer :: i, N
83-
    open(unit = inp, file = "input.txt")
83+
    real :: k, F, h, x, S(4), Y(N)
84-
    read(inp, *) n, m
84+
    do i = 1, N - 1
85-
    allocate(P(n))
85+
        x = h * i
86-
    do i = 1, n
86+
        S(1) =       F(x          , Y(i)                 )
87-
        P(i) = i
87+
        S(2) = 2.0 * F(x + h / 2.0, Y(i) + h * S(1) / 2.0)
88
        S(3) = 2.0 * F(x + h / 2.0, Y(i) + h * S(2) / 2.0)
89-
    allocate(sP(n))
89+
        S(4) =       F(x + h      , Y(i) + h * S(3)      )
90-
    sP = P
90+
        Y(i + 1) = Y(i) + h * sum(S) / 6.0
91-
    allocate(A(n, n))
91+
92-
    allocate(sA(n, n))
92+
93-
    allocate(Y(n, m))
93+
 
94-
    allocate(sY(n, m))
94+
program phase
95-
    allocate(tempY(m, n))
95+
    use global_vars
96-
    read (inp, *) A
96+
97-
    A = transpose(A)
97+
    integer :: i, out = 42, dfac
98-
    sA = A
98+
    real :: V, h
99-
    read (inp, *) tempY
99+
    real, allocatable :: DELTA(:)
100-
    Y = transpose(tempY)
100+
    allocate(DELTA(N))
101-
    sY = Y
101+
    h = R / N
102-
    close(inp)
102+
    k = lk
103-
    open(unit = outp, file = "output.txt")
103+
    open(unit = out, file = "output.txt")
104-
    !LU decomposition
104+
    write(out, *) "k               delta"
105-
    call LU(n, m, A, P, Y)
105+
    do while (k <= rk)
106-
    !LU output
106+
        DELTA(1) = -V(0.0) * (k * h)**(2 * l + 1) * h**2 / ((2 * l + 3) * dfac(2*l + 1)**2)
107-
    write(outp, *) "A"
107+
        call RungeKutta(h, N, DELTA)
108-
    do i = 1, n
108+
        write(out, *) k, DELTA(N)
109-
        write(outp, *) A(i, :)
109+
        k = k + dk
110
    end do
111-
    write(outp, *) "P"
111+
    close(out)
112-
    write(outp, *) P
112+