Conditional Control Flow Constructs

Sequential Control Flow

      Execution order follows the textual order

 

      straight line flow

 

      Many simple problems can not be solved only with such sequential flow

 

      Here is an example

 

      Problem: Computation of a maximum of two numbers

Solution

Program max2

Implicit none

integer num1,num2, max

read *, num1,num2

if (num1 > num2) then

!control comes here if num1 > num2

     max = num1

!control jumps to the end of the if statement (endif)

 

else  !control comes here if num1 < = num2

     max = num2

endif

print *, max

end program max2

Another Problem

      Input two numbers

      Compute the quotient and remainder of  the bigger number divided by the smaller number

      The numbers are input in unknown order

Solution

Program Quo_Rem1

Implicit none

integer num1,num2, quotient, remainder

read *, num1,num2

if (num1 > num2) then

   quotient = num1/num2     ! / is integer division

    remainder = num1 (quotient * num2)

else

   quotient = num2/num1

   remainder = num2 (quotient * num1)

endif

print *, quotient, remainder

end program Quo_Rem1

Problems with the solution

What happens if num1 or num2 is negative?

 

   Problem Specification needs to be clarified

 

What if one of the numbers is 0?

 

   Divide by zero leads to overflow

   Should be avoided

   need to test it before dividing

Program Quo_Rem2

     integer::  num1,num2, temp, quotient, reminder
read *, num1,num2
if (abs(num1) < abs(num2)) then
! abs function returns the absolute value
    temp = num2
    num2 = num1 ! swapping the contents

        num1 = temp  ! of num1 and num2
end if
if (.not.(num2 == 0)) then
!num2 contains a nonzero value
    quotient = num1/num2
     remainder = num1 - quotient * num2
     print *, quotient, remainder
else
     print *,"cannot divide! one of the numbers is zero"
end if

The program Quo_Rem2

      The body of if-then-else is simpler

 

      The else clause is missing

 

      Complex conditions can appear in the if-condition

 

      Successive if-statements allowed

Another Problem

      %Nesting of ifs
Problem: Compute Maximum of three numbers

Solution: ?

 

A Strategy

 

Let num1,num2,num3 store the three numbers.

 

      Compute the maximum of num1 and num2. Name it max12

      Compute the maximum of num2 and num3. Name it max23

      Compute the maximum of max12 and max23, which is the maximum of num1.num2,num3

 

Another Strategy

      Compute the maximum of num1 and num2, say max12

      Compute the maximum of max12 and num3, which is the required maximum?

 

Which is the better strategy?

      The latter - less number of steps

 

    Now we are ready to write the program

Program max3

     integer num1,num2,num3,max
read *, num1,num2,num3
if (num1 > num2) then
   if (num1 > num3) then !num1 > num2,num1 > num3
      max = num1
   else ! num1 > num2 and num1 <= num3
      max = num3
  endif
elseif (num2 > num3) then !num1 <=num2 > num3
          max = num2
else ! num1 <=num2<=num3
   max = num3
endif
print *, max
end program max2

Nested If statements

      If statements in the then clause or else clause

 

      elseif construct

 

      Arbitrary series of nesting permitted

 

      elseif and else corresponds to the innermost if for which the endif is yet to come

 

      if  and endif are like left and right brackets.

Further Observations

      else clause can be missing

 

      endif can be dropped if there is only one statement

 

      long series of ifs can be confusing (at most 20 levels allowed)

 

      indentation improves readability

 

      use indentation and comments

If conditions

      Control flow branches in conditional statements

      Branching decided by evaluating the conditions

      conditions are expressions of a new type called LOGICAL

      Examples:

          (x > 0), (z == 1), .NOT. (num == 2)

      All these involve relational operators: >,==

      Relational operators are defined over many data types to compare values

Relations over Arithmetic

      Given e1,e2 expressions over integer (or real),

   e1 == e2  ( equality )

   e1  <  e2  ( less than )

   e1 <= e2  ( less than or equal )

   e1  >  e2  ( greater than )

   e1 >= e2  ( greater than or equal )

   e1  /=  e2  ( not equal )

 

 

LOGICAL VARIABLES

      Fortran 90 has a built in LOGICAL DATA TYPE

      Expressions involving relational operators are of type LOGICAL

      Variables can be declared to have type LOGICAL

      Declarations:

                   LOGICAL ::  found, goodness

      Logical variables assume just two values

   .TRUE.,     .FALSE.

      They can be used in if conditions, eg.

     if (found) then stop

   if (goodness) then x = 0

