Section 1.8 Example 2: Quadratic Equation#
Adapted from: “Guide to Fortran 2008 Programming” by Walter S. Brainerd (Springer 2015)
Program to compute the roots of a quadratic Equation using the quadratic formula#
program quadratic_equation_solver
! Calculates and prints the roots
! of a quadratic equation
implicit none
! Variables
! a, b, c: coefficients
! x1, x2: roots
real :: a, b, c, x1, x2, x1_smaller, x2_smaller
real :: difference, percentage
complex :: z1, z2
real :: discriminant
print *
write (*, '(a)') "***** Quadratic Equation Solver *****"
print *
! For the Jupyter Notebook, we will pipe the coefficients from the command line
! Read the coefficients
!print *, "Enter a, the coefficient of x ** 2 -->"
!read *, a
!print *, "Enter b, the coefficient of x -->"
!read *, b
!print *, "Enter c, the constant term -->"
!read *, c
! The piped output from an echo statement will be processed by the line below
read *, a, b, c
write (*, '(a)') "The read in coefficients are:"
write (*, '(3 (a, f8.3))') "a = ", a, " b = ", b, " c = ", c
print * ! skip a line on the screen
if (a == 1) then
write (*, '(a, f6.3, a, f5.3)' ) "This program will solve the quadratic equation x^2 ", b, "x + ", + c
else if ((a /= 1) .and. (b > 0)) then
write (*, '(a, f5.3, a, f6.3, a, f5.3)') "This program will solve the quadratic equation ", a, "x^2 +", b, "x + ", c
else if ((a /= 1) .and. (b < 0)) then
write (*, '(a, f5.3, a, f6.3, a, f5.3)') "This program will sovle the quadratic equation ", a, "x^2 ", b, "x + ", c
end if
print * ! skip a line on the screen
if ((a == 0) .and. (b == 0)) then
! Handle impossible case a and b both equal to zero
write (*, '(a)') "Coefficients of a and b cannot both be zero!"
else if ((a == 0) .and. (b /= 0)) then
! Handle linear case
x1 = -c / b
x2 = x1
! Print the roots
write (*, '(a)') "Linear case: the root is:"
write (*, '(a)') "x = ", x1
else if ((a /= 0) .and. (b /= 0)) then
! Handle 2nd order cases by first calculating the discriminant
!print * ! kips a line on the screen
discriminant = ((b ** 2) - (4 * a * c))
write (*, '(a, f8.3)') "The discriminant = ", discriminant
print * ! skip a line on the screen
if (discriminant > 0) then
! Calculate real, non-degenerate roots by the quadratic formula
write (*, '(a)') "Roots are real and non-degenerate..."
x1 = (-b + sqrt(discriminant)) / (2 * a)
x2 = (-b - sqrt(discriminant)) / (2 * a)
else if (discriminant == 0) then
! Calculate real, degenerate roots by the quadratic formula
write (*, '(a)') "Roots are real and degenerate..."
x1 = (-b + sqrt(discriminant)) / (2 * a)
x2 = x1
else if (discriminant < 0) then
write (*, '(a)') "Roots are complex"
x1 = 0
x2 = 0
z1 = (-b + sqrt (cmplx (discriminant))) / (2 * a)
z2 = (-b - sqrt (cmplx (discriminant))) / (2 * a)
end if
! Calculate the smaller root using x1 = c / (a * x2) and taking abs value
if (abs(x1) < abs(x2)) then
x1_smaller = abs(c / (a * x2))
difference = abs(x1)- x1_smaller
percentage = (difference / x1_smaller) * 100
else if (abs(x1) > abs(x2)) then
x2_smaller = abs(c / (a * x1))
difference = abs(x2) - x2_smaller
percentage = (difference / x2_smaller) * 100
else if (abs(x1) == abs(x2)) then
x1_smaller = abs (c / (a * x2))
x2_smaller = x1_smaller
difference = 0
percentage = 0
end if
! Print the roots
if (discriminant >= 0) then
print * ! skip a line on the screen
write (*, '(a)') "The roots are (using just sqrt):"
write (*, '(a, f6.3)') "x1 = ", x1
write (*, '(a, f6.3)') "x2 = ", x2
print * ! skip a line on the screen
! ************
! ************
write (*, '(a)') "The absolute value of the smaller root according to x2 = c/ax1 is:"
if (abs(x1) <= abs(x2)) then
write (*, '(a, f5.3)') "x1 = ", x1_smaller
else if (abs(x1) >= abs(x2)) then
write (*, '(a, f5.3)') "x2 = ", x2_smaller
end if
! ************
print * ! skip a line on the screen
write (*, '(a, f5.3)') "The difference is: ", difference
write (*, '(a, f5.3, a)') "The percentage difference is: ", percentage, "%"
! ************
else if (discriminant < 0) then
print * ! skip a line on the screen
write (*, '(a)') "The roots are (using sqrt and cmplx):"
write (*, '(a, f6.3, a, f5.3, a)') "z1 = ", real(z1), " +", aimag(z1), "i"
write (*, '(a, f6.3, a, f6.3, a)') "z2 = ", real(z2), " ", aimag(z2), "i"
end if
end if
end program quadratic_equation_solver
The following explanation is given by “Code Copilot” within ChatGPT 4.
The Fortran program quadratic_equation_solver
calculates and prints the roots of a quadratic equation of the form \(ax^2 + bx + c = 0\). The program is structured to handle different scenarios based on the values of the coefficients \(a\), \(b\), and \(c\). Here is a detailed explanation of its functionality:
Initial Setup and Input Reading#
The program starts with an introductory message to the user.
It reads the coefficients \(a\), \(b\), and \(c\) from the standard input. In the commented section, there’s an indication that in an interactive environment like Jupyter Notebook, these values would be piped directly from the command line.
Handling Different Quadratic Forms#
The program first checks if \(a\) equals 1 or not and formats the display of the quadratic equation accordingly. It accounts for both positive and negative \(b\) values.
Error Handling and Special Cases#
The program checks if both \(a\) and \(b\) are zero, which is not a valid state for a quadratic equation and prints an error message.
If \(a\) is zero but \(b\) is not, the equation is linear, not quadratic. It then calculates the root as \(-c/b\) and prints it.
Discriminant Calculation and Root Analysis#
The program calculates the discriminant \(\Delta = b^2 - 4ac\). This value determines the nature of the roots:
Positive Discriminant: Indicates two distinct real roots. The roots are calculated using the quadratic formula.
Zero Discriminant: Indicates a single repeated real root.
Negative Discriminant: Indicates complex roots. The program computes these using Fortran’s complex number handling capabilities.
Additional Calculations and Output#
The program includes logic to compute which root is smaller and attempts to verify this using a derived formula \(x = c/(ax_2)\) (however, this formula seems contextually misplaced for quadratic equations).
It calculates the percentage difference between the computed smaller root and the derived value, presumably to check the accuracy or stability of the numerical computations.
Final Output#
Depending on the discriminant, the program prints:
The real roots or the single real root and the calculations regarding the smaller root verification.
The complex roots if applicable.
Error Handling and Special Case Checks#
The program has checks for unusual or special input values to ensure robustness, like when both \(a\) and \(b\) are zero.
Conclusion#
This Fortran program is comprehensive in handling the different scenarios encountered when solving quadratic equations. It not only provides the roots based on the discriminant but also includes checks for special cases, such as non-quadratic conditions (linear equation) and invalid inputs. Additionally, the extra calculations for verifying the smaller root’s computation add an interesting layer of numerical analysis.
Program Compilation and Execution#
The above program is compiled and run using Fortran Package Manager (fpm):
import os
root_dir = os.getcwd()
code_dir = root_dir + "/" + "Fortran_Code/Section_1_8_Ex_2_Quadratic_Formula"
os.chdir(code_dir)
build_status = os.system("fpm build 2>/dev/null")
Find the roots for the equation
#
exec_status = os.system("echo '1 3 2' | fpm run 2>/dev/null")
***** Quadratic Equation Solver *****
The read in coefficients are:
a = 1.000 b = 3.000 c = 2.000
This program will solve the quadratic equation x^2 3.000x + 2.000
The discriminant = 1.000
Roots are real and non-degenerate...
The roots are (using just sqrt):
x1 = -1.000
x2 = -2.000
The absolute value of the smaller root according to x2 = c/ax1 is:
x1 = 1.000
The difference is: 0.000
The percentage difference is: 0.000%
Find the roots for the equation
#
exec_status = os.system("echo '1 2 1' | fpm run 2>/dev/null")
***** Quadratic Equation Solver *****
The read in coefficients are:
a = 1.000 b = 2.000 c = 1.000
This program will solve the quadratic equation x^2 2.000x + 1.000
The discriminant = 0.000
Roots are real and degenerate...
The roots are (using just sqrt):
x1 = -1.000
x2 = -1.000
The absolute value of the smaller root according to x2 = c/ax1 is:
x1 = 1.000
The difference is: 0.000
The percentage difference is: 0.000%
Find the roots for the equation
#
exec_status = os.system("echo '1 5 9' | fpm run 2>/dev/null")
***** Quadratic Equation Solver *****
The read in coefficients are:
a = 1.000 b = 5.000 c = 9.000
This program will solve the quadratic equation x^2 5.000x + 9.000
The discriminant = -11.000
Roots are complex
The roots are (using sqrt and cmplx):
z1 = -2.500 +1.658i
z2 = -2.500 -1.658i
Find the roots for the equation
#
exec_status = os.system("echo '1 6 1' | fpm run 2>/dev/null")
***** Quadratic Equation Solver *****
The read in coefficients are:
a = 1.000 b = 6.000 c = 1.000
This program will solve the quadratic equation x^2 6.000x + 1.000
The discriminant = 32.000
Roots are real and non-degenerate...
The roots are (using just sqrt):
x1 = -0.172
x2 = -5.828
The absolute value of the smaller root according to x2 = c/ax1 is:
x1 = 0.172
The difference is: 0.000
The percentage difference is: 0.000%