Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.
Chapter 11 Other data types
Introduction • In this chapter we will introduce three data types provided in F language that we have not yet considered. 1) Parameterized types 2) Complex type 3) Derived types
Parameterized data types • The internal representation of data varies from one machine to another. • 32 bits: 1) Integer: provides values in the range -2147483648 through 2147483647, 2) Real:single-precision values provides approximately seven digits of precision and range of values from approximately -1038 to 1038. • For computations in which more precision is needed than is available using the default real data type. Fortran provides parameterized real types. A parameterized type declaration has the form: type-specifier (KIND = kind-number), attributes :: list or type-specifier (kind-number), attributes :: list where kind-number is an integer constant or a constant integer expression whose value is positive. Kind numbers, called kind type parameters, for various types are machine dependent.
Parameterized data types • There must be at least two kinds of real types, one for single-precision values and other for double-precision values, which provides approximately twice as many significant digits as single precision. The kind numbers for these two types typically are 1 and 2:
Parameterized data types • Example: real (kind = 2) :: Z real (kind = 2), dimension (5, 5) :: Beta declares the variable Z and the 5X5 array Beta to be real of kind 2 (commonly, double precision). • The number of kinds of integer types varies from one Fortran compiler to another, but most compilers provide at least three and some provide four kinds:
Kind type parameters • It is known that the number of integer and real kinds and their meaning differ from one compiler to another. Fortran provides several intrinsic functions for use with parameterized types. Two of the most useful functions are selected_real_kind and selected_int_kind because they facilitate writing programs that are portable from one machine to another. • A reference to selected_real_kind has the form selected_real_kind (p, r) where p and r are integers, with r optional. It returns a kind type parameter that will provide at least p decimal digit of precision a range of at least -10r to 10r, provided such a kind is available. Example: real (kind = selected_real_kind (20, 50)) :: X declares that X is to be a real variable whose values are to have at least 20 decimal digits of precision and may be in the range -1050 to 1050.
Kind type parameters • A reference to selected_int_kind has the form selected_int_kind (r) where r is an integer. It returns a kind type parameter that will provide a range of at least -10r to 10r, if such a kind is available; otherwise it returns -1. Example: integer, parameter :: Range20 = selected_int_kind(20) integer (kind = Range20) :: M, N declare that M and N are integer variables whose values may have up to 20 digits. If no such integer kind is available, a compiler error will result. • To specify the kind of a constant, an underscore followed by a kind number is appended to the constant. For example: 123456789_3 is an integer constant whose kind number is 3, and
Kind type parameters 12345678901234567890_Range20 is an integer constant whose kind number is Range20, where Range20 is the named constant defined earlier by integer, parameter :: Range20 = selected_int_kind(20) • When a value is assigned to a parameterized real variable in a program, it is important that the kind of the value being assigned is the same as the kind of the variable. Consider the following program: program test implicit none real :: X integer, parameter :: DP = selected_real_kind(14) real (kind = DP) :: A, B X = 0.1 B = 0.1_DP A = X
Kind type parameters print *, A A = B print *, A end program test On some systems the values displayed for A by the first two print statements resemble the following: 0.1000000014901161 0.100000000000000 • It is important to ensure that all variables, arrays, and functions that are to have values of a particular kind are declared to be of that kind. For example, if R is a real variable of kind DP and Area is an ordinary (single-precision) real variable, the computation in the statement Area = 3.1415926535898_DP * R ** 2 will be carried out in extended precision, but the resulting value will then be assigned to the single-precision variable Area, thus losing approximately half of the significant digits.
Kind type parameters • As these examples illustrate, although mixed-kind expressions are permitted, accuracy may be lost because of the use of lower-precision constants or variables. • Read pages between 297-312 (Ellis’s book). • Do self-test exercises 11.1.
The complex data type • A complex number is a number of the form a + b i where a and b are real numbers. The first real number, a, is called the real part of the complex number, and the second real number, b, is called the imaginary part. In Fortran, a complex constant is represented as a pair of real constants. (a, b) where a and b represent the real part and the imaginary part of the complex number, respectively. For example: (1.0, 1.0) (-6.0, 7.2) (-5.432, -1.4142) are complex constants equivalent to 1.0 + 1.0 i -6.0 + 7.2i -5.432 -1.4142i respectively.
The complex data type • The names of variables, arrays, or functions that are complex may be any legal Fortran names, but their types must be declared using the complex type statement. For example, the statements complex :: A, B complex, dimension (10, 10) :: Rho declare A, B, and the 10 X 10 array Rho to be complex variables. The statements integer, parameter :: DP = selected_real_kind(14) complex(kind = DP) :: Gamma or integer, parameter :: DP = selected_real_kind(14) complex(DP) :: Gamma
The complex data type declare the variable Gamma whose type is complex of kind DP. For a complex value, this means that both the real part and the imaginary part are real values of kind DP (that is, both are double-precision values). • Some of the mathematical functions commonly used with complex numbers are the absolute value, conjugate, and complex exponential functions. For the complex number z = a + bi, these functions are defined as follows: Absolute value : Conjugate : Complex exponential : These three functions are implemented in Fortran by the intrinsic functions abs, conjg, and exp, respectively.
The complex data type • Three intrinsic functions that are useful in converting from real type to complex type, and vice versa, are aimag (z) Gives the imaginary part of the complex argument z as a real valuewhose kind is the same as the kind of z. cmplx(x, y, kind = k) Converts the two integer, real, or double-precision or arguments x and y into a complex number. The first cmplx(x, kind = k) and the second argument x becomes the real part ofthecomplex number, and the second argument y becomesthe imaginary part. The second form is equivalent tocmplx (x, 0, kind = k). The kind specifier is optional. real (z, kind = k) Z Gives the real part of the complex argument z. The kind specifier is optional. • Read pages between 335-354 (Ellis’s book) • Do self-test exercises 12.1.
Derived types and structures • Arrays are used to store elements of the same type, but in many situations we need to process items that are related in some way but that are not all of the same type. For example, a date consists of a month name (of character type), a day (of integer type), and a year (of integer type); a record of computer usage might contain, among other items, a user’s name and password (character strings), identification number (integer), resource limit (integer), and resources used to date (real). In Fortran 90, a derived data type can be used to declare a structure, which can be used to store such related data items of possibly different types. The positions in the structure in which these data items are stored are called the components of the structure. A simple form of a derived type definition is typetype-name declaration1 declaration2 . . . declarationk end typetype-name where type-name is a valid Fortran identifier that names the derived type and each declarationi declares one or more components in a structure of this type.
Derived types and structures • For example, the following type definition type Computer_Usage_Info character (15) :: LastName, FirstName integer ::IdNumber character (6) :: Password integer :: ResourceLimit real :: ResourcesUsed end type Computer_Usage_Info defines the derived type Computer_Usage_Info. A structure of this type will have 6 components. A typical value of type Computer_Usage_Info might be pictured as follows: LastName FirstName IdNumber Password ResourceLimit ResourcesUsed Babbage Charles 10101 ADA 750 380.81
Derived types and structures • The components of a structure need not be of different types. For instance, the type definition type Point real :: X, Y end type Point defines the derived type Point, and a structure of type Point will have two components named X and Y, each of which is of real type: X Y The type identifiers in such definitions can then be used to declare the types of structures in declarations of the form type (type-name) :: list-of-identifiers 2.5 3.2
Derived types and structures • For example: type (Point) :: P, Q (declares structures P and Q of type Point); type (Computer_Usage_Info) :: User (declares a structure User of type Computer_Usage_Info); and type (computer_Usage_Info), dimension (50):: UserList or type (Computer_Usage_Info) :: UserList (50) declares a one-dimensional array UserList, each of whose elements is a structure of type Computer_Usage_Info.
Derived types and structures • Values of a derived type are sequences of values for the components of that derived type. Their form is type-name (list of component values) Example: Point (2.5, 3.2) is a value of type Point and can be assigned to variable P of type Point, P = Point (2.5, 3.2) or associated with a named constant Center of type Point, type (Point), parameter :: Center = Point (2.5, 3.2) similarly, Computer_Usage_Info (“Babbage”, “Charles”, & 10101, “ADA”, 750, 380.81) is a value of type Computer_Usage_Info and can be assigned to the variable User or to a component of the array UserList:
Derived types and structures User = Computer_Usage_Info (“Babbage”, “Charles”, & 10101, “ADA”, 750, 380.81) UserList (1) = User • The components in such derived-type constructors may also be variables or expressions. For example, if A is a real variable with value 1.1, the assignment statement P = Point (A, 2*A) assigns the structure having real components 1.1 and 2.2 to the variable P. • Individual components of a structure are accessed using qualified variables formed by joining the structure name to the component name with the component selector character (%): structure-name%component-name
Derived types and structures • For example: UserList%LastName, UserList%FirstName, UserList%IdNumber, UserList%Password, UserList%ResourceLimit, and UserList%ResourcesUsed refer to the six components of the structure UserList. • Each component of a structure has a specified type and may be used in the same way as any item of that type. For instance, since User%LastName is of character type, it may be assigned a value in an assignment statement User%LastName = “Babbage” or by input statement read *, User%LastName Its value can be displayed by an output statement print *, User%LastName and its value can be modified by a substring reference: User%LastName(1:1) = “C”
I / O operations on structures • Input and output of a structure must be done component wise, that is, by reading or displaying the value of each component in the structure individually. Example: To input a value for User, we must read values for each component of User separately: read *, User%LastName, User%FirstName, User%IdNumber, & User%Password, User%ResourceLimit, User%ResourcesUsed Similarly, to display the value of User, we must display each component individually, as in print ‘(1X, “Name: “, 2A)’, User%FirstName, User%LastName print ‘(1X, “IdNumber: “, I5)’, User%IdNumber print ‘(1X, “Resource Limit: “, I5)’, User%ResourceLimit print ‘(1X, “Used to date: “, F6.2)’, User%ResourcesUsed
Assignment of structures • Sometimes it is necessary to copy the components of one structure into another structure. This can be done with series of assignment statements that copy the individual components of one structure to the components of the other structure. Example: If User_1 and User_2 are structure variables of type Computer_Usage_Info and we wish to copy the components of User_1 in to User_2, we could use User_2%LastName = User_1&LastName User_2%FistName = User_1&FirstName User_2%IdNumber = User_1&IdNumber User_2%Password = User_1&Password User_2%ResourceLimit = User_1&ResourceLimit User_2%ResourcesUsed = User_1&ResourcesUsed
Assignment of structures • If the structures have the same type, this can be done more conveniently with a single assignment statement of the form structure-variable = structure-expression For example, the six assignment statements above could be replaced by the single assignment statement User_2 = User_1 • Read pages between 200-216 (Ellis’s book). • Do self-test exercises 8.1.
Strings (character data type) • Computers store and process information in three principal forms as numerical information, logical information, and character (textual or verbal) information. As we have seen in the previous chapters, the unit of numerical information is a single number of real or integer type, and a primitive data object of logical type is a single true or false value. In contrast, F always processes character data in composite form, as groups, or strings, of characters. Operations apply to strings rather than to the individual characters (letters, digits, or punctuation symbols) in a string. CHARACTER CONSTANTS A character constant is a sequence of characters enclosed between quotation marks, as in the following examples: “Do_it_with_F.” “12345” “Energy_can_not_be_created_or_destroyed.”
Character variables and named constants • Each character variable and named constant has a fixed length, which is a type property that is specified in a type declaration following the keyword character. • The length specification, as we saw in the previous chapters, may be given as an explicit constant, but named constants are preferred. Example: character (len=10) :: Print_Buffer, String, Text character (len=120) :: Line integer, parameter :: NAMED_CONSTANT = 64 character (len=NAMED_CONSTANT) :: Conservation_Law The length of character string may be assumed from the defining constant string in a declaration such as the following: character (len=*), parameter :: WORD = “Praseodymium” An asterisk replaces the usual length constant in the type declaration. The actual length of the named constant WORD (12, in this example) is taken from the length of the literal constant string. With this notation, two or more named string constants of different lengths can be defined in the same declaration. Note that this assumed length spacification applies only to named constants.
Character arrays • All elements of a character array have the same length; there is no way to create an array containing some character strings of one length and others of a different length. EXAMPLE: program test implicit none integer, parameter :: LN = 10, ARRAY_SIZE = 5 character (len = LN), dimension (ARRAY_SIZE) :: Amino_Acids, Compounds Amino_Acids(1) = “Glycine “ Amino_Acids(2) = “Alanine “ Amino_Acids(3) = “Valine “ Amino_Acids(4) = “Leucine “ Amino_Acids(5) = “Tyrosine “ Compounds(1) = “Phenol “ write (unit = *, fmt = *) Amino_Acids, Compounds(1) stop end program test
Substrings • It is often necessary to refer to a portion of a string in a character expression. A parenthesized substring specification may follow the name of a character variable or constant. The substring specification gives the first and last character positions of the substring. Example on substring notation: program test1 implicit none integer, parameter :: S_LEN = 18 character (len = S_LEN) :: El_Name, Compound Compound = “Zinc Hydroxide” write (unit = *, fmt = *) Compound (1 : 4) El_Name = “Praseodymium “ write (unit = *, fmt = *) El_Name (2 : 9) stop end program test1
Substrings • Execution of the program produces the following output: Zinc raseodym
Concatenation of character expressions • A pair of strings may be joined into a single longer string by appending the second string to the first. This operation is known as concatenation. It is specified by an operator that consists of two slashes written between a pair of character expressions. • For example, “ABC” // “DEFG” represents the concatenation of the three-character string ABC with the four-character string DEFG to form the seven-character string ABCDEFG. • The expression on the right is fully evaluated before any assignment takes place. X = “ZZ” // X(3 : 14) X = X ( : 7) // “ “ // X (9 : )
Intrinsic functions for character processing • Len (String Length);The intrinsic function len, with a character string as its argument, returns a result of integer type that is the length of the character string. • Index (Pattern Matching);Applications involving lines or paragraphs of text frequently require that a certain (usually short) pattern be located within a (longer) string. For example, we might wish to search the string Matter cannot be destroyed. To find the location of the pattern can. The intrinsic function index provides a simple way to perform such a search or pattern matching operation. The function has two arguments of character type. The first identifiers the longer string to be searched, while the second indicates the pattern to be located within the longer string. For example, the value of index (“Matter cannot be destroyed.”,”can”) is 8, since can is found as a sub string beginning at the eight character position in the longer string.
Intrinsic functions for character processing • char and ichar (Integer value of a Character); It is often useful to be able to obtain an integer “code number” from a single character of text. The intrinsic function ichar has an argument consisting of a single character-that is, a character string of length1-and produces an integer value giving a unique code value for each different character. The inverse function char produces a single character from an integer between 0 and 127. • trim and len_trim;trim(string) returns the initial substring of string, omitting trailing blanks. Len_trim (string) returns the length of string, ignoring trailing blanks. • Do exercises 6.1.1-6.1.7 on pages 290-292 (Meissner’s book).