LOGICAL OPERATORS

      Operators over logical type values

      They are

              .not., .and., .or., .eqv., .neqv.

 

      .not. p is .true.       iff   p is .false.

 

       p .and. q is .true.  iff   both p and q are .false.

 

      p .or. q is .true.     iff    one of (or both) p,q  .true.

      p .eqv. q is .true.   iff   both p and q has the same

                                        truth value

      p .neqv. q is .true. iff   both p and q have different

                                        truth values

Operator precedence

      A general logical expression may include arithmetic, relational and logical operators

 

      operator precedence defined to specify order of evaluation

 

      arithmetic operators are evaluated first followed by relational operators

 

      logical operators are evaluated last

 

      precedence amongst logical operators

          .not. , .and. ,  .or. ,  .eqv. and .neqv.

If condition

      The condition in an `if' statement is a logical expressions, eg.

 

1. if ((a>=b) .eqv. x) then ...

 

-     a,b arithmetic variables,  x logical variable

 

2.  if (((rate*prin)> 100) .AND. .NOT. (closed)) then ...

Quadratic Equation Solving

      Roots of quadratic equation:

                   ax2  + bx + c = 0

 

      Can have

   exactly one root

   two real roots

   two complex conjugate roots

 

      Type of roots depends upon the discriminant

                     (b2  - 4ac)

A Program to solve the equation

    program quadratic
implicit none
real :: a, b, c, disc, x_r, x_r1, x_r2, x_im1, x_im2
real, parameter :: eps = 1.0e-6
read *, a, b, c

if (a == 0.0) then
   ! a is 0, not a quadratic equation
   print *, "equation is not quadratic"
else
   disc = b*b
4.0*a*c
   x_r = -b/(2.0*a)

 

     if ( abs(disc) < eps ) then ! discriminant nearly zero
      print *, "double real root", x_r

    elseif ( disc > 0 ) then  ! two distinct real roots
       disc = sqrt(disc)/(2.0*a)
        x_r1 = x_r + disc  ! disc temporary variable
        x_r2 = x_r - disc
        print *,
two real roots, x_r1,    and, x_r2


else   ! disc is negative, complex conjugate roots
        x_im1 = sqrt(-disc)/(2.0*a)
        x_im2 = - x_im1
        print *, "complex conjugate roots", x_r, "+", &
        x_im1, "i  and", x_r, "-", x_im2, "i"
endif

endif

end program quadratic

 

Comparison of Real Numbers

       instead of disc == 0.0  we have checked

             abs(disc) < eps

     as condition for double root

 

       misleading results occur otherwise,     eg.

 

               0.1x2 - 0.3 x + 0.225 = 0

 

       has 1.5 as double root

 

       errors in representation give disc > 0.0

 

       roots obtained are 1.5004526 and   1.4995474

Comparing Real Numbers

      double roots undesirable in many applications

 

      two roots close to each other may be treated as double

 

      if abs(disc) is small, roots are close

 

      a parameter eps (epsilon) is usually used for comparing reals

 

      two reals are treated as equal if absolute value of difference is < eps

Quadratic Equations

      numerical problems in solving quadratic equations by this method

 

      if two roots differ by orders of magnitude, smaller root cannot be found accurately

 

                        x2 1000.001x + 1.0 = 0

 

       two real roots 1.0000000e+03, 1.0070801e-03

 

      what happens if actual roots are 1.0e+4 and 1.0 e-4 ?

Strategies

      Strategies are high level descriptions of computations

      They are intuitive and understandable to humans

      Easier to write, analyze, explore and change compared to programs

      Develop strategies first

      Only when a strategy is finalized, write the programs

      Precise statement of strategies is called Algorithm

Algorithm

      Is a sequence of steps

 

      Each step is precise and unambiguous to people

 

      Each step is a high level instruction, that can be carried out by mechanically

 

       Each step can be translated into `low level' programs

 

      Is at a much higher level than HLL itself

Analyzing algorithms

      Before writing the program, analyze and choose the efficient algorithm

 

      Metrics for algorithm

   Number of steps

   Complexity of steps

    number of primitive operations

    (like addition, multiplication, comparison)