├── .gitignore ├── README.md ├── curve-fitting └── curvfit.f90 ├── filter ├── gaussian_filter1d.f90 └── gaussian_filter1d.ipynb ├── interpolation └── interp.f90 ├── linear-algebraic-equations └── linear.f90 ├── nonlinear-equations └── nonlinear.f90 ├── numerial-differentiation └── diff.f90 ├── numerial-integration └── integration.f90 ├── ordinary-differential-equations ├── boundary-value-problems │ ├── finite-difference-method │ │ └── fdm.f90 │ └── shooting-method │ │ └── shoot.f90 └── initial-value-problems │ ├── 1d-heat-diffusion │ ├── diff.dat │ ├── diff.in │ └── heatdiff.f90 │ ├── multi-step │ └── multi_step.f90 │ └── single-step │ └── single_step.f90 └── roots-of-equations └── roots.f90 /.gitignore: -------------------------------------------------------------------------------- 1 | *.dat 2 | *.txt 3 | *.o 4 | *.obj 5 | *.mod 6 | .ipynb_checkpoints 7 | 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Numerical Methods 2 | 3 | - Sample programs of general numerical methods implemented in FORTRAN. 4 | - Each file contains a module and a main program. 5 | - Various methods and functions of the same kind are listed in a module. 6 | 7 | ## Contents 8 | 1. Linear Algebraic Equations 9 | 2. Nonlinear Equations 10 | 3. Interpolation 11 | 4. Curve Fitting 12 | 5. Roots of Equations 13 | 6. Numerical Differentiation 14 | 7. Numerical Integration 15 | 8. Ordinary Differential Equations 16 | 1. Initial Value Problems 17 | 2. Boundary Value Problems 18 | -------------------------------------------------------------------------------- /curve-fitting/curvfit.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) !double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module curvfit 8 | use kinds 9 | private 10 | public :: uptri, gramschmidt, leastsquares, lsqcurvefit 11 | contains 12 | !******************************************************************************* 13 | subroutine lsqcurvefit(x,y,n,c,m) 14 | ! Polynomial curve fitting with least squares 15 | ! x,y ---- input data 16 | ! n ---- dimension of x and y 17 | ! m ---- order of polynomials 18 | ! c ---- coefficients of polynomials 19 | ! f(x) = c1 + c2*x + c3*x^2 + c4*x^3 + .... 20 | implicit none 21 | integer, intent(in) :: m, n 22 | integer :: i 23 | real(dp), intent(in) :: x(n), y(n) 24 | real(dp), intent(out) :: c(m) 25 | real(dp) :: a(n,m) 26 | !-----error 27 | if(m>n) stop 'Warning: order of polynomial is greater than the number of data points' 28 | do i=1,n 29 | a(i,:)=bv(x(i),m) 30 | end do 31 | call leastsquares(a,y,c,n,m) 32 | contains 33 | !------------------------------------------------------------------------------- 34 | function bv(x,m) 35 | ! base function 36 | implicit none 37 | integer, intent(in) :: m 38 | real(dp), intent(in) :: x 39 | integer :: i 40 | real(dp) :: bv(m) 41 | bv(1)=1.0_dp 42 | do i=2,m 43 | bv(i)=bv(i-1)*x 44 | end do 45 | end function bv 46 | !------------------------------------------------------------------------------- 47 | end subroutine lsqcurvefit 48 | !******************************************************************************* 49 | subroutine leastsquares(a,b,x,m,n) 50 | ! Least squares solution for Ax=b where A(m,n) 51 | ! Ax=b, QRx=b, Rx=QTb 52 | ! Back substitution 53 | implicit none 54 | integer, intent(in) :: m, n 55 | real(dp), dimension(m,n), intent(in) :: a 56 | real(dp), dimension(m), intent(in) :: b 57 | real(dp), dimension(n), intent(out) :: x 58 | real(dp), dimension(m,n) :: q 59 | real(dp), dimension(n,m) :: qt 60 | real(dp), dimension(n,n) :: r 61 | real(dp), dimension(n) :: qtb 62 | call gramschmidt(a,q,r,m,n) 63 | qt=transpose(q) 64 | !-----Rx=Q'b 65 | qtb=matmul(qt,b) 66 | !-----back substitution 67 | call uptri(r,qtb,x,n) 68 | end subroutine leastsquares 69 | !******************************************************************************* 70 | subroutine gramschmidt(a,q,r,m,n) 71 | ! Corrected Gram-Schmidt method for QR decomposition 72 | ! A=QR is a rectangular matrix A(m,n) 73 | ! Q: orthogonal matrix, R: upper triagular matrix 74 | ! Q(m,n), R(n,n) 75 | implicit none 76 | integer, intent(in) :: m, n 77 | integer :: i, j, k 78 | real(dp), dimension(m,n), intent(in) :: a 79 | real(dp), dimension(m,n), intent(out) :: q 80 | real(dp), dimension(n,n), intent(out) :: r 81 | real(dp), dimension(m) :: temp 82 | r(1,1)=sqrt(dot_product(a(:,1),a(:,1))) 83 | q(:,1)=a(:,1)/r(1,1) 84 | do k=2,n 85 | do j=1,k-1 86 | r(j,k)=dot_product(q(:,j),a(:,k)) 87 | end do 88 | temp=a(:,k) 89 | do j=1,k-1 90 | temp=temp-q(:,j)*r(j,k) 91 | end do 92 | r(k,k)=sqrt(dot_product(temp,temp)) 93 | q(:,k)=temp/r(k,k) 94 | end do 95 | end subroutine gramschmidt 96 | !******************************************************************************* 97 | subroutine uptri(a,b,x,n) 98 | implicit none 99 | integer :: i,k 100 | integer, intent(in) :: n 101 | real(dp), dimension(1:n,1:n), intent(in) :: a 102 | real(dp), dimension(1:n), intent(in) :: b 103 | real(dp), dimension(1:n), intent(out) :: x 104 | real(dp) :: s 105 | x(n)=b(n)/a(n,n) 106 | do i=n-1,1,-1 107 | s=0.0_dp 108 | do k=i+1,n 109 | s=s+a(i,k)*x(k) 110 | end do 111 | x(i)=(b(i)-s)/a(i,i) 112 | end do 113 | end subroutine uptri 114 | !******************************************************************************* 115 | end module curvfit 116 | !******************************************************************************* 117 | program main 118 | use kinds 119 | use curvfit 120 | implicit none 121 | integer, parameter :: n=7 122 | real(dp), dimension(n) :: x, y 123 | real(dp) :: c1(3), c2(4), c3(9) 124 | x(:)=([-3.0_dp, -2.0_dp, -1.0_dp, 0.0_dp, 1.0_dp, 2.0_dp, 3.0_dp]) 125 | y(:)=([4.0_dp, 2.0_dp, 3.0_dp, -0.0_dp, -1.0_dp, -2.0_dp, -5.0_dp]) 126 | call lsqcurvefit(x,y,n,c1,3) 127 | call lsqcurvefit(x,y,n,c2,4) 128 | write(*,101) c1, c2 129 | 101 format(/T4,'Polynomial curve fitting',//, & 130 | T3,'2nd order polynomial with coefficients: ', 3(/,F16.11),//, & 131 | T3,'3rd order polynomial with coefficients: ', 4(/,F16.11),/) 132 | write(*,*) 133 | call lsqcurvefit(x,y,n,c2,9) 134 | end program main 135 | !******************************************************************************* 136 | -------------------------------------------------------------------------------- /filter/gaussian_filter1d.f90: -------------------------------------------------------------------------------- 1 | module filter1d 2 | 3 | implicit none 4 | 5 | contains 6 | 7 | subroutine gaussian_filter_1d0(x_in, y_in, x, ynew, delta) 8 | ! Filtering 1-D progress variable from laminar flame calculation 9 | ! using a 1-D Gaussian filter. 10 | ! Spatial profile of 1-D progress variable needs to be 11 | ! provided in a file for the corresponding fuel type. 12 | ! File name should be formated like 'progvar1d_C3H8_phi_1_0.txt'. 13 | 14 | ! Ruipengyu Li 20/03/2017 15 | ! Adapted from Bo 16 | integer, parameter :: dp = selected_real_kind(15) 17 | integer :: nl 18 | integer :: i, j 19 | integer :: iex 20 | integer :: ierr 21 | real(dp), intent(in) :: delta 22 | real(dp), dimension(:), intent(in) :: x_in, y_in 23 | real(dp), dimension(:), intent(out) :: x, ynew 24 | real(dp), allocatable, dimension(:) :: dx, y, x_ex 25 | real(dp) :: pi, gw1, gw2, dx_min, dx_max, gauss, gauss_ex 26 | 27 | nl = size(x_in) 28 | allocate(dx(nl-1), y(nl-1), stat=ierr) 29 | x = 0.0_dp 30 | dx = 0.0_dp 31 | y = 0.0_dp 32 | ynew = 0.0_dp 33 | do i=1,nl-1 34 | x(i) = 0.5_dp * (x_in(i) + x_in(i+1)) 35 | y(i) = 0.5_dp * (y_in(i) + y_in(i+1)) 36 | dx(i) = x_in(i+1) - x_in(i) 37 | end do 38 | x(nl) = x_in(nl) 39 | dx_min = minval(dx) 40 | dx_max = maxval(dx) 41 | iex = int((delta+0.01*dx_min) / dx_min) 42 | allocate(x_ex(-iex:nl+iex), stat=ierr) 43 | pi = 4.0_dp*atan(1.0_dp) 44 | do i=1,nl-1 45 | x_ex(i) = x(i) 46 | end do 47 | do i=0,-iex,-1 48 | x_ex(i) = x_ex(i+1) - dx(1) 49 | end do 50 | do i=nl,nl+iex 51 | x_ex(i) = x_ex(i-1) + dx(nl-1) 52 | end do 53 | do i=1,nl-1 54 | gauss = 0.0_dp 55 | gauss_ex = 0.0_dp 56 | do j=i-iex,i+iex-1 57 | if(j>=1 .and. j<(nl-1)) then 58 | gw1 = sqrt(6.0/pi/delta**2) * exp(-6.0*(x(j)-x(i))**2/delta**2) 59 | gw2 = sqrt(6.0/pi/delta**2) * exp(-6.0*(x(j+1)-x(i))**2/delta**2) 60 | ynew(i) = ynew(i) + 0.5*(gw1*y(j)+gw2*y(j+1)) * (x(j+1)-x(j)) 61 | gauss = gauss + 0.5*(gw1+gw2) * (x(j+1)-x(j)) 62 | else 63 | gw1 = sqrt(6.0/pi/delta**2) * exp(-6.0*(x_ex(j)-x_ex(i))**2/delta**2) 64 | gw2 = sqrt(6.0/pi/delta**2) * exp(-6.0*(x_ex(j+1)-x_ex(i))**2/delta**2) 65 | gauss_ex = gauss_ex + 0.5*(gw1+gw2) * (x_ex(j+1)-x_ex(j)) 66 | end if 67 | end do 68 | ynew(i) = ynew(i) * (gauss+gauss_ex)/gauss 69 | ynew(nl) = ynew(nl-1) 70 | end do 71 | deallocate(dx, y, x_ex, stat=ierr) 72 | end subroutine gaussian_filter_1d0 73 | 74 | end module filter1d 75 | 76 | program main 77 | 78 | use filter1d 79 | 80 | implicit none 81 | 82 | integer, parameter :: dp = selected_real_kind(15) 83 | integer :: i, n 84 | integer :: ierr 85 | real(dp), allocatable, dimension(:) :: x, y 86 | real(dp), allocatable, dimension(:) :: xnew, ynew 87 | real(dp) :: dx, delta 88 | n = 100 89 | allocate(x(n), y(n), stat=ierr) 90 | allocate(xnew(n), ynew(n), stat=ierr) 91 | x = 0.0_dp 92 | dx = 1.0_dp/n 93 | do i=2,n 94 | x(i) = x(1) + (i-1)*dx 95 | end do 96 | y = 0.0_dp 97 | where(x > 0.5_dp) y = 1.0_dp 98 | delta = 1.0e-1_dp 99 | call gaussian_filter_1d0(x, y, xnew, ynew, delta) 100 | write(*,'(2f12.5)') (xnew(i), ynew(i), i=1,n) 101 | end program main 102 | -------------------------------------------------------------------------------- /filter/gaussian_filter1d.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# One-Dimensional Gaussian Filter" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "In this notebook, a step function is filtered using a Gaussian filter." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "1-D Gaussian filter function:\n", 22 | "$$\n", 23 | "F(x) = \\left(\\frac{6}{\\pi \\Delta^2}\\right) ^ {1/2} exp\\left({-\\frac{6x^2}{\\Delta^2}}\\right)\n", 24 | "$$\n", 25 | "Filtered data $\\bar{y}$ can be obtained from original $y$:\n", 26 | "$$\n", 27 | "\\bar{y}(x) = \\int^{+\\infty}_{-\\infty} y(x') F(x-x') dx'\n", 28 | "$$" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 1, 34 | "metadata": { 35 | "collapsed": true 36 | }, 37 | "outputs": [], 38 | "source": [ 39 | "import numpy as np\n", 40 | "import matplotlib.pyplot as plt\n", 41 | "import math" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": { 48 | "collapsed": true 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "# Raw data\n", 53 | "x = np.linspace(-1., 1., 101)\n", 54 | "y = np.ones_like(x)\n", 55 | "y[np.where(x >= 0.0)] = 2.0" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "image/png": "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\nS7q/xXLaslbrktZubdS1OtS1OiXWdU5EbFlppZkLhRS25yNirus6TrRW65LWbm3UtTrUtTonc10c\nPgIADBAKAICBky0U9nRdwDLWal3S2q2NulaHulbnpK3rpBpTAACMdrL1FAAAIxQXCrZfbvsO27Xt\nZUfpbe+0/TXbR2y/Y+j+021/zvbdzb+tfIPKOI9r+8m2bx36+aHttzbL3mX73qFlu6ZVV7PePbYP\nNs89v9rtc9Rl+2zbX7R9Z/Oav2VoWav7a7n2MrTctj/YLL/d9vnjbpu5rlc19Ry0faPt84aWLfma\nTqmuHbYfGnp93jnutpnrettQTYdsV7ZPb5bl3F97bR+zfWiZ5dNrXxFR1I+kX5P0ZElfkjS3zDrr\nJX1d0q9IeoSk2yT9erPsvZLe0dx+h6T3tFTXqh63qfF76s8tlqR3SfqTDPtrrLok3SNpc+r/q826\nJG2VdH5z+1RJdw29jq3tr1HtZWidXZI+K8mSLpT0lXG3zVzXsyRtam5ftFjXqNd0SnXtkHT9JNvm\nrOuE9V8i6Qu591fz2M+RdL6kQ8ssn1r7Kq6nEBGHI+JrK6z2DElHIuIbEfEzSZ+QdHGz7GJJH21u\nf1TS77VU2mof9wWSvh4Rk56oN67U/29n+ysi7ouIW5rbP5J0WP3v+W7bqPYyXO/Hou8mSafZ3jrm\nttnqiogbI+IHza83qf8Nh7ml/J873V8nuETS/paee6SIOCDpwRGrTK19FRcKYzpT0neGfj+q439M\nzojj3wD3PUlntPScq33cV+jhDfLNTddxb1uHaVZRV0j6vO2b3f/O7NVun6suSZLt7ZKeJukrQ3e3\ntb9GtZeV1hln25x1DXud+p82Fy33mk6rrmc1r89nbT9lldvmrEu2HyVpp6RPDt2da3+NY2rtq8vv\naJ6Y7c9LetwSi/4iIj7d1vNERNgee3rWqLpW87i2HyHppZL+bOjuqyRdoX7DvELS+yX90RTrenZE\n3Gv7lyV9zvZ/N59uxt0+V12yfYr6b963RsQPm7sn3l8lsv089UPh2UN3r/iaZnSLpG0R8T/NeM+n\nJJ07pecex0sk/VdEDH9673J/Tc1MhkJE/E7iQ9wr6eyh389q7pOk79veGhH3Nd2zY23UZXs1j3uR\npFsi4vtDjz24bfvvJV0/zboi4t7m32O2/0X9busBdby/bG9UPxA+HhHXDj32xPtrCaPay0rrbBxj\n25x1yfZTJV0j6aKIeGDx/hGvafa6hsJbEXGD7Sttbx5n25x1DXlYTz3j/hrH1NrXyXr46KuSzrX9\nhOZT+SskXdcsu07Sa5rbr5HUVs9jNY/7sGOZzR/GRS+TtOQshRx12X607VMXb0t64dDzd7a/bFvS\nRyQdjogPnLCszf01qr0M13tpM0vkQkkPNYe/xtk2W122t0m6VtKrI+KuoftHvabTqOtxzesn289Q\n/2/RA+Nsm7Oupp7HSHquhtpc5v01jum1rxwj6V3+qP8H4Kikn0r6vqR/a+5/vKQbhtbbpf5sla+r\nf9hp8f7HSvoPSXdL+ryk01uqa8nHXaKuR6v/5njMCdv/g6SDkm5vXvSt06pL/ZkNtzU/d6yV/aX+\noZBo9smtzc+uHPtrqfYi6Q2S3tDctqQPN8sPamjm23JtraX9tFJd10j6wdD+mV/pNZ1SXW9qnvc2\n9QfAn7UW9lfz+2slfeKE7XLvr/2S7pP0c/X/fr2uq/bFGc0AgIGT9fARAGAJhAIAYIBQAAAMEAoA\ngAFCAQAwQCgAAAYIBQDAAKEAJLL99ObCbo9szny9w/ZvdF0XMAlOXgNaYPvdkh4p6RclHY2Iv+24\nJGAihALQgua6M1+V9L/qX7Kh6rgkYCIcPgLa8VhJp6j/DXCP7LgWYGL0FIAW2L5O/W+9eoL6F997\nU8clAROZye9TANYS25dK+nlE/KPt9ZJutP38iPhC17UBq0VPAQAwwJgCAGCAUAAADBAKAIABQgEA\nMEAoAAAGCAUAwAChAAAYIBQAAAP/B9vzghI7zUjUAAAAAElFTkSuQmCC\n", 66 | "text/plain": [ 67 | "" 68 | ] 69 | }, 70 | "metadata": {}, 71 | "output_type": "display_data" 72 | } 73 | ], 74 | "source": [ 75 | "plt.plot(x, y)\n", 76 | "plt.xlabel('x')\n", 77 | "plt.ylabel('y')\n", 78 | "plt.show()" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": { 85 | "collapsed": true 86 | }, 87 | "outputs": [], 88 | "source": [ 89 | "# Gaussian weights\n", 90 | "def gauss_weight(x, a, delta):\n", 91 | " gw = math.sqrt(6./math.pi/delta**2) * \\\n", 92 | " math.exp(-6.*(x-a)**2/delta**2)\n", 93 | " return gw" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 5, 99 | "metadata": { 100 | "collapsed": true 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "gw = np.zeros_like(x)\n", 105 | "x0 = 0.0\n", 106 | "delta = 0.5\n", 107 | "for i in range(len(x)):\n", 108 | " gw[i] = gauss_weight(x[i], x0, delta)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 6, 114 | "metadata": {}, 115 | "outputs": [ 116 | { 117 | "data": { 118 | "image/png": "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\n", 119 | "text/plain": [ 120 | "" 121 | ] 122 | }, 123 | "metadata": {}, 124 | "output_type": "display_data" 125 | } 126 | ], 127 | "source": [ 128 | "plt.plot(x, gw)\n", 129 | "plt.xlabel('x')\n", 130 | "plt.ylabel('Gaussian Func')\n", 131 | "plt.show()" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "We can see that $\\Delta$ is half of the curve width" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "**The integral of the entire gauss function is unity.**" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 7, 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "name": "stdout", 155 | "output_type": "stream", 156 | "text": [ 157 | "Integral of gaussian function: 0.999999999995\n" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "s = 0.\n", 163 | "for i in range(len(x)-1):\n", 164 | " s = s + gw[i] * (x[i+1] - x[i])\n", 165 | "print('Integral of gaussian function:', s)" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "However, it is not the case if the centre of the curve is shifted." 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 8, 178 | "metadata": {}, 179 | "outputs": [ 180 | { 181 | "name": "stdout", 182 | "output_type": "stream", 183 | "text": [ 184 | "Integral of gaussian function: 0.906149917292\n" 185 | ] 186 | } 187 | ], 188 | "source": [ 189 | "x0 = 0.8\n", 190 | "for i in range(len(x)):\n", 191 | " gw[i] = gauss_weight(x[i], x0, delta)\n", 192 | "s = 0.\n", 193 | "for i in range(len(x)-1):\n", 194 | " s = s + gw[i] * (x[i+1] - x[i])\n", 195 | "print('Integral of gaussian function:', s)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 9, 201 | "metadata": {}, 202 | "outputs": [ 203 | { 204 | "data": { 205 | "image/png": "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\ngg==\n", 206 | "text/plain": [ 207 | "" 208 | ] 209 | }, 210 | "metadata": {}, 211 | "output_type": "display_data" 212 | } 213 | ], 214 | "source": [ 215 | "plt.plot(x, gw)\n", 216 | "plt.xlabel('x')\n", 217 | "plt.ylabel('Gaussian Func')\n", 218 | "plt.show()" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 10, 224 | "metadata": { 225 | "collapsed": true 226 | }, 227 | "outputs": [], 228 | "source": [ 229 | "# Integrate using trapezoidal rule\n", 230 | "def gaussian_filter(x, y, delta):\n", 231 | " yf = np.zeros_like(y)\n", 232 | " for i in range(len(x)):\n", 233 | " gw = 0.\n", 234 | " for j in range(len(x)-1):\n", 235 | " gw1 = gauss_weight(x[j], x[i], delta)\n", 236 | " gw2 = gauss_weight(x[j+1], x[i], delta)\n", 237 | " yf[i] = yf[i] + 0.5*(gw1*y[j] + gw2*y[j+1]) * (x[j+1] - x[j])\n", 238 | " gw = gw + 0.5 * (gw1 + gw2) * (x[j+1] - x[j])\n", 239 | " return yf" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 11, 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "data": { 249 | "image/png": "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\n", 250 | "text/plain": [ 251 | "" 252 | ] 253 | }, 254 | "metadata": {}, 255 | "output_type": "display_data" 256 | } 257 | ], 258 | "source": [ 259 | "delta = 0.5\n", 260 | "yf = np.zeros_like(y)\n", 261 | "yf = gaussian_filter(x, y, delta)\n", 262 | "plt.plot(x, y, 'b--', label='Original')\n", 263 | "plt.plot(x, yf, 'r-', label='Filtered')\n", 264 | "plt.xlabel('x')\n", 265 | "plt.ylabel('y or yf')\n", 266 | "plt.legend(loc='best')\n", 267 | "plt.show()" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "What happened? The filtered curve seems okay in the middle but is off when it is close to the two ends.\n", 275 | "\n", 276 | "**Recall that the gaussian function is not complete (integral is not unity) when approaching the boundaries.**\n", 277 | "\n", 278 | "One solution is to take into account the weights close to boundary.\n", 279 | "\n", 280 | "Another solution is to extend the domain in both directions by at least $\\Delta$" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 12, 286 | "metadata": { 287 | "collapsed": true 288 | }, 289 | "outputs": [], 290 | "source": [ 291 | "# Integrate\n", 292 | "def gaussian_filter2(x, y, delta):\n", 293 | " yf = np.zeros_like(y)\n", 294 | " for i in range(len(x)):\n", 295 | " gw = 0.\n", 296 | " for j in range(len(x)-1):\n", 297 | " gw1 = gauss_weight(x[j], x[i], delta)\n", 298 | " gw2 = gauss_weight(x[j+1], x[i], delta)\n", 299 | " yf[i] = yf[i] + 0.5*(gw1*y[j] + gw2*y[j+1]) * (x[j+1] - x[j])\n", 300 | " gw = gw + 0.5 * (gw1 + gw2) * (x[j+1] - x[j])\n", 301 | " yf[i] = yf[i] / gw\n", 302 | " return yf" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": 13, 308 | "metadata": {}, 309 | "outputs": [ 310 | { 311 | "data": { 312 | "image/png": "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\ngg==\n", 313 | "text/plain": [ 314 | "" 315 | ] 316 | }, 317 | "metadata": {}, 318 | "output_type": "display_data" 319 | } 320 | ], 321 | "source": [ 322 | "delta = 0.5\n", 323 | "yf = np.zeros_like(y)\n", 324 | "yf = gaussian_filter2(x, y, delta)\n", 325 | "plt.plot(x, y, 'b--', label='Original')\n", 326 | "plt.plot(x, yf, 'r-', label='Filtered')\n", 327 | "plt.xlabel('x')\n", 328 | "plt.ylabel('y or yf')\n", 329 | "plt.legend(loc='best')\n", 330 | "plt.show()" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "This is what we want.\n", 338 | "\n", 339 | "Note that the actual filter operation changed to:\n", 340 | "$$\n", 341 | "\\bar{y}(x) = \n", 342 | "\\frac{\\int^{+\\infty}_{-\\infty} y(x') F(x-x') dx'}\n", 343 | "{\\int^{+\\infty}_{-\\infty} F(x-x') dx'}\n", 344 | "$$\n", 345 | "where the demomenator is unity unless the point of evaluation is close to the boundary. It is added in order to adjust the weights when the integral of gaussian function is not unity close to boundaries." 346 | ] 347 | } 348 | ], 349 | "metadata": { 350 | "kernelspec": { 351 | "display_name": "Python 3", 352 | "language": "python", 353 | "name": "python3" 354 | }, 355 | "language_info": { 356 | "codemirror_mode": { 357 | "name": "ipython", 358 | "version": 3 359 | }, 360 | "file_extension": ".py", 361 | "mimetype": "text/x-python", 362 | "name": "python", 363 | "nbconvert_exporter": "python", 364 | "pygments_lexer": "ipython3", 365 | "version": "3.6.1" 366 | } 367 | }, 368 | "nbformat": 4, 369 | "nbformat_minor": 2 370 | } 371 | -------------------------------------------------------------------------------- /interpolation/interp.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) !double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module interpolation 8 | use kinds 9 | implicit none 10 | private 11 | public :: lagrange, newton 12 | contains 13 | !******************************************************************************* 14 | subroutine lagrange(n,xdata,ydata,m,x,p) 15 | ! Lagrange's interpolation method 16 | ! xdata,ydata ----- data points (x0,y0), (x1,y1),...,(xn,yn) 17 | ! n ----- number of data points minus 1 18 | ! m ----- number of interpolated points 19 | ! x ----- interpolating points 20 | ! p ----- interpolation result 21 | implicit none 22 | integer :: i 23 | integer, intent(in) :: n, m 24 | real(dp), intent(in) :: xdata(0:n), ydata(0:n), x(0:m) 25 | real(dp), dimension(n), intent(out) :: p(0:m) 26 | do i=0,m 27 | call lagrange_interp(n,xdata,ydata,x(i),p(i)) 28 | end do 29 | contains 30 | !****************************************************** 31 | subroutine lagrange_interp(n,xdata,ydata,x,p) 32 | ! interpolation of a single point 33 | implicit none 34 | integer :: i, j 35 | integer, intent(in) :: n 36 | real(dp), intent(in) :: xdata(0:n), ydata(0:n) 37 | real(dp), intent(in) :: x 38 | real(dp), intent(out) :: p 39 | real(dp) :: l(0:n) 40 | !-----weighting function 41 | l(:)=1.0_dp 42 | do i=0,n 43 | do j=0,n 44 | if(j==i) cycle 45 | !-----product term 46 | l(i)=l(i)*(x-xdata(j))/(xdata(i)-xdata(j)) 47 | end do 48 | end do 49 | !-----sum up for polynomial 50 | p=0.0_dp 51 | do i=0,n 52 | p=p+ydata(i)*l(i) 53 | end do 54 | end subroutine lagrange_interp 55 | !****************************************************** 56 | end subroutine lagrange 57 | 58 | 59 | !******************************************************************************* 60 | subroutine newton(n,xdata,ydata,m,x,p) 61 | implicit none 62 | integer :: i, j, k 63 | integer, intent(in) :: n, m 64 | real(dp), intent(in) :: xdata(0:n), ydata(0:n), x(0:m) 65 | real(dp), dimension(n), intent(out) :: p(0:m) 66 | do i=0,m 67 | call newton_interp(n,xdata,ydata,x(i),p(i)) 68 | end do 69 | contains 70 | !****************************************************** 71 | subroutine newton_interp(n,xdata,ydata,x,y) 72 | implicit none 73 | integer :: i, j, k 74 | integer, intent(in) :: n 75 | real(dp), intent(in) :: xdata(0:n), ydata(0:n) 76 | real(dp), intent(in) :: x 77 | real(dp), intent(out) :: y 78 | real(dp) :: q(0:n,0:n), b(n+1) 79 | do i=0,n 80 | q(i,0)=ydata(i) 81 | end do 82 | do i=1,n 83 | do j=1,i 84 | q(i,j)=(q(i,j-1)-q(i-1,j-1))/(xdata(i)-xdata(i-j)) 85 | end do 86 | end do 87 | b(n+1)=q(n,n) 88 | do k=n,1,-1 89 | b(k)=q(k-1,k-1)+b(k+1)*(x-xdata(k-1)) 90 | end do 91 | y=b(1) 92 | end subroutine newton_interp 93 | !****************************************************** 94 | end subroutine newton 95 | !******************************************************************************* 96 | end module interpolation 97 | 98 | 99 | !******************************************************************************* 100 | program main 101 | use kinds 102 | use interpolation 103 | implicit none 104 | real(dp), parameter :: pi = 3.141592653589793_dp 105 | real(dp) :: adata(0:3), xdata(0:3), ydata(0:3) 106 | real(dp) :: xdeg(0:2), x(0:2), y(0:2), yreal(0:2) 107 | !-----data points from degree to radi 108 | adata = ([30._dp, 45._dp, 60._dp, 90._dp]) 109 | xdata = adata*pi/180._dp 110 | ydata = ([sqrt(3._dp)/2, sqrt(2._dp)/2, 1._dp/2, 0._dp]) 111 | !-----points to be interpolated 112 | xdeg = ([47._dp, 53._dp, 79._dp]) 113 | x = xdeg*pi/180._dp 114 | write(*,*) ' Computed cos(x) with various interpolation methods' 115 | write(*,101) xdeg 116 | call lagrange(3,xdata,ydata,2,x,y) 117 | write(*,102) y 118 | call newton(3,xdata,ydata,2,x,y) 119 | write(*,103) y 120 | yreal=cos(x) 121 | write(*,104) yreal 122 | 101 format(/,T3,'Angle(deg):',T16,3F12.5) 123 | 102 format(T3,'Langrange:',T16,3F12.7) 124 | 103 format(T3,'Newton:',T16,3F12.7) 125 | 104 format(T3,'Real:',T16,3F12.7) 126 | end program main 127 | !******************************************************************************* 128 | -------------------------------------------------------------------------------- /linear-algebraic-equations/linear.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) !double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module linsolv 8 | use kinds 9 | implicit none 10 | private 11 | public :: uptri, downtri, gauss, doolittle, lusolv, crout, det, cholesky, & 12 | mat_eq, mat_inv, gauss_iter, thomas, jacobi, gs, richardson, & 13 | conjgrad, tdma 14 | contains 15 | !******************************************************************************* 16 | subroutine mat_inv(a,inv_a,n) 17 | ! calculate the inverse of matrix A 18 | ! use AX=I 19 | implicit none 20 | integer :: i 21 | integer, intent(in) :: n 22 | real(dp), dimension(1:n,1:n), intent(in) :: a 23 | real(dp), dimension(1:n,1:n), intent(out) :: inv_a 24 | real(dp), dimension(1:n,1:n) :: e 25 | do i=1,n 26 | e(i,i)=1.0_dp 27 | end do 28 | call mat_eq(a,e,inv_a,n,n) 29 | end subroutine mat_inv 30 | !******************************************************************************* 31 | subroutine gauss_iter(a,b,x,n) 32 | ! an simple iterative approach to correct the solution 33 | implicit none 34 | integer :: i 35 | integer, parameter :: itmax=5 36 | integer, intent(in) :: n 37 | real(dp), dimension(1:n,1:n), intent(in) :: a 38 | real(dp), dimension(1:n), intent(in) :: b 39 | real(dp), dimension(1:n), intent(out) :: x 40 | real(dp), dimension(1:n) :: x1, x2, db, dx 41 | ! initial value 42 | call gauss(a,b,x1,n) 43 | !x1=1.0_dp ! test a bad x1 value 44 | do i=1,itmax 45 | db=matmul(a,x1)-b 46 | ! correction dx 47 | call gauss(a,db,dx,n) 48 | ! corrected solution x2 49 | x2=x1-dx 50 | ! update 51 | x1=x2 52 | end do 53 | x=x1 54 | end subroutine gauss_iter 55 | !******************************************************************************* 56 | subroutine gauss(a,b,x,n) 57 | ! Gauss elimination 58 | implicit none 59 | integer :: i,k,idmax 60 | integer, intent(in) :: n 61 | real(dp), dimension(1:n,1:n), intent(in) :: a 62 | real(dp), dimension(1:n), intent(in) :: b 63 | real(dp), dimension(1:n), intent(out) :: x 64 | real(dp), dimension(1:n,1:n+1) :: ab 65 | real(dp), dimension(1:n,1:n) :: aup 66 | real(dp), dimension(1:n) :: bup 67 | real(dp), dimension(1:n+1) :: temp1, temp2 68 | real(dp) :: lam, elmax 69 | ab(1:n,1:n)=a 70 | ab(:,n+1)=b 71 | do k=1,n-1 72 | elmax=abs(ab(k,k)) 73 | idmax=k 74 | ! maximum element in the column 75 | do i=k+1,n 76 | if(abs(ab(i,k))>elmax) then 77 | elmax=ab(i,k) 78 | idmax=i 79 | end if 80 | end do 81 | ! swap two lines 82 | temp1=ab(k,:) 83 | temp2=ab(idmax,:) 84 | ab(k,:)=temp2 85 | ab(idmax,:)=temp1 86 | do i=k+1,n 87 | lam=ab(i,k)/ab(k,k) 88 | ab(i,:)=ab(i,:)-lam*ab(k,:) 89 | end do 90 | end do 91 | aup(:,:)=ab(1:n,1:n) 92 | bup(:)=ab(:,n+1) 93 | call uptri(aup,bup,x,n) 94 | end subroutine gauss 95 | !******************************************************************************* 96 | subroutine mat_eq(a,b,x,n,m) 97 | ! Gauss elimination for multiple sets of equations 98 | implicit none 99 | integer :: i, k, idmax 100 | integer, intent(in) :: n, m 101 | real(dp), dimension(1:n,1:n), intent(in) :: a 102 | real(dp), dimension(1:n,1:m), intent(in) :: b 103 | real(dp), dimension(1:n,1:m), intent(out) :: x 104 | real(dp), dimension(1:n,1:n+m) :: ab 105 | real(dp), dimension(1:n,1:n) :: aup 106 | real(dp), dimension(1:n+m) :: temp1, temp2 107 | real(dp), dimension(1:n) :: temp3, temp4 108 | real(dp) :: lam, elmax 109 | ab(1:n,1:n)=a 110 | ab(:,n+1:n+m)=b 111 | do k=1,n-1 112 | elmax=abs(ab(k,k)) 113 | idmax=k 114 | ! maximum element in a column 115 | do i=k+1,n 116 | if(abs(ab(i,k))>elmax) then 117 | elmax=ab(i,k) 118 | idmax=i 119 | end if 120 | end do 121 | ! swap two lines 122 | temp1=ab(k,:) 123 | temp2=ab(idmax,:) 124 | ab(k,:)=temp2 125 | ab(idmax,:)=temp1 126 | do i=k+1,n 127 | lam=ab(i,k)/ab(k,k) 128 | ab(i,:)=ab(i,:)-lam*ab(k,:) 129 | end do 130 | end do 131 | aup(:,:)=ab(1:n,1:n) 132 | do i=1,m 133 | temp3=ab(:,n+i) 134 | call uptri(aup,temp3,temp4,n) 135 | x(:,i)=temp4 136 | end do 137 | end subroutine mat_eq 138 | !******************************************************************************* 139 | subroutine thomas(a,f,x,n) 140 | ! Thomas algorithm 141 | ! only for tri-diagonal matrices Ax=f 142 | ! may include a matrix check procedure 143 | implicit none 144 | integer :: i 145 | integer, intent(in) :: n 146 | real(dp), dimension(1:n,1:n), intent(in) :: a 147 | real(dp), dimension(1:n), intent(in) :: f 148 | real(dp), dimension(1:n), intent(out) :: x 149 | real(dp), dimension(1:n-1) :: c,d 150 | real(dp), dimension(1:n) :: b,u,y 151 | real(dp), dimension(2:n) :: e,l 152 | ! copy A to vectors 153 | do i=1,n 154 | b(i)=a(i,i) 155 | end do 156 | do i=1,n-1 157 | c(i)=a(i,i+1) 158 | end do 159 | do i=2,n 160 | e(i)=a(i,i-1) 161 | end do 162 | ! decompose 163 | do i=1,n-1 164 | d(i)=c(i) 165 | end do 166 | u(1)=b(1) 167 | do i=2,n 168 | l(i)=e(i)/u(i-1) 169 | u(i)=b(i)-l(i)*c(i-1) 170 | end do 171 | ! back substitution 172 | y(1)=f(1) 173 | do i=2,n 174 | y(i)=f(i)-l(i)*y(i-1) 175 | end do 176 | ! back substitution 177 | x(n)=y(n)/u(n) 178 | do i=n-1,1,-1 179 | x(i)=(y(i)-c(i)*x(i+1))/u(i) 180 | end do 181 | end subroutine thomas 182 | !******************************************************************************* 183 | subroutine lusolv(a,b,x,n) 184 | ! LU decomposition 185 | implicit none 186 | integer :: i, k 187 | integer, intent(in) :: n 188 | real(dp), dimension(1:n,1:n), intent(in) :: a 189 | real(dp), dimension(1:n), intent(in) :: b 190 | real(dp), dimension(1:n), intent(out) :: x 191 | real(dp), dimension(1:n,1:n) :: l, u 192 | real(dp), dimension(1:n) :: y 193 | call doolittle(a,l,u,n) 194 | call downtri(l,b,y,n) 195 | call uptri(u,y,x,n) 196 | end subroutine lusolv 197 | !******************************************************************************* 198 | subroutine crout(a,l,u,n) 199 | ! Crout decomposition 200 | implicit none 201 | integer :: i,j,k,m 202 | integer, intent(in) :: n 203 | real(dp), dimension(1:n,1:n), intent(in) :: a 204 | real(dp), dimension(1:n,1:n), intent(out) :: l, u 205 | real(dp) :: s 206 | l(:,1)=a(:,1) 207 | u(1,:)=a(1,:)/l(1,1) 208 | do k=2,n 209 | do i=k,n 210 | s=0.0_dp 211 | do m=1,k-1 212 | s=s+l(i,m)*u(m,k) 213 | end do 214 | l(i,k)=a(i,k)-s 215 | end do 216 | do j=k+1,n 217 | s=0.0_dp 218 | do m=1,k-1 219 | s=s+l(k,m)*u(m,j) 220 | end do 221 | u(k,j)=(a(k,j)-s)/l(k,k) 222 | end do 223 | u(k,k)=1 224 | end do 225 | end subroutine crout 226 | !******************************************************************************* 227 | subroutine doolittle(a,l,u,n) 228 | ! Doolittle decomposition 229 | implicit none 230 | integer :: i,j,k,m 231 | integer, intent(in) :: n 232 | real(dp), dimension(1:n,1:n), intent(in) :: a 233 | real(dp), dimension(1:n,1:n), intent(out) :: l, u 234 | real(dp) :: s 235 | u(1,:)=a(1,:) 236 | l(:,1)=a(:,1)/u(1,1) 237 | do k=2,n 238 | l(k,k)=1.0_dp 239 | do j=k,n 240 | s=0.0_dp 241 | do m=1,k-1 242 | s=s+l(k,m)*u(m,j) 243 | end do 244 | u(k,j)=a(k,j)-s 245 | end do 246 | do i=k+1,n 247 | s=0.0_dp 248 | do m=1,k-1 249 | s=s+l(i,m)*u(m,k) 250 | end do 251 | l(i,k)=(a(i,k)-s)/u(k,k) 252 | end do 253 | end do 254 | end subroutine doolittle 255 | !******************************************************************************* 256 | subroutine cholesky(a,b,x,n) 257 | ! Cholesky decomposition for symmetric matrices 258 | implicit none 259 | integer :: i,j,k 260 | integer, intent(in) :: n 261 | real(dp), dimension(1:n,1:n), intent(in) :: a 262 | real(dp), dimension(1:n), intent(in) :: b 263 | real(dp), dimension(1:n), intent(out) :: x 264 | real(dp), dimension(1:n,1:n) :: l, lt 265 | real(dp), dimension(1:n) :: y 266 | real(dp) :: s 267 | logical :: sym 268 | ! check symetricity 269 | do i=1,n 270 | do j=1,n 271 | sym=a(i,j)==a(j,i) 272 | if (sym==0) stop "Cholesky returns. Matrix is not symmetric." 273 | end do 274 | end do 275 | ! first column 276 | if(a(1,1)<0) stop "Cholesky returns. Matrix is not positive definite." 277 | l(1,1)=sqrt(a(1,1)) 278 | l(2:,1)=a(2:,1)/l(1,1) 279 | ! diagonal term 280 | do j=2,n 281 | s=0.0_dp 282 | do k=1,j-1 283 | s=s+l(j,k)**2 284 | end do 285 | if((a(j,j)-s)<0) stop "Cholesky returns. Matrix is not positive definite." 286 | l(j,j)=sqrt(a(j,j)-s) 287 | ! nondiagonal term 288 | do i=j+1,n 289 | s=0.0_dp 290 | do k=1,j-1 291 | s=s+l(i,k)*l(j,k) 292 | end do 293 | l(i,j)=(a(i,j)-s)/l(j,j) 294 | end do 295 | end do 296 | ! end of decomposition 297 | call downtri(l,b,y,n) 298 | do i=1,n 299 | do j=1,n 300 | lt(i,j)=l(j,i) 301 | end do 302 | end do 303 | call uptri(lt,y,x,n) 304 | end subroutine cholesky 305 | !******************************************************************************* 306 | function det(a,n) 307 | ! calculate determinant of matrix A 308 | implicit none 309 | integer :: i 310 | integer, intent(in) :: n 311 | real(dp), dimension(1:n,1:n), intent(in) :: a 312 | real(dp) :: det 313 | real(dp), dimension(1:n,1:n) :: l, u 314 | call crout(a,l,u,n) 315 | det=1.0_dp 316 | do i=1,n 317 | det=det*l(i,i) 318 | end do 319 | end function det 320 | !******************************************************************************* 321 | subroutine uptri(a,b,x,n) 322 | implicit none 323 | integer :: i,k 324 | integer, intent(in) :: n 325 | real(dp), dimension(1:n,1:n), intent(in) :: a 326 | real(dp), dimension(1:n), intent(in) :: b 327 | real(dp), dimension(1:n), intent(out) :: x 328 | real(dp) :: s 329 | x(n)=b(n)/a(n,n) 330 | do i=n-1,1,-1 331 | s=0.0_dp 332 | do k=i+1,n 333 | s=s+a(i,k)*x(k) 334 | end do 335 | x(i)=(b(i)-s)/a(i,i) 336 | end do 337 | end subroutine uptri 338 | !******************************************************************************* 339 | subroutine downtri(a,b,x,n) 340 | implicit none 341 | integer :: i,k 342 | integer, intent(in) :: n 343 | real(dp), dimension(1:n,1:n), intent(in) :: a 344 | real(dp), dimension(1:n), intent(in) :: b 345 | real(dp), dimension(1:n), intent(out) :: x 346 | real(dp) :: s 347 | x(1)=b(1)/a(1,1) 348 | do i=2,n 349 | s=0.0_dp 350 | do k=1,i-1 351 | s=s+a(i,k)*x(k) 352 | end do 353 | x(i)=(b(i)-s)/a(i,i) 354 | end do 355 | end subroutine downtri 356 | !****************************************************************************** 357 | subroutine jacobi(a,b,x,x0,n) 358 | ! Jacobi iterative method 359 | implicit none 360 | integer :: i,j,k 361 | integer, parameter :: imax=500 362 | integer, intent(in) :: n 363 | real(dp), dimension(1:n,1:n), intent(in) :: a 364 | real(dp), dimension(1:n), intent(in) :: x0, b 365 | real(dp), dimension(1:n), intent(out) :: x 366 | real(dp), dimension(1:n) :: x1, x2 367 | real(dp) :: s, dx2, tol=1.0e-7_dp 368 | do i=1,n 369 | if(a(i,i)==0.0_dp) stop "Jacobi returns. Matrix contains zero diagonal element." 370 | end do 371 | x1=x0 372 | do k=1,imax 373 | do i=1,n 374 | s=0.0_dp 375 | do j=1,n 376 | if(j==i) cycle 377 | s=s+a(i,j)*x1(j) 378 | end do 379 | x2(i)=(b(i)-s)/a(i,i) 380 | end do 381 | ! accuracy 382 | dx2=0.0_dp 383 | do i=1,n 384 | dx2=dx2+(x1(i)-x2(i))**2 385 | end do 386 | dx2=sqrt(dx2) 387 | if(dx2i) then 417 | s=s+a(i,j)*x1(j) 418 | end if 419 | end do 420 | x2(i)=(b(i)-s)*rf/a(i,i)+(1-rf)*x1(i) 421 | end do 422 | dx2=0.0_dp 423 | do i=1,n 424 | dx2=dx2+(x1(i)-x2(i))**2 425 | end do 426 | dx2=sqrt(dx2) 427 | if(dx2elmax) then 101 | elmax=ab(i,k) 102 | idmax=i 103 | end if 104 | end do 105 | ! swap two lines 106 | temp1=ab(k,:) 107 | temp2=ab(idmax,:) 108 | ab(k,:)=temp2 109 | ab(idmax,:)=temp1 110 | do i=k+1,n 111 | lam=ab(i,k)/ab(k,k) 112 | ab(i,:)=ab(i,:)-lam*ab(k,:) 113 | end do 114 | end do 115 | aup(:,:)=ab(1:n,1:n) 116 | bup(:)=ab(:,n+1) 117 | call uptri(aup,bup,x,n) 118 | end subroutine gauss 119 | !******************************************************************************* 120 | subroutine uptri(a,b,x,n) 121 | implicit none 122 | integer :: i,k 123 | integer, intent(in) :: n 124 | real(dp), dimension(1:n,1:n), intent(in) :: a 125 | real(dp), dimension(1:n), intent(in) :: b 126 | real(dp), dimension(1:n), intent(out) :: x 127 | real(dp) :: s 128 | x(n)=b(n)/a(n,n) 129 | do i=n-1,1,-1 130 | s=0.0_dp 131 | do k=i+1,n 132 | s=s+a(i,k)*x(k) 133 | end do 134 | x(i)=(b(i)-s)/a(i,i) 135 | end do 136 | end subroutine uptri 137 | !******************************************************************************* 138 | end module nonlinear 139 | !******************************************************************************* 140 | program main 141 | use kinds 142 | use nonlinear 143 | implicit none 144 | call newton() 145 | end program main 146 | -------------------------------------------------------------------------------- /numerial-differentiation/diff.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module diff 8 | ! Numerical differentiation by central difference method and five 9 | ! point polynomial fitting. 10 | ! Richardson extrapolation eliminates truncation errors. 11 | ! Analytical differentiation is often not available 12 | ! for complex functions and discrete points. 13 | ! e.g. compute velocity and acceleration from discrete distance 14 | ! data points. 15 | use kinds 16 | implicit none 17 | private 18 | public :: central_diff, five_diff, richardson 19 | contains 20 | !******************************************************************************* 21 | subroutine central_diff() 22 | ! Central difference method for fist derivative of a function 23 | ! A simple demenstration to show that accuracy decreases with 24 | ! sufficiently small h. 25 | ! due to subtraction when f(x+h) is too close to f(x-h). 26 | implicit none 27 | integer :: i 28 | real(dp) :: x, h, f1, f2, df 29 | write(*,*) 'Result by mid-point formula:' 30 | h=1.0_dp 31 | x=sqrt(2._dp) 32 | do i=1,50 33 | f2=atan(x+h) 34 | f1=atan(x-h) 35 | df=(f2-f1)/(2*h) 36 | h=h/2.0_dp 37 | write(*,*) i,h,df 38 | end do 39 | write(*,*) 40 | end subroutine central_diff 41 | !******************************************************************************* 42 | subroutine five_diff() 43 | ! Five point polynomial fitting on a uniform grid. 44 | ! Compute f'(0.5) of function f(x)=x^2e^x. 45 | ! f'(i) = (-f(i+2)+8f(i+1)-8f(i-1)+f(i-2))/12h + O(h^4) 46 | ! Details of derivation of eqs are not shown here. 47 | implicit none 48 | integer :: i, m ! Midpoint 49 | integer, parameter :: n = 5 50 | real(dp) :: x(n), f(n), h, df 51 | h = 1.0e-2_dp 52 | m = int(n/2) + 1 53 | x(m) = 0.5_dp 54 | !-----set grid around the midpoint 55 | do i=m,n 56 | x(i) = x(m) + (i-m)*h 57 | end do 58 | do i=m,1,-1 59 | x(i) = x(m) - (m-i)*h 60 | end do 61 | !-----function values 62 | do i=1,n 63 | ! f(i) = sin(x(i)) + cos(x(i)) 64 | f(i) = x(i)**2*exp(-x(i)) 65 | end do 66 | !-----five point formula 67 | df = -f(m+2)+8._dp*f(m+1)-8._dp*f(m-1)+f(m-2) 68 | df = df/(12._dp*h) 69 | write(*,*) 'Five point poly: ' 70 | write(*,'(t8,a2,24x,a2)') 'x', 'y' 71 | write(*,*) x(m), df 72 | write(*,*) 73 | end subroutine five_diff 74 | !******************************************************************************* 75 | subroutine richardson() 76 | ! Richardson extrapolation 77 | ! Eliminate truncation error 78 | implicit none 79 | real(dp) :: x 80 | real(dp) :: h 81 | real(dp) :: f, f_exact 82 | integer :: p 83 | x=0.5 84 | h=0.05 85 | p=2 86 | 87 | f=(2.0_dp**p*g(x,h/2.0_dp)-g(x,h))/(2.0_dp**p-1.0_dp) 88 | f_exact=g_exact(x) 89 | write(*,*) 90 | write(*,*) 'Richardson:' 91 | write(*,'(t8,a2,24x,a2)') 'x', 'y' 92 | write(*,*) x, f 93 | write(*,*) 'Analytical result:' 94 | write(*,*) f_exact 95 | 96 | contains 97 | !************************************ 98 | function func(x) 99 | implicit none 100 | real(dp), intent(in) :: x 101 | real(dp) :: func 102 | func = x**2*exp(-x) 103 | end function func 104 | !************************************ 105 | function g(x,h) 106 | ! Central difference first derivative 107 | implicit none 108 | real(dp), intent(in) :: x 109 | real(dp), intent(in) :: h 110 | real(dp) :: g 111 | !g = (func(x+h)+func(x-h)-2*func(x))/h**2 112 | g = (func(x+h)-func(x-h))/(2.0_dp*h) 113 | end function g 114 | !*********************************** 115 | function g_exact(x) 116 | implicit none 117 | real(dp), intent(in) :: x 118 | real(dp) :: g_exact 119 | g_exact = 2*x*exp(-x)-x**2*exp(-x) 120 | end function g_exact 121 | !************************************ 122 | end subroutine richardson 123 | !******************************************************************************* 124 | end module diff 125 | !******************************************************************************* 126 | program main 127 | use kinds 128 | use diff 129 | implicit none 130 | call central_diff() 131 | call five_diff() 132 | call richardson() 133 | end program main 134 | !******************************************************************************* 135 | -------------------------------------------------------------------------------- /numerial-integration/integration.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module intgrl 8 | ! Numerical integration methods including Newton-Cotes (trapezoid and Simpson) 9 | ! and Gauss quadrature (Gauss-Legendre). 10 | ! Multiple integrals of simple geometrical shapes can be evaluated by Gauss 11 | ! quadrature in a similar way and is not illustrated here. 12 | use kinds 13 | implicit none 14 | private 15 | public :: func, intf_exact, trapezoid, auto_simpson, romberg, gauss_legendre, & 16 | complex_gauss, auto_gauss 17 | contains 18 | !******************************************************************************* 19 | subroutine trapezoid(intf,a,b,n) 20 | ! Trapezoidal rule 21 | ! intf----definite integral of a function 22 | ! a----lower bound 23 | ! b----upper bound 24 | ! n----number of panels 25 | implicit none 26 | integer :: i 27 | integer, intent(in) :: n 28 | real(dp), intent(in) :: a, b 29 | real(dp), intent(out) :: intf 30 | real(dp) :: h, s 31 | 32 | h=(b-a)/n 33 | 34 | s=0.0_dp 35 | do i=1,n-1 36 | s=s+func(a+i*h) 37 | end do 38 | intf = (func(a) + func(b) + 2.0_dp*s)*h/2.0_dp 39 | end subroutine trapezoid 40 | !******************************************************************************* 41 | subroutine auto_simpson(intf,a,b,n) 42 | ! adaptive simpson rule 43 | ! automatic adjustment of panel size 44 | ! n-----initial number of panels 45 | implicit none 46 | integer :: i, imax=20 47 | integer, intent(inout) :: n 48 | real(dp), intent(in) :: a, b 49 | real(dp), intent(out) :: intf 50 | real(dp) :: intf1, intf2, tol=1.0e-7_dp 51 | do i=1,imax 52 | call simpson(intf1,a,b,n) 53 | n=2.0_dp*n 54 | call simpson(intf2,a,b,n) 55 | if(abs(intf1-intf2)(f12.6),/)') 'Iter: ', i,x 144 | write(*,'(a6,i3)') 'Iter', i 145 | do j=1,n 146 | write(*,'(f12.6)') x(j) 147 | end do 148 | write(*,*) 149 | if(sqrt(dx(1)**2+dx(2)**2)elmax) then 258 | elmax=ab(i,k) 259 | idmax=i 260 | end if 261 | end do 262 | ! swap two lines 263 | temp1=ab(k,:) 264 | temp2=ab(idmax,:) 265 | ab(k,:)=temp2 266 | ab(idmax,:)=temp1 267 | do i=k+1,n 268 | lam=ab(i,k)/ab(k,k) 269 | ab(i,:)=ab(i,:)-lam*ab(k,:) 270 | end do 271 | end do 272 | aup(:,:)=ab(1:n,1:n) 273 | bup(:)=ab(:,n+1) 274 | call uptri(aup,bup,x,n) 275 | end subroutine gauss 276 | !******************************************************************************* 277 | end module finite_diff 278 | !****************************************************************************** 279 | program main 280 | use kinds 281 | use finite_diff 282 | implicit none 283 | write(*,*) 'Solution for linear example: ' 284 | call fd_lin() 285 | write(*,*) 286 | write(*,*) 'Solution for non-linear example: ' 287 | call fd_nonlin() 288 | end program main 289 | -------------------------------------------------------------------------------- /ordinary-differential-equations/boundary-value-problems/shooting-method/shoot.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module shoot_method 8 | ! Boundary value problems 9 | ! Shooting method 10 | ! Guess unknown derivatives at one boundary and 11 | ! solve an initial value problem. 12 | ! March to the other boundary. 13 | ! Adjust and try until the prescribed boundary value. 14 | use kinds 15 | implicit none 16 | private 17 | public :: shoot_integrate, rk45_adaptive, func 18 | contains 19 | !******************************************************************************* 20 | subroutine shoot_integrate(xstart,xstop,ystop,yb,u1,u2,m) 21 | ! Shooting integration for 2nd order ode (can be extended for higher order.) 22 | ! with classical Runge-Kutta method. 23 | ! xstart-----start of integration 24 | ! xstop-----end of integration 25 | ! u1-----1st trial value of unknown init. cond. 26 | ! u2-----2st trial value of unknown init. cond. 27 | ! m-----dimension of odes 28 | ! x,y-----integration output 29 | implicit none 30 | integer, intent(in) :: m 31 | !real(dp), intent(inout) :: u1, u2, xstop 32 | !real(dp), intent(inout) :: xstart 33 | real(dp), intent(in) :: xstart, xstop 34 | !real(dp), intent(in) :: ystart 35 | real(dp), intent(in) :: yb 36 | real(dp), dimension(m), intent(out) :: ystop 37 | real(dp), intent(in) :: u1, u2 38 | real(dp) :: usol, xcopy, ycorr(m) 39 | !-----compute correct initial condition 40 | call ridder_res(u1,u2,yb,usol) 41 | write(*,'(t4,a31,/,3(f12.5))') 'Two guesses and computed root: ', u1, u2, usol 42 | call init_cond(usol,ycorr) 43 | call rk45_adaptive(xstart,xstop,ycorr,ystop,m) 44 | contains 45 | !******************************************************************************* 46 | subroutine init_cond(gs,yinit) 47 | ! gs-----a guess of y' 48 | ! yinit-----inital values of the system 49 | real(dp), intent(in) :: gs ! unknown 50 | real(dp), dimension(m), intent(out) :: yinit 51 | yinit = [0._dp,gs] 52 | end subroutine init_cond 53 | !******************************************************************************* 54 | function resdiff(gs,ybc) 55 | ! y'' = f(x,y,y'); y(a) = alpha; y(b) = beta. 56 | ! boundary residual (difference between the computed and specified 57 | ! boundary value at x = b. 58 | ! computed y(b) = theta(u) 59 | ! res(u) = theta(u) - beta = 0 60 | implicit none 61 | real(dp), intent(in) :: gs 62 | real(dp), intent(in) :: ybc 63 | real(dp), dimension(m) :: y1, y2 64 | real(dp) :: resdiff 65 | call init_cond(gs,y1) 66 | call rk45_adaptive(xstart,xstop,y1,y2,m) 67 | resdiff = y2(m-1) - ybc 68 | end function resdiff 69 | !******************************************************************************* 70 | subroutine ridder_res(a,b,ybc,xsol) 71 | ! Ridder's method using 3 points 72 | ! calculate residual difference function 73 | implicit none 74 | integer, parameter :: imax=50 75 | integer :: i 76 | integer :: iter 77 | real(dp), parameter :: tol=1.e-5_dp 78 | real(dp), intent(in) :: a, b, ybc 79 | real(dp), intent(out) :: xsol 80 | real(dp) :: fx 81 | real(dp) :: x0, x1, x2, dx, fa, fb, fc, c, sq 82 | !write(*,105) 83 | !105 format (/,T10,'Ridder method intermediate output',/, & 84 | ! 10x,'iter',8x,'x',25x,'f(x)') 85 | x0 = a 86 | x1 = b 87 | fa = resdiff(x0,ybc) 88 | if(fa==0._dp) then 89 | xsol = x0 90 | fx = fa 91 | return 92 | end if 93 | fb = resdiff(x1,ybc) 94 | if(fb==0._dp) then 95 | xsol = x1 96 | fx = fb 97 | return 98 | end if 99 | if(fa*fb>0._dp) stop 'Ridder returns; Root is not bracketed' 100 | do i=1,imax 101 | c = 0.5_dp*(x0+x1) 102 | fc = resdiff(c,ybc) 103 | sq = sqrt(fc**2-fa*fb) 104 | if(sq==0._dp) return 105 | dx = (c-x0)*fc/sq 106 | if((fa-fb)<0._dp) dx = -dx 107 | xsol = c + dx 108 | fx = resdiff(xsol,ybc) 109 | !-----test for convergence 110 | if(i>0) then 111 | if(abs(xsol-c)0._dp) then 116 | if(fa*fx<0._dp) then 117 | x1 = xsol 118 | fb = fx 119 | else 120 | x0 = xsol 121 | fa = fx 122 | end if 123 | else 124 | x0 = c 125 | x1 = xsol 126 | fa = fc 127 | fb = fx 128 | end if 129 | end do 130 | iter = i 131 | end subroutine ridder_res 132 | end subroutine shoot_integrate 133 | !******************************************************************************* 134 | subroutine rk45_adaptive(xstart,xstop,ystart,ystop,m,hstep) 135 | ! Adaptive Runge-Kutta method with embedded Runge-Kutta-Fehlberg formula 136 | implicit none 137 | integer :: i 138 | integer, intent(in) :: m 139 | real(dp), intent(in) :: xstart 140 | real(dp), intent(in) :: xstop 141 | real(dp), dimension(m), intent(in) :: ystart 142 | real(dp), dimension(m), intent(out) :: ystop 143 | real(dp), intent(in), optional :: hstep 144 | real(dp), dimension(m) :: y, dy 145 | real(dp) :: x, h, delta, error 146 | real(dp) :: hnext 147 | real(dp), parameter :: tol = 1.0e-6_dp 148 | x = xstart 149 | y = ystart 150 | !-----initial step size 151 | if(present(hstep)) then 152 | h = min(hstep, xstop-x) 153 | else 154 | h = min(1.0e-1_dp, xstop-x) 155 | end if 156 | !-----integration 157 | do while(xtol) then 163 | !-----recalculate current step with reduced step size 164 | h = h * delta 165 | call rkf(x,y,h,m,dy,error) 166 | end if 167 | y = y + dy 168 | x = x + h 169 | !-----next step size with a margin of safety 170 | delta = 0.9_dp*(tol/error)**0.2_dp 171 | if(error/=0.0_dp) then 172 | hnext = h * delta 173 | else 174 | hnext = h 175 | end if 176 | !-----check if next step is the last one 177 | if((h>0._dp) == ((x+hnext)>=xstop)) then 178 | hnext = xstop - x 179 | end if 180 | h = hnext 181 | !-----intermediate result print 182 | ! write(*,'(f12.5)') x, y 183 | end do 184 | ystop = y 185 | 186 | contains 187 | 188 | subroutine rkf(x,y,h,m,dy,error) 189 | ! 5th order Runge-Kutta-Fehlberg formulas by Cash-Karp 190 | implicit none 191 | integer :: i 192 | integer, intent(in) :: m 193 | real(dp), intent(in) :: x, h 194 | real(dp), dimension(m), intent(in) :: y 195 | real(dp), dimension(m), intent(out):: dy 196 | real(dp), intent(out) :: error 197 | real(dp), dimension(m) :: e 198 | real(dp), dimension(6,m) :: k 199 | real(dp), dimension(2:6) :: a 200 | real(dp), dimension(1) :: b2 201 | real(dp), dimension(2) :: b3 202 | real(dp), dimension(3) :: b4 203 | real(dp), dimension(4) :: b5 204 | real(dp), dimension(5) :: b6 205 | real(dp), dimension(6) :: c, d 206 | real(dp) :: s 207 | !-----list of coefficients 208 | a = ([1._dp/5, 3._dp/10, 3._dp/5, 1._dp, 7._dp/8]) 209 | b2 = ([1._dp/5]) 210 | b3 = ([3._dp/40, 9._dp/40]) 211 | b4 = ([3._dp/10, -9._dp/10, 6._dp/5]) 212 | b5 = ([-11._dp/54, 5._dp/2, -70._dp/27, 35._dp/27]) 213 | b6 = ([1631._dp/55296, 175._dp/512, 575._dp/13824, 44275._dp/110592, 253._dp/4096 ]) 214 | c = ([37._dp/378, 0._dp, 250._dp/621, 125._dp/594, 0._dp, 512._dp/1771]) 215 | d = ([2825._dp/27648, 0._dp, 18575._dp/48384, 13525._dp/55296, 277._dp/14336, 1._dp/4]) 216 | !-----formulas 217 | k(1,:) = h*func(x, y, m) 218 | k(2,:) = h*func(x+a(2)*h, y+b2(1)*k(1,:), m) 219 | k(3,:) = h*func(x+a(3)*h, y+(b3(1)*k(1,:)+b3(2)*k(2,:)), m) 220 | k(4,:) = h*func(x+a(4)*h, y+(b4(1)*k(1,:)+b4(2)*k(2,:)+b4(3)*k(3,:)), m) 221 | k(5,:) = h*func(x+a(5)*h, y+(b5(1)*k(1,:)+b5(2)*k(2,:)+b5(3)*k(3,:)+b5(4)*k(4,:)), m) 222 | k(6,:) = h*func(x+a(6)*h, y+(b6(1)*k(1,:)+b6(2)*k(2,:)+b6(3)*k(3,:)+b6(4)*k(4,:)+b6(5)*k(5,:)), m) 223 | !-----initialize arrays {dy} and {e} 224 | dy = 0._dp 225 | e = 0._dp 226 | !-----compute solution increment {dy} and per-step error {e} 227 | do i=1,6 228 | !-----5th order formula 229 | dy = dy + c(i)*k(i,:) 230 | !-----use 4th order formula implicitly to estimate the truncation error 231 | e = e + (c(i)-d(i))*k(i,:) 232 | end do 233 | !-----rms error 234 | error = sqrt(sum(e**2)/m) 235 | end subroutine rkf 236 | end subroutine rk45_adaptive 237 | !******************************************************************************* 238 | function func(x,y,m) 239 | ! m-dimension 1st order odes 240 | ! Any higher nth order ode can always be converted to n 1st order odes 241 | implicit none 242 | integer, intent(in) :: m 243 | real(dp), intent(in) :: x 244 | real(dp), dimension(m), intent(in) :: y 245 | real(dp), dimension(m) :: func 246 | func(1) = y(2) 247 | func(2) = -3._dp*y(1)*y(2) 248 | !func(1) = y(2) 249 | !func(2) = -4.75_dp*y(1) - 10.0_dp*y(2) 250 | end function func 251 | end module shoot_method 252 | !******************************************************************************* 253 | program main 254 | use kinds 255 | use shoot_method 256 | implicit none 257 | integer :: m 258 | real(dp) :: xstart, xstop, u1, u2, x, yb, res 259 | real(dp) :: ystart(2), ystop(2) 260 | xstart = 0.0_dp 261 | xstop = 2.00_dp 262 | ystart = [0._dp, 1.5145_dp] ! with root 263 | yb = 1._dp 264 | u1 = 1._dp 265 | u2 = 2._dp 266 | call shoot_integrate(xstart,xstop,ystop,yb,u1,u2,2) 267 | !call rk45_adaptive(xstart,xstop,ystart,ystop,2) 268 | write(*,101) xstop, ystop 269 | 101 format(T4, 'Result from shooting method, ',"x,y,y': "/,(f13.6)) 270 | end program main 271 | -------------------------------------------------------------------------------- /ordinary-differential-equations/initial-value-problems/1d-heat-diffusion/diff.in: -------------------------------------------------------------------------------- 1 | 1D transient heat conduction (diffusion ) 2 | finite difference method 3 | 20 !number of grid point 4 | 1. !time step 5 | 1000. !max time 6 | 1. !length of rod 7 | 1e-05 !thermal diffusivity 8 | -------------------------------------------------------------------------------- /ordinary-differential-equations/initial-value-problems/1d-heat-diffusion/heatdiff.f90: -------------------------------------------------------------------------------- 1 | program main 2 | !---------------------------------------------------------------------- 3 | ! Example of an initial value problem; 4 | ! solves 1d transient heat conduction equation 5 | ! dT/dt=alpha*d2T/dx2 6 | ! explicit method 7 | ! iterative mehtod(explicit) 8 | !---------------------------------------------------------------------- 9 | implicit none 10 | integer :: i,ni,nt,i_read,file1,file2 11 | real :: t,alpha,tmax,xmax,delx,delt,s 12 | real, dimension(:), allocatable :: x,temp,temp_cp 13 | file1=1 14 | file2=2 15 | open(unit=file1,file='diff.in') 16 | open(unit=file2,file='diff.dat') 17 | do i_read=1,2 18 | read(file1,*) 19 | end do 20 | read(file1,*) ni 21 | read(file1,*) delt 22 | read(file1,*) tmax 23 | read(file1,*) xmax 24 | read(file1,*) alpha 25 | !-----initiate 26 | allocate(x(ni),temp(ni),temp_cp(ni)) 27 | !-----grid 28 | delx=xmax/ni 29 | x(1)=0. 30 | x(ni)=xmax 31 | do i=2,ni-1 32 | x(i)=x(i-1)+delx 33 | end do 34 | !-----initial value 35 | nt=int(tmax/delt) 36 | s=alpha*delt/(delx**2) 37 | do i=1,ni 38 | temp(i)=0.0 39 | end do 40 | t=0. 41 | !-----boundary condition 42 | temp(1)=100. 43 | temp(ni)=100. 44 | !-----time integration 45 | do while (t<=tmax) 46 | do i=1,ni 47 | temp_cp(i)=temp(i) 48 | end do 49 | do i=2,ni-1 50 | temp(i)=s*temp_cp(i-1)+(1-2*s)*temp_cp(i)+s*temp_cp(i+1) 51 | end do 52 | write(file2,102) t 53 | write(file2,103) (temp(i),i=1,ni) 54 | t=t+delt 55 | end do 56 | deallocate(x,temp,temp_cp) 57 | 102 format('time:',1X,7F6.1) 58 | 103 format(10F8.2) 59 | end program main 60 | -------------------------------------------------------------------------------- /ordinary-differential-equations/initial-value-problems/multi-step/multi_step.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp = kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module adams_bashforth 8 | ! Initial value problem. 9 | ! Adams-Bashforth is a linear multi-step method. 10 | ! Use information of previous steps. 11 | ! A linear combination of previous points and derivatives. 12 | ! Need a single-step method (Runge-Kutta) to drive initially. 13 | ! Because first few points are not available 14 | use kinds 15 | implicit none 16 | public :: ab3, ab3_pece, func, rk45_adaptive 17 | 18 | contains 19 | !******************************************************************************* 20 | subroutine ab3_pece(x,y,xstop,m,n) 21 | ! Predict-Evaluate-Correct-Evaluate mode of 22 | ! 3rd order Adams-Bashforth method 23 | ! calculate an initial guess with a 3-step method 24 | ! improve it using a 4-step method 25 | ! also evaluate the function func = y' 26 | implicit none 27 | integer :: i 28 | integer, intent(in) :: m, n 29 | real(dp), intent(inout) :: x 30 | real(dp), intent(in) :: xstop 31 | real(dp), dimension(m), intent(inout) :: y 32 | real(dp), dimension(m) :: y0, y1, y2, y3, f0, f1, f2, f3 33 | real(dp), dimension(m) :: y3_p, f3_e 34 | real(dp) :: x0, x1, x2, x3, h 35 | !-----step size 36 | h = (xstop-x)/n 37 | !-----initial values 38 | x0 = x 39 | y0 = y 40 | f0 = func(x0,y0,m) 41 | !-----compute first point 42 | call rk45_adaptive(x0,y0,x0+h,m) 43 | x1 = x0 44 | y1 = y0 45 | f1 = func(x1,y1,m) 46 | !-----compute second point 47 | call rk45_adaptive(x1,y1,x1+h,m) 48 | x2 = x1 49 | y2 = y1 50 | f2 = func(x2,y2,m) 51 | do i=3,n 52 | !-----predict 53 | y3_p = y2 + h*(23._dp*f2 - 16._dp*f1 + 5._dp*f0)/12._dp 54 | x3 = x2 + h 55 | !-----evaluate 56 | f3_e = func(x3,y3_p,m) 57 | !-----correct 58 | y3 = y2 + h*(9._dp*f3_e + 19._dp*f2 - 5._dp*f1 + f0)/24._dp 59 | !-----evaluate 60 | f3 = func(x3,y3,m) 61 | write(*,'(f10.5)') x3, y3 62 | !-----update 63 | x2 = x2 + h 64 | y2 = y3 65 | f0 = f1 66 | f1 = f2 67 | f2 = f3 68 | end do 69 | 70 | end subroutine ab3_pece 71 | !******************************************************************************* 72 | subroutine ab3(x,y,xstop,m,n) 73 | ! 3 step 3rd order Adams-Bashforth method 74 | ! m-----dimension of odes 75 | ! n-----number of integral division 76 | ! xstop-----end of integration 77 | implicit none 78 | integer :: i 79 | integer, intent(in) :: m, n 80 | real(dp), intent(in) :: xstop 81 | real(dp), intent(inout) :: x 82 | real(dp), dimension(m), intent(inout) :: y 83 | real(dp), dimension(m) :: y0, y1, y2, y3, f0, f1, f2, f3 84 | real(dp) :: x0, x1, x2, x3, h 85 | !-----step size 86 | h = (xstop-x)/n 87 | !-----initial values 88 | x0 = x 89 | y0 = y 90 | f0 = func(x0,y0,m) 91 | !-----compute first point 92 | call rk45_adaptive(x0,y0,x0+h,m) 93 | x1 = x0 94 | y1 = y0 95 | f1 = func(x1,y1,m) 96 | !-----compute second point 97 | call rk45_adaptive(x1,y1,x1+h,m) 98 | x2 = x1 99 | y2 = y1 100 | f2 = func(x2,y2,m) 101 | do i=3,n 102 | y3 = y2 + h*(23._dp*f2 - 16._dp*f1 + 5._dp*f0)/12._dp 103 | x3 = x2 + h 104 | write(*,'(f10.5)') x3, y3 105 | !-----update 106 | x2 = x2 + h 107 | y2 = y3 108 | f0 = f1 109 | f1 = f2 110 | f2 = func(x2,y2,m) 111 | end do 112 | end subroutine ab3 113 | 114 | !******************************************************************************* 115 | function func(x,y,m) 116 | ! system of ordinary differential equations 117 | ! y' = func = f(x) 118 | implicit none 119 | integer, intent(in) :: m 120 | real(dp), intent(in) :: x 121 | real(dp), dimension(m), intent(in) :: y 122 | real(dp), dimension(m) :: func 123 | func(1) = y(2)*y(3) 124 | func(2) = -y(1)*y(3) 125 | func(3) = -0.4_dp*y(1)*y(2) 126 | end function func 127 | !******************************************************************************* 128 | subroutine rk45_adaptive(x,y,xstop,m,hstep) 129 | ! Adaptive Runge-Kutta method with embedded Runge-Kutta-Fehlberg formula 130 | implicit none 131 | integer :: i 132 | integer, intent(in) :: m 133 | real(dp), intent(in) :: xstop 134 | real(dp), intent(in), optional :: hstep 135 | real(dp), intent(inout) :: x 136 | real(dp), dimension(m), intent(inout) :: y 137 | real(dp), dimension(m) :: dy 138 | real(dp) :: h, delta, error 139 | real(dp) :: hnext 140 | real(dp), parameter :: tol = 1.0e-6_dp 141 | !-----initial step size 142 | if(present(hstep)) then 143 | h = min(hstep, xstop-x) 144 | else 145 | h = min(1.0e-1_dp, xstop-x) 146 | end if 147 | !-----integration 148 | do while(xtol) then 154 | !-----recalculate current step with reduced step size 155 | h = h * delta 156 | call rkf(x,y,h,m,dy,error) 157 | end if 158 | y = y + dy 159 | x = x + h 160 | !-----next step size with a margin of safety 161 | delta = 0.9_dp*(tol/error)**0.2_dp 162 | if(error/=0.0_dp) then 163 | hnext = h * delta 164 | else 165 | hnext = h 166 | end if 167 | !-----check if next step is the last one 168 | if((h>0._dp) == ((x+hnext)>=xstop)) then 169 | hnext = xstop - x 170 | end if 171 | h = hnext 172 | !-----print 173 | write(*,'(E14.5)') x, y 174 | end do 175 | 176 | contains 177 | 178 | subroutine rkf(x,y,h,m,dy,error) 179 | ! 5th order Runge-Kutta-Fehlberg formulas by Cash-Karp 180 | implicit none 181 | integer :: i 182 | integer, intent(in) :: m 183 | real(dp), intent(in) :: x, h 184 | real(dp), dimension(m), intent(in) :: y 185 | real(dp), dimension(m), intent(out):: dy 186 | real(dp), intent(out) :: error 187 | real(dp), dimension(m) :: e 188 | real(dp), dimension(6,m) :: k 189 | real(dp), dimension(2:6) :: a 190 | real(dp), dimension(1) :: b2 191 | real(dp), dimension(2) :: b3 192 | real(dp), dimension(3) :: b4 193 | real(dp), dimension(4) :: b5 194 | real(dp), dimension(5) :: b6 195 | real(dp), dimension(6) :: c, d 196 | real(dp) :: s 197 | !-----list of coefficients 198 | a = ([1._dp/5, 3._dp/10, 3._dp/5, 1._dp, 7._dp/8]) 199 | b2 = ([1._dp/5]) 200 | b3 = ([3._dp/40, 9._dp/40]) 201 | b4 = ([3._dp/10, -9._dp/10, 6._dp/5]) 202 | b5 = ([-11._dp/54, 5._dp/2, -70._dp/27, 35._dp/27]) 203 | b6 = ([1631._dp/55296, 175._dp/512, 575._dp/13824, 44275._dp/110592, 253._dp/4096 ]) 204 | c = ([37._dp/378, 0._dp, 250._dp/621, 125._dp/594, 0._dp, 512._dp/1771]) 205 | d = ([2825._dp/27648, 0._dp, 18575._dp/48384, 13525._dp/55296, 277._dp/14336, 1._dp/4]) 206 | !-----formulas 207 | k(1,:) = h*func(x, y, m) 208 | k(2,:) = h*func(x+a(2)*h, y+b2(1)*k(1,:), m) 209 | k(3,:) = h*func(x+a(3)*h, y+(b3(1)*k(1,:)+b3(2)*k(2,:)), m) 210 | k(4,:) = h*func(x+a(4)*h, y+(b4(1)*k(1,:)+b4(2)*k(2,:)+b4(3)*k(3,:)), m) 211 | k(5,:) = h*func(x+a(5)*h, y+(b5(1)*k(1,:)+b5(2)*k(2,:)+b5(3)*k(3,:)+b5(4)*k(4,:)), m) 212 | k(6,:) = h*func(x+a(6)*h, y+(b6(1)*k(1,:)+b6(2)*k(2,:)+b6(3)*k(3,:)+b6(4)*k(4,:)+b6(5)*k(5,:)), m) 213 | !-----initialize arrays {dy} and {e} 214 | dy = 0._dp 215 | e = 0._dp 216 | !-----compute solution increment {dy} and per-step error {e} 217 | do i=1,6 218 | !-----5th order formula 219 | dy = dy + c(i)*k(i,:) 220 | !-----use 4th order formula implicitly to estimate the truncation error 221 | e = e + (c(i)-d(i))*k(i,:) 222 | end do 223 | !-----rms error 224 | error = sqrt(sum(e**2)/m) 225 | end subroutine rkf 226 | end subroutine rk45_adaptive 227 | !******************************************************************************* 228 | end module adams_bashforth 229 | !******************************************************************************* 230 | program main 231 | use kinds 232 | use adams_bashforth 233 | implicit none 234 | integer :: n = 100 235 | real(dp) :: x, xstop, y(3) 236 | x = 1._dp 237 | xstop = 6.0_dp 238 | y = [1._dp, 1._dp, 1._dp] 239 | write(*,*) 'Result by Adams-Bashforth method: ' 240 | call ab3_pece(x,y,xstop,3,n) 241 | end program main 242 | !******************************************************************************* 243 | -------------------------------------------------------------------------------- /ordinary-differential-equations/initial-value-problems/single-step/single_step.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp = kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module runge_kutta 8 | ! Initial value problem. 9 | ! Runge-Kutta is a explicit single step method. 10 | ! Only one previous point and its derivative 11 | ! are used to determine current value. 12 | ! Both classical and adaptive versions are included. 13 | use kinds 14 | implicit none 15 | public :: func, rk4, rk45_adaptive 16 | 17 | contains 18 | !******************************************************************************* 19 | subroutine rk4(x,y,xstop,m,n) 20 | ! First order odes with 4th order Runge-Kutta method 21 | ! Initial value problem {y}' = {f(x,{y})} 22 | ! x-----independent variable 23 | ! y-----dependent variable y(1), y(2), ..., y(m) 24 | ! xstop-----end of integration 25 | ! m-----dimension of odes 26 | ! n-----number of integral steps 27 | implicit none 28 | integer :: i 29 | integer, intent(in) :: m, n 30 | real(dp), intent(in) :: xstop 31 | real(dp), intent(inout) :: x 32 | real(dp), dimension(m), intent(inout) :: y 33 | real(dp) :: h 34 | h = (xstop-x)/n 35 | do i=1,n 36 | y = y + rk4_coef(x,y,h,m) 37 | x = x + h 38 | write(*,'(E14.5)') x, y 39 | end do 40 | 41 | contains 42 | 43 | function rk4_coef(x,y,h,m) 44 | ! Coefficients and increament with classical 4th order Runge-Kutta method 45 | implicit none 46 | integer :: i 47 | integer, intent(in) :: m 48 | real(dp), intent(in) :: x, h 49 | real(dp), dimension(m), intent(in) :: y 50 | real(dp), dimension(m) :: rk4_coef 51 | real(dp), dimension(4,m) :: k 52 | k(1,:) = h*func(x, y, m) 53 | k(2,:) = h*func(x+0.5_dp*h, y+0.5_dp*k(1,:), m) 54 | k(3,:) = h*func(x+0.5_dp*h, y+0.5_dp*k(2,:), m) 55 | k(4,:) = h*func(x+h, y+k(3,:), m) 56 | rk4_coef = (k(1,:) + 2.0_dp*k(2,:) + 2.0_dp*k(3,:) + k(4,:))/6.0_dp 57 | end function rk4_coef 58 | end subroutine rk4 59 | !******************************************************************************* 60 | subroutine rk45_adaptive(xstart,xstop,ystart,ystop,m,hstep) 61 | ! Adaptive Runge-Kutta method with embedded Runge-Kutta-Fehlberg formula 62 | implicit none 63 | integer :: i 64 | integer, intent(in) :: m 65 | real(dp), intent(in) :: xstart 66 | real(dp), intent(in) :: xstop 67 | real(dp), dimension(m), intent(in) :: ystart 68 | real(dp), dimension(m), intent(out) :: ystop 69 | real(dp), intent(in), optional :: hstep 70 | real(dp), dimension(m) :: y, dy 71 | real(dp) :: x, h, delta, error 72 | real(dp) :: hnext 73 | real(dp), parameter :: tol = 1.0e-6_dp 74 | x = xstart 75 | y = ystart 76 | !-----initial step size 77 | if(present(hstep)) then 78 | h = min(hstep, xstop-x) 79 | else 80 | h = min(1.0e-1_dp, xstop-x) 81 | end if 82 | !-----integration 83 | do while(xtol) then 89 | !-----recalculate current step with reduced step size 90 | h = h * delta 91 | call rkf(x,y,h,m,dy,error) 92 | end if 93 | y = y + dy 94 | x = x + h 95 | !-----next step size with a margin of safety 96 | delta = 0.9_dp*(tol/error)**0.2_dp 97 | if(error/=0.0_dp) then 98 | hnext = h * delta 99 | else 100 | hnext = h 101 | end if 102 | !-----check if next step is the last one 103 | if((h>0._dp) == ((x+hnext)>=xstop)) then 104 | hnext = xstop - x 105 | end if 106 | h = hnext 107 | !-----print 108 | write(*,'(E14.5)') x, y 109 | end do 110 | ystop = y 111 | 112 | contains 113 | 114 | subroutine rkf(x,y,h,m,dy,error) 115 | ! 5th order Runge-Kutta-Fehlberg formulas by Cash-Karp 116 | implicit none 117 | integer :: i 118 | integer, intent(in) :: m 119 | real(dp), intent(in) :: x, h 120 | real(dp), dimension(m), intent(in) :: y 121 | real(dp), dimension(m), intent(out):: dy 122 | real(dp), intent(out) :: error 123 | real(dp), dimension(m) :: e 124 | real(dp), dimension(6,m) :: k 125 | real(dp), dimension(2:6) :: a 126 | real(dp), dimension(1) :: b2 127 | real(dp), dimension(2) :: b3 128 | real(dp), dimension(3) :: b4 129 | real(dp), dimension(4) :: b5 130 | real(dp), dimension(5) :: b6 131 | real(dp), dimension(6) :: c, d 132 | real(dp) :: s 133 | !-----list of coefficients 134 | a = ([1._dp/5, 3._dp/10, 3._dp/5, 1._dp, 7._dp/8]) 135 | b2 = ([1._dp/5]) 136 | b3 = ([3._dp/40, 9._dp/40]) 137 | b4 = ([3._dp/10, -9._dp/10, 6._dp/5]) 138 | b5 = ([-11._dp/54, 5._dp/2, -70._dp/27, 35._dp/27]) 139 | b6 = ([1631._dp/55296, 175._dp/512, 575._dp/13824, 44275._dp/110592, 253._dp/4096 ]) 140 | c = ([37._dp/378, 0._dp, 250._dp/621, 125._dp/594, 0._dp, 512._dp/1771]) 141 | d = ([2825._dp/27648, 0._dp, 18575._dp/48384, 13525._dp/55296, 277._dp/14336, 1._dp/4]) 142 | !-----formulas 143 | k(1,:) = h*func(x, y, m) 144 | k(2,:) = h*func(x+a(2)*h, y+b2(1)*k(1,:), m) 145 | k(3,:) = h*func(x+a(3)*h, y+(b3(1)*k(1,:)+b3(2)*k(2,:)), m) 146 | k(4,:) = h*func(x+a(4)*h, y+(b4(1)*k(1,:)+b4(2)*k(2,:)+b4(3)*k(3,:)), m) 147 | k(5,:) = h*func(x+a(5)*h, y+(b5(1)*k(1,:)+b5(2)*k(2,:)+b5(3)*k(3,:)+b5(4)*k(4,:)), m) 148 | k(6,:) = h*func(x+a(6)*h, y+(b6(1)*k(1,:)+b6(2)*k(2,:)+b6(3)*k(3,:)+b6(4)*k(4,:)+b6(5)*k(5,:)), m) 149 | !-----initialize arrays {dy} and {e} 150 | dy = 0._dp 151 | e = 0._dp 152 | !-----compute solution increment {dy} and per-step error {e} 153 | do i=1,6 154 | !-----5th order formula 155 | dy = dy + c(i)*k(i,:) 156 | !-----use 4th order formula implicitly to estimate the truncation error 157 | e = e + (c(i)-d(i))*k(i,:) 158 | end do 159 | !-----rms error 160 | error = sqrt(sum(e**2)/m) 161 | end subroutine rkf 162 | end subroutine rk45_adaptive 163 | !******************************************************************************* 164 | function func(x,y,m) 165 | ! m-dimension 1st order odes 166 | ! Any higher nth order ode can always be converted to n 1st order odes 167 | implicit none 168 | integer, intent(in) :: m 169 | real(dp), intent(in) :: x 170 | real(dp), dimension(m), intent(in) :: y 171 | real(dp), dimension(m) :: func 172 | !func(1) = y(2)*y(3) 173 | !func(2) = -y(1)*y(3) 174 | !func(3) = -0.51*y(1)*y(2) 175 | !func(1) = y(2) 176 | !func(2) = -9.80665_dp + (65.351e-3_dp)*y(2)**2._dp*exp(-10.53e-5_dp*y(1)) 177 | func(1) = y(2) 178 | func(2) = -4.75_dp*y(1) - 10.0_dp*y(2) 179 | end function func 180 | !******************************************************************************* 181 | end module runge_kutta 182 | !******************************************************************************* 183 | program main 184 | use kinds 185 | use runge_kutta 186 | implicit none 187 | integer :: n 188 | real(dp) :: xstart, h, xstop, tol 189 | real(dp), dimension(2) :: ystart, ysol 190 | xstart = 0.0_dp 191 | xstop = 11.1_dp 192 | ystart = ([-9.0_dp, 0.0_dp]) 193 | h = 0.1_dp 194 | write(*,*) 'Result by Runge-Kutta method: ' 195 | call rk45_adaptive(xstart,xstop,ystart,ysol,2) 196 | end program main 197 | !******************************************************************************* 198 | -------------------------------------------------------------------------------- /roots-of-equations/roots.f90: -------------------------------------------------------------------------------- 1 | !******************************************************************************* 2 | module kinds 3 | implicit none 4 | integer, parameter :: dp=kind(0.d0) ! double precision 5 | end module kinds 6 | !******************************************************************************* 7 | module root 8 | use kinds 9 | implicit none 10 | private 11 | public :: func, bisect, picard, newton_raphson, secant, ridder 12 | contains 13 | !******************************************************************************* 14 | subroutine bisect(a,b,x,fx,iter) 15 | ! Bolzano bisection method 16 | ! f(x)=0 continuous in [a,b] 17 | ! if f(a)f(b)<0 then f(x) has at least one root in [a,b] 18 | ! c is the midpoint between a and b 19 | implicit none 20 | integer, parameter :: imax=50 21 | integer :: i 22 | integer, intent(out) :: iter 23 | real(dp), parameter :: tol=1.e-8_dp 24 | real(dp), intent(inout) :: a, b 25 | real(dp), intent(out) :: x, fx 26 | real(dp) :: c, dx 27 | write(*,101) 28 | 101 format (T10,'Bisection method intermediate output',/, & 29 | 10x,'iter',8x,'x',25x,'f(x)') 30 | do i=1,imax 31 | c = (a+b)/2 32 | if(func(c)==0) then 33 | exit 34 | else if(func(a)*func(c)<0.0_dp) then 35 | b = c 36 | else 37 | a = c 38 | end if 39 | dx = abs(a-b) 40 | if(dx0._dp) stop 'Ridder returns; Root is not bracketed' 164 | do i=1,imax 165 | c = 0.5_dp*(x0+x1) 166 | fc = func(c) 167 | sq = sqrt(fc**2-fa*fb) 168 | if(sq==0._dp) return 169 | dx = (c-x0)*fc/sq 170 | if((fa-fb)<0._dp) dx = -dx 171 | x = c + dx 172 | fx = func(x) 173 | !-----test for convergence 174 | if(i>0) then 175 | if(abs(x-c)0._dp) then 180 | if(fa*fx<0._dp) then 181 | x1 = x 182 | fb = fx 183 | else 184 | x0 = x 185 | fa = fx 186 | end if 187 | else 188 | x0 = c 189 | x1 = x 190 | fa = fc 191 | fb = fx 192 | end if 193 | end do 194 | iter = i 195 | end subroutine ridder 196 | !******************************************************************************* 197 | function func(x) 198 | ! input function 199 | implicit none 200 | real(dp), intent(in) :: x 201 | real(dp) :: func 202 | !func = (x-1)**3._dp - 3._dp*x + 2._dp 203 | !func=1._dp/8 * (35._dp * x**4._dp - 30._dp * x**2._dp + 3._dp) 204 | !func = x**3._dp + 2._dp*x**2._dp +10._dp*x -20._dp 205 | func = x**3 - 10._dp*x**2 + 5._dp 206 | end function func 207 | !******************************************************************************* 208 | function dfunc(x) 209 | ! first derivative of the function 210 | ! analytical values 211 | implicit none 212 | real(dp), intent(in) :: x 213 | real(dp) :: dfunc 214 | !dfunc = 2._dp*x**2 + 4._dp*x + 10._dp 215 | dfunc = 3._dp*x**2 - 20._dp*x 216 | end function dfunc 217 | !******************************************************************************* 218 | end module root 219 | !******************************************************************************* 220 | program main 221 | use kinds 222 | use root 223 | implicit none 224 | integer :: iter 225 | real(dp) :: a, b, x0, x, fx 226 | a = 0.6_dp 227 | b = 0.8_dp 228 | call bisect(a,b,x,fx,iter) 229 | write(*,201) x,fx,iter 230 | x0 = 0.6_dp 231 | call picard(x0,x,fx,iter) 232 | write(*,202) x,fx,iter 233 | call newton_raphson(x0,x,fx,iter) 234 | write(*,203) x,fx,iter 235 | call secant(a,b,x,fx,iter) 236 | write(*,204) x,fx,iter 237 | call ridder(a,b,x,fx,iter) 238 | write(*,205) x,fx,iter 239 | 201 format(/,T4,'Result by bisection:',/, & 240 | 3x,'x=',3x,F15.10,/, & 241 | 3x,'f(x)',1x,F15.10,/, & 242 | 3x,'iter=',I5) 243 | 202 format(/,T4,'Result by Picard:',/, & 244 | 3x,'x=',3x,F15.10,/, & 245 | 3x,'f(x)',1x,F15.10,/, & 246 | 3x,'iter=',I5) 247 | 203 format(/,T4,'Result by Newton-Raphson :',/, & 248 | 3x,'x=',3x,F15.10,/, & 249 | 3x,'f(x)',1x,F15.10,/, & 250 | 3x,'iter=',I5) 251 | 204 format(/,T4,'Result by secant :',/, & 252 | 3x,'x=',3x,F15.10,/, & 253 | 3x,'f(x)',1x,F15.10,/, & 254 | 3x,'iter=',I5) 255 | 256 | 205 format(/,T4,'Result by ridder :',/, & 257 | 3x,'x=',3x,F15.10,/, & 258 | 3x,'f(x)',1x,F15.10,/, & 259 | 3x,'iter=',I5) 260 | end program main 261 | !******************************************************************************* 262 | --------------------------------------------------------------------------------