What is recursion?
Recursion is an important mathematical concept.
Recursion in programming is a technique for defining a problem in terms of one or more smaller versions of the same problem.
The solution to the problem is built on the result(s) from the smaller version(s).
What is recursion?
Best known example:the factorial
n! = n (n-1)!0! = 1
That’s all you need to calculate n!
Recursive procedures
recursive function function_name(…) result(result)
Let’s use it to calculate n! Structure plan
• n = 0factorial_n = 1
• n > 0factorial_n = n * factorial(n-1)
• n < 0 Error! Return factorial_n = 0
Example
! Factorial,function to calculate factorials recursively
! * accepts : integer n => 0
! * returns : n !
function factorial (n) result (n)
integer : : fact, i
integer, intent (in) : : n
fact = 1
do i = 2, n
fact = fact * i
end do
end function factorial
Example! Factorial, function to calculate factorials recursively
! * accepts : integer n => 0
! * returns : n !
recursive function factorial (n) result (n)
integer : : fact
integer, intent (in) : : n
if ( n == 0 ) then
fact = 1
else
fact = n * factorial (n-1)
end if
end function factorial
Solution 1
recursive function factorial(n) result(factorial_n) ! Dummy argument and result variable integer, intent(in) :: n real :: factorial_n ! Determine whether further recursion is required select case(n) case(0) ! Recursion has reached the end factorial_n = 1.0 case(1:) ! More recursive calculation(s) required factorial_n = n*factorial(n-1) case default ! n is negative - return zero as an error indicator factorial_n = 0.0end function factorial
Write a function for n! Using “select case” structure.
Solution 2
recursive subroutine factorial(n, factorial_n) ! Dummy arguments integer, intent(in) :: n real, intent(out) :: factorial_n ! Determine whether further recursion is required select case(n) case(0) ! Recursion has reached the end factorial_n = 1.0 case(1:) ! Recursive call(s) required ! to obtain (n-1)! call factorial(n-1, factorial_n) case default ! n is negative - return zero as an error indicator factorial_n = 0.0end subroutine factorial
Write a subroutine for n! Using “select case” structure.
Procedures as arguments
Up to now, procedures had as dummy arguments
real, integer, character, logical
andarrays with these types
But, what about a procedure as a dummy argument?
How to declare a procedure?
We have to provide information concerning the interface of the procedure
The interface block:interface
interface_bodyend interface
How to declare a procedure?
Example:
interface function dummy_fun(a, b) result(r) real, intent(in) :: a, b
real :: r end function dummy_funend interface
How to declare a procedure?
Example:
interface subroutine one_arg(x) real, intent(inout) :: x end subroutine one_arg recursive subroutine two_args(x, y) real, intent(inout) :: x, y end subroutine two_argsend interface
Couple of details...
Dummy procedure arguments in a function must be functions
All actual procedure arguments must be module procedures
It is not permissible for an intrinsic procedure to be an actual argument
Derived data types: Creating your own data
You can create your own data types! They can be derived from:
– Intrinsic data types:integer, real, character,
logical
– Previously defined data types
F provides the programmers to create their own data type to supplement the above-given intrinsic types.
Derived data types and structuresAs mentioned before, arrays are used to store elements of the same type. Sometimes items needed to be processed, are not all of the same type.
A data consisting a date for example, has two different types :
the month name of character type
the day and year of integer type
Another example can be given a record (measurement) captured using a computer, might contain
an user’s name in character strings
a password in character strings
an identification number of integer type
captured record of real type
Derived data types and structures
type, public :: new_type component_definition . . .
end type new_type
F provides a “derived data type” in order to declare a “structure” used to store items of different types.
The position in the structure, in which these data items are stored, are called the “components of the structure”.
It is possible to store a name component, a password component, etc. in a structure using the form of,
Example
type, public :: person
character(len=12) :: first_name
character(len=1) :: middle_initial
character(len=12) :: last_name
integer :: age
character(len=1) :: sex ! M or F
character(len=5) :: tax_number
end type person
Example
Now you can declare variable of type person:
type ( type _name ) : : list_of_identifiers
type(person) :: ali, mukaddes, veli
Putting data in a derived type variable
ali = person("Ali","M","Aktepe",56,"M","45645")
mukaddes =
person("Mukaddes"," ","Has",18,"F","12345")
veli = person("Veli","M","Karatepe",65,"M","34567")
This is a structure constructor
Refering to components
variable%component
structure_name % component_name Example:
ali%last_namemukaddes%ageveli%first_name
Using derived types to define new derived types type, public :: employee type(person) :: employee character(len=20) department real :: salaryend type employee
type(person) :: saadet saadet%employee%age = 34
Arrays of derived typestype(person), dimension(1:12) :: bil102class
Then:
bil102class(2)%sex = "M"
You can do operations on components:
bil102class(3)%age+bil102class(4)%age
But no such operation is permissible:
bil102class(3) - bil102class(4)
Example:Let's do some geometry! Two derived types:
– point– line
Two functions:– distinct_points(p1,p2) result(distinct)– line_from_points(p1,p2) result(join_line)
program example_8_1_1! variable declaration
real:: resultinteger :: nprint *,"enter n value"read *, n
! result = factorial(n)call factorials(n,result)print *,n,"!=", resultend program example_8_1_1
recursive function factorial(n) result(factorial_n)! dummy argument and result variable
integer, intent(in) :: nreal :: factorial_n
! determine whether further recursion is requiredselect case (n)case(0)
! recursion has reached the endfactorial_n = 1.0case (1:)
! more recursive calculation(s) requiresfactorial_n = n*factorial(n-1)case default
! n is negative - return zero as an error indicatorfactorial_n = 0.0end selectend function factorial
program example_8_1_2! variable declaration
real:: resultinteger :: nprint *,"enter n value"read *, ncall factorial(n,result)print *,n,"!=", resultend program example_8_1_2
recursive subroutine factorial(n, factorial_n)! dummy argument and result variable
integer, intent(in) :: nreal, intent(out) :: factorial_n
! determine whether further recursion is requiredselect case (n)case(0)
! recursion has reached the endfactorial_n = 1.0case (1:)
! recursive call(s) required to obtain (n-1)!call factorial(n-1, factorial_n)factorial_n = n*factorial_ncase default
! n is negative - return zero as an error indicatorfactorial_n = 0.0end selectend subroutine factorial