Ordinary differential equations · Lecture 22

ODEs II: Runge–Kutta and Predictor–Corrector Methods

Fourth-order accuracy from values of ff alone (Runge–Kutta), reusing past slopes (Milne and Adams–Bashforth–Moulton), systems of equations, and the stability limits that decide which method survives a stiff problem.

Md Mahbub E Noor · Assistant Professor
CSE-3107 Numerical Methods · B.Sc. 3rd Year 1st Semester
Department of CSE, University of Barishal

Why this lecture

The problem: a spring that must not gain energy

A mass on a spring: position xx, velocity yy. Without friction it should oscillate for ever with the same energy x2+y2=1x^2 + y^2 = 1.

  • Equations: x′=yx' = y,   y′=−x\;y' = -x, start (1,0)(1, 0): two unknowns, a system
  • Euler, h=0.1h = 0.1, ten periods: energy grows from 1 to 517; the mass flies off
  • Heun: 1.016 (better, still drifting)
  • Orbits, circuits, molecules and epidemics need methods that stay accurate over thousands of steps
method (h=0.1h = 0.1)energy after 10 periods
exact1
Euler517.4
Heun1.0158
RK4?
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
2 / 25

Today's goals

  • Derive the idea of Runge–Kutta methods and apply RK4 by hand and in code
  • Solve systems and second-order equations by the same methods
  • Apply Milne's and Adams–Bashforth–Moulton predictor–corrector methods
  • Explain stability, stiff equations and why implicit methods exist
  • Choose a solver for a given problem
Last time

Euler (order 1) and Heun (order 2); instability when hh is too large.


Today

Higher order with more slopes per step, or with slopes from earlier steps.

Ordinary differential equations · you are here
L21 · ODEs I→L22 · ODEs II
Builds on: L16, L20, L21
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
3 / 25
Start here

The idea in one picture

xyxₙxₙ + h/2xₙ + htrue solutionk₁: slope at the startk₂: slope at the middlek₃: middle againk₄: slope at the endone step with the average slope (k₁ + 2k₂ + 2k₃ + k₄)/6Euler lands at 2.00RK4: 2.708
Euler used one slope, measured only at the start of the step.RK4 samples four slopes. k₁: the slope at the start.k₂: the slope at the middle of the step, reached using k₁.k₃: the middle again, reached using the better slope k₂.k₄: the slope at the end, reached using k₃.Take one step with a weighted average: the middle slopes count double.Result 2.708 against the true 2.718. Euler with the same step: 2.00.
In plain words
  • Euler uses the slope at the start only, so it drifts
  • Runge–Kutta samples the slope at several places inside the step
  • A weighted average of those slopes is far more accurate
New words today
k₁ … k₄
the four sampled slopes
RK4
the fourth-order Runge–Kutta method
predictor–corrector
guess the next value, then improve it
stability
errors stay bounded instead of exploding
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
4 / 25

The Runge–Kutta idea: average several slopes inside the step

Second order: two slopes, weights chosen to match Taylor up to h²k1=hf(xn,yn),k2=hf(xn+ah, yn+ak1)yn+1=yn+(1−12a)k1+12ak2\begin{aligned} k_1 &= hf(x_n, y_n), \qquad k_2 = hf(x_n + ah,\, y_n + ak_1) \\ y_{n+1} &= y_n + \Big(1 - \tfrac{1}{2a}\Big)k_1 + \tfrac{1}{2a}k_2 \end{aligned}
Two members of the familya=1:    yn+1=yn+12(k1+k2)    (Heun)a=12:    yn+1=yn+k2    (midpoint)\begin{aligned} a = 1:&\;\; y_{n+1} = y_n + \tfrac12(k_1 + k_2) \;\;(\text{Heun}) \\ a = \tfrac12:&\;\; y_{n+1} = y_n + k_2 \;\;(\text{midpoint}) \end{aligned}
  • Same accuracy as the Taylor method of order 2, but no derivatives of ff
  • Each kk is a trial slope × hh; later slopes use earlier ones
  • Matching more Taylor terms needs more slopes: four slopes give order 4
  • Heun from Lecture 21 is RK2
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
5 / 25

The classical fourth-order Runge–Kutta method (RK4)

Four slopes per stepk1=hf(xn,yn)k2=hf(xn+h2, yn+k12)k3=hf(xn+h2, yn+k22)k4=hf(xn+h, yn+k3)\begin{aligned} k_1 &= hf(x_n, y_n) & k_2 &= hf\big(x_n + \tfrac h2,\, y_n + \tfrac{k_1}{2}\big) \\ k_3 &= hf\big(x_n + \tfrac h2,\, y_n + \tfrac{k_2}{2}\big) & k_4 &= hf(x_n + h,\, y_n + k_3) \end{aligned}
Weighted average: weights 1, 2, 2, 1yn+1=yn+16(k1+2k2+2k3+k4),global error O(h4)y_{n+1} = y_n + \tfrac16\big(k_1 + 2k_2 + 2k_3 + k_4\big), \qquad \text{global error } O(h^4)
  • Slopes at the start, twice at the middle, at the end
  • Weights 1, 2, 2, 1 = Simpson's 1, 4, 1 with the middle split in two (Lecture 20)
  • Halve hh: error ÷16\div 16
  • Four evaluations per step, but huge steps are allowed: the workhorse of scientific computing
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
6 / 25
The method, step by step

RK4, step by step

  1. k1=h f(xn,yn)k_1 = h\,f(x_n, y_n): slope at the start
  2. k2=h f(xn+h/2,  yn+k1/2)k_2 = h\,f(x_n + h/2,\; y_n + k_1/2): midpoint, using k1k_1
  3. k3=h f(xn+h/2,  yn+k2/2)k_3 = h\,f(x_n + h/2,\; y_n + k_2/2): midpoint again, using k2k_2
  4. k4=h f(xn+h,  yn+k3)k_4 = h\,f(x_n + h,\; y_n + k_3): end point, using k3k_3
  5. yn+1=yn+(k1+2k2+2k3+k4)/6y_{n+1} = y_n + (k_1 + 2k_2 + 2k_3 + k_4)/6;   xn+1=xn+h\;x_{n+1} = x_n + h; repeat

Works unchanged for systems if yy and the kk's are vectors.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
7 / 25

Problem 1: one RK4 step for y′=x+yy' = x + y, y(0)=1y(0) = 1, h=0.1h = 0.1

Compute y(0.1)y(0.1) by RK4 and compare with the exact value 2e0.1−1.12e^{0.1} - 1.1.
1
k1=0.1(0+1)=0.1k_1 = 0.1(0 + 1) = 0.1
2
k2=0.1(0.05+1+0.05)=0.11k_2 = 0.1\big(0.05 + 1 + 0.05\big) = 0.11
3
k3=0.1(0.05+1+0.055)=0.1105k_3 = 0.1\big(0.05 + 1 + 0.055\big) = 0.1105
4
k4=0.1(0.1+1+0.1105)=0.12105k_4 = 0.1\big(0.1 + 1 + 0.1105\big) = 0.12105
5
y1=1+16(0.1+0.22+0.221+0.12105)=1.1103417y_1 = 1 + \tfrac16(0.1 + 0.22 + 0.221 + 0.12105) = 1.1103417
Exact 1.11034181.1103418: RK4 is correct to 7 digits after one step (Euler: 1.1, Heun: 1.11).
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
8 / 25

Explore: Euler, Heun and RK4 side by side

  • With h=0.2h = 0.2 RK4 sits on the exact curve; Euler falls far behind
  • Halve hh and compare how fast each error falls (2, 4, 16)
  • Periodic example y′=ycos⁡xy' = y\cos x: RK4 stays on track with h=0.5h = 0.5
  • Logistic growth: the S-curve of populations and of sigmoid units
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
9 / 25

Systems and higher-order equations

Several unknowns: the same formulas with vectorsy′=F(x,y),k1=hF(xn,yn),  …yn+1=yn+16(k1+2k2+2k3+k4)\begin{aligned} \mathbf{y}' &= \mathbf{F}(x, \mathbf{y}), \qquad \mathbf{k}_1 = h\mathbf{F}(x_n, \mathbf{y}_n), \;\dots \\ \mathbf{y}_{n+1} &= \mathbf{y}_n + \tfrac16(\mathbf{k}_1 + 2\mathbf{k}_2 + 2\mathbf{k}_3 + \mathbf{k}_4) \end{aligned}
A second-order equation becomes a first-order systemy′′=g(x,y,y′)  ⟹  u′=v,    v′=g(x,u,v)y'' = g(x, y, y') \;\Longrightarrow\; u' = v,\;\; v' = g(x, u, v)
  • Spring x′′=−xx'' = -x: x′=yx' = y, y′=−xy' = -x
  • Pendulum θ′′=−gLsin⁡θ\theta'' = -\tfrac gL\sin\theta: no closed-form solution for large swings
  • Compute all components of k1\mathbf{k}_1 before any of k2\mathbf{k}_2
  • Every ODE solver library works with systems in this form
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
10 / 25

Explore: systems in the phase plane

  • Left: the path in the (x,y)(x, y) plane; right: x(t)x(t) and y(t)y(t)
  • Euler on the spring spirals outwards; RK4 stays on the circle
  • Predator–prey: the conserved quantity tests the solver
  • Switch methods and step sizes and watch the "conserved quantity" line
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
11 / 25

Predictor–corrector methods: reuse earlier slopes

Milne: predictor (open Newton–Cotes) and corrector (Simpson's rule)yn+1P=yn−3+4h3(2fn−fn−1+2fn−2)yn+1C=yn−1+h3(fn−1+4fn+fn+1)\begin{aligned} y^{P}_{n+1} &= y_{n-3} + \frac{4h}{3}\big(2f_n - f_{n-1} + 2f_{n-2}\big) \\ y^{C}_{n+1} &= y_{n-1} + \frac h3\big(f_{n-1} + 4f_n + f_{n+1}\big) \end{aligned}
Adams–Bashforth (predictor) and Adams–Moulton (corrector), fourth orderyn+1P=yn+h24(55fn−59fn−1+37fn−2−9fn−3)yn+1C=yn+h24(9fn+1+19fn−5fn−1+fn−2)\begin{aligned} y^{P}_{n+1} &= y_n + \frac{h}{24}\big(55f_n - 59f_{n-1} + 37f_{n-2} - 9f_{n-3}\big) \\ y^{C}_{n+1} &= y_n + \frac{h}{24}\big(9f_{n+1} + 19f_n - 5f_{n-1} + f_{n-2}\big) \end{aligned}
  • fk=f(xk,yk)f_k = f(x_k, y_k) are slopes already computed: about 2 new evaluations per step (RK4 needs 4)
  • Not self-starting: the first 3 steps come from RK4
  • Predictor − corrector difference estimates the error for free
  • Milne can be unstable for decaying solutions; Adams is the standard choice
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
12 / 25
The method, step by step

A predictor–corrector method, step by step

  1. Get y0,y1,y2,y3y_0, y_1, y_2, y_3 (starting values) by RK4; compute f0,…,f3f_0, \dots, f_3
  2. Predict yn+1Py^{P}_{n+1} with the predictor formula
  3. Evaluate fn+1P=f(xn+1,yn+1P)f^{P}_{n+1} = f(x_{n+1}, y^{P}_{n+1})
  4. Correct: yn+1Cy^{C}_{n+1} with the corrector formula (optionally repeat steps 3–4 once)
  5. Store fn+1=f(xn+1,yn+1C)f_{n+1} = f(x_{n+1}, y^{C}_{n+1}), shift the window of four slopes, repeat

Two new ff values per step; the error estimate costs nothing.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
13 / 25

Problem 2: Milne and Adams for y′=x+yy' = x + y at x=0.4x = 0.4

Starting values from RK4 (h=0.1h = 0.1): y0=1y_0 = 1, y1=1.110342y_1 = 1.110342, y2=1.242805y_2 = 1.242805, y3=1.399717y_3 = 1.399717. Find y(0.4)y(0.4) by Milne's and by Adams' method.
quantityMilneAdams–Bashforth–Moulton
slopes f0,f1,f2,f3f_0, f_1, f_2, f_31, 1.210342, 1.442805, 1.699717same
predictor1+0.43(2.420684−1.442805+3.399434)=1.5836421 + \tfrac{0.4}{3}(2.420684 - 1.442805 + 3.399434) = 1.5836421.399717+0.124(…)=1.5836401.399717 + \tfrac{0.1}{24}(\ldots) = 1.583640
fP=0.4+yPf^{P} = 0.4 + y^{P}1.9836421.983640
corrector1.242805+0.13(1.442805+6.798868+1.983642)=1.5836491.242805 + \tfrac{0.1}{3}(1.442805 + 6.798868 + 1.983642) = 1.5836491.399717+0.124(…)=1.5836491.399717 + \tfrac{0.1}{24}(\ldots) = 1.583649
exact 2e0.4−1.42e^{0.4} - 1.41.5836491.583649

Both correctors agree with the exact value to 6 decimals, using only 2 new evaluations of ff (RK4 would use 4).

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
14 / 25

Stability and stiff equations

Test equation y′ = λy; amplification factor per step, z = hλEuler: yn+1=(1+z) ynRK4: yn+1=(1+z+z22+z36+z424)yn\begin{aligned} \text{Euler: } y_{n+1} &= (1 + z)\,y_n \\ \text{RK4: } y_{n+1} &= \Big(1 + z + \frac{z^2}{2} + \frac{z^3}{6} + \frac{z^4}{24}\Big)y_n \end{aligned}
Implicit (backward) Euler: stable for every h > 0 when λ < 0yn+1=yn+h f(xn+1,yn+1)  ⇒  yn+1=yn1−zy_{n+1} = y_n + h\,f(x_{n+1}, y_{n+1}) \;\Rightarrow\; y_{n+1} = \frac{y_n}{1 - z}
  • Stable when |factor| ≤ 1: Euler needs −2≤hλ≤0-2 \le h\lambda \le 0; RK4 about −2.79≤hλ-2.79 \le h\lambda
  • Stiff: a fast decaying part (large ∣λ∣|\lambda|) forces a tiny hh even after it has died out
  • Implicit methods solve an equation each step (Newton, Lecture 9–10) but take large steps safely
  • Milne's corrector has a parasitic root of size >1> 1: errors grow for decaying solutions
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
15 / 25
Classical vs numerical

Same kind of system, two approaches

Calculus

Classical (solve exactly)

  • Spring x′′=−xx'' = -x: characteristic roots ±i\pm i
  • x=cos⁡tx = \cos t, y=−sin⁡ty = -\sin t
  • Energy exactly 1 for ever
vs
Algorithm

Numerical (RK4, h=0.1h = 0.1)

  • 628 steps over ten periods
  • Largest error in xx: 5×10−55\times10^{-5}
  • Energy 0.999991 (Euler: 517)
When the classical approach cannot work

An epidemic (SIR model): S′=−0.3SIS' = -0.3SI,   I′=0.3SI−0.1I\;I' = 0.3SI - 0.1I

No formula gives I(t)I(t). RK4 with a step of one day: the infected fraction peaks at 30.4% on day 27, and about 94% of people are eventually infected. This is how epidemic forecasts were computed in 2020.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
16 / 25

RK4 for a single equation and for a system

  • A reusable rk4_step for y′=f(x,y)y' = f(x, y)
  • The same steps for the spring system (x,y)(x, y)
  • Compares the energy after 10 periods with Euler
  • Lab: Adams–Bashforth–Moulton and the epidemic model
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
17 / 25
When explicit methods break

Limitations shown failing

  • Stiff: y′=−50(y−cos⁡x)y' = -50(y - \cos x) follows cos⁡x\cos x smoothly, yet RK4 explodes for h=0.06h = 0.06 (hλ=−3<−2.79h\lambda = -3 < -2.79)
  • Euler already fails at h=0.05h = 0.05; backward Euler is fine even with h=0.1h = 0.1
  • Singularities: y′=y2y' = y^2 blows up at x=1x = 1; a fixed-step method steps right past it
  • Fixed hh wastes work where the solution is smooth: real solvers adapt hh
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
18 / 25
Practice

Practice problem

Problem 3"Use the fourth-order Runge–Kutta method to find y(0.1)y(0.1) and y(0.2)y(0.2) for dydx=y−x\dfrac{dy}{dx} = y - x, y(0)=2y(0) = 2, with h=0.1h = 0.1."
How to write a complete answer
  • Write the four formulas and say whether the kk's include hh
  • Step 1: k1=0.2k_1 = 0.2, k2=0.205k_2 = 0.205, k3=0.20525k_3 = 0.20525, k4=0.210525k_4 = 0.210525;   y1=2.205171\;y_1 = 2.205171
  • Step 2 from (0.1,2.205171)(0.1, 2.205171): y2=2.421403y_2 = 2.421403
  • Compare with the exact e0.2+1.2=2.421403e^{0.2} + 1.2 = 2.421403: correct to 6 decimals; give a one-line comparison with Euler (2.41) and modified Euler (2.421025)
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
19 / 25
When to use it

Runge–Kutta and predictor–corrector methods: method profile

Best case
  • RK4: smooth non-stiff problems; 6–8 digits with moderate hh; self-starting, easy step changes
  • Adams–Bashforth–Moulton: expensive ff (2 evaluations per step) with a free error estimate
  • Systems of any size, written once in vector form
Worst case
  • Stiff problems: explicit methods need tiny steps
  • Milne for decaying solutions: unstable
  • Solutions with singularities or sudden jumps (fixed hh)
Best suited for
  • Orbits, mechanics, circuits, chemical kinetics (non-stiff), epidemics
  • Adaptive pairs (RK45 / Dormand–Prince) in SciPy and MATLAB
  • Multistep methods in long simulations where ff is costly
Avoid when
  • Stiff systems (use implicit methods: backward Euler, BDF, Radau)
  • Very long Hamiltonian simulations (use symplectic integrators)
  • Fixed hh when the solution changes scale (use adaptive step size)

Rule of thumb: start with an adaptive RK (RK45); if it takes absurdly small steps, the problem is stiff: switch to an implicit solver.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
20 / 25

Comparative analysis: ODE methods

MethodOrderff per stepSelf-starting?Stability (hλh\lambda real)Error at x=1x = 1 (y′=x+yy' = x+y, h=0.1h = 0.1)
Euler11yes[−2,0][-2, 0]0.249
Heun / RK222yes[−2,0][-2, 0]8.4×10−38.4\times10^{-3}
RK444yes[−2.79,0][-2.79, 0]4.2×10−64.2\times10^{-6}
Milne P–C42no (needs RK4 start)weakly unstable6×10−76\times10^{-7}
Adams–Bashforth–Moulton42no (needs RK4 start)about [−1.25,0][-1.25, 0]3.6×10−63.6\times10^{-6}
Backward Euler (implicit)11 + equation solveyesall hλ<0h\lambda < 00.30

No method wins everywhere: RK4 for general use, Adams when ff is expensive, implicit methods when the problem is stiff.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
21 / 25
Roadmap

End of Module 6: from solving to fitting

We can now simulate models. The last module asks the reverse question: given data, which model and which parameters?

What it does well (keep this)
  • RK4: order 4 from function values alone
  • Systems and higher-order equations
  • Predictor–corrector with a free error estimate
  • Stability limits and stiffness
LimitationHow it is overcomeWhere
Model parameters (e.g. β\beta, γ\gamma of an epidemic) are unknown
→
Fit them to data: least squares
Lecture 23 →
Choosing a model that fits without overfitting
→
Polynomial, exponential fits; validation
Lecture 24 →
Training is itself an ODE: w′=−∇L(w)w' = -\nabla L(w)
→
Gradient descent = Euler on the gradient flow
Lecture 25 →
Step size too large makes training explode
→
Learning rate vs stability (today's ∣1+hλ∣<1|1 + h\lambda| < 1)
Lecture 25 →
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
22 / 25
Applications

Where this method runs in the real world

Click a card to see an RK or multistep solver in action.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
23 / 25

Checkpoint

Checkpoint · think, then discuss with your neighbourRK4 for y′=yy' = y, y(0)=1y(0) = 1, h=0.1h = 0.1: k1=0.1k_1 = 0.1. What is k2k_2?
A0.1050.105
B0.110.11
C0.10.1
D0.11050.1105
A. k2=hf(y0+k1/2)=0.1(1+0.05)=0.105k_2 = hf(y_0 + k_1/2) = 0.1(1 + 0.05) = 0.105. Then k3=0.10525k_3 = 0.10525, k4=0.110525k_4 = 0.110525, y1=1.1051708y_1 = 1.1051708 (exact e0.1=1.1051709e^{0.1} = 1.1051709).
Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
24 / 25

Summary

Key points
  • RK4: k1,…,k4k_1, \dots, k_4 at start, middle, middle, end; yn+1=yn+16(k1+2k2+2k3+k4)y_{n+1} = y_n + \frac16(k_1 + 2k_2 + 2k_3 + k_4); order 4
  • Systems: same formulas with vectors; y′′=gy'' = g becomes u′=vu' = v, v′=gv' = g
  • Milne and Adams–Bashforth–Moulton: predictor + corrector from past slopes, 2 evaluations per step, need RK4 starting values
  • Stability: ∣|amplification∣≤1| \le 1; stiff problems need implicit methods
Opening problem: solved

RK4 with h=0.1h = 0.1 keeps the spring's energy at 0.999991 after ten periods (Euler: 517, Heun: 1.016). The largest position error is 5×10−55\times10^{-5}.

Homework
  1. Use RK4 with h=0.1h = 0.1 to find y(0.2)y(0.2) for y′=x2+y2y' = x^2 + y^2, y(0)=1y(0) = 1.
  2. Write y′′+0.5y′+4y=0y'' + 0.5y' + 4y = 0, y(0)=1y(0) = 1, y′(0)=0y'(0) = 0 as a system and take one RK4 step with h=0.1h = 0.1.
  3. Using the RK4 values of Problem 3 at x=0,0.1,0.2,0.3x = 0, 0.1, 0.2, 0.3, find y(0.4)y(0.4) by the Adams–Bashforth–Moulton method.
  4. For y′=−100yy' = -100y, find the largest stable hh for Euler and for RK4. Check in the lab.
Next lecture

Module 7: least squares and linear regression. From solving models to fitting them to data, the core of machine learning.

Md Mahbub E Noor
Lecture 22: ODEs II: Runge–Kutta, Milne, Adams
University of Barishal
25 / 25