Multi-Dimensional
Arrays
Matrices
•
Arrays
seen so far are single dimensional
–
A linear list of items
–
One subscript for accessing individual
elements
•
Multidimensional
arrays are useful organizations in many applications
–
values of temperatures at different
locations in different times
–
number of runs in different sessions on
different days in a test match
–
trajectory of a planet in space - time
•
Matrices
–
simplest and useful multidimensional
arrays
– Two
dimensions
Two-Dimensional Data
Structures
•
Fortran
allows variables that can assume two dimensional array values
•
Typical
values are:
23 14
9 5.6 78.9
23.2 .true. .true.
12 67 89 4.7
0.7 15.2 .false. .false.
9
5 56 6.0
98.2 76.5 .true. .true.
5.2 23.0 14.6
–
An
integer 3 by 3 matrix: 3 rows and 3 columns of integer values
–
4
by 3 real matrix
– 3 by 2 logical matrix
Matrix Declaration
•
Matrix entries can be of different
types
•
No. of rows and columns can be arbitrary
•
Fortran Declaration defines these two
attributes for a matrix variable
–
Real, Dimension(3,6):: Sum
–
Logical, Dimension(23:100,-2:5):: flag
–
integer, Dimension(15:19,5):: runs
•
Accessing an element
–
Sum(2,5), flag(56,0), runs(18,3)
• Two
subscripts are needed
Matrix Representation
•
Memory
is Single-Dimensional
•
Linear
representation of matrix elements
•
Row
major order: One row after another
•
Column
major order: one column after another (assumed representation)
•
Example:
15
56 67 76
20
54 77 11
3
45 86 22
Initialization/Assignment
•
Using
array constructor (column major order)
A = (\ 2,3,4,3,4,5,4,5,6 \)
• Explicit nested do
loops
do I = 1, 5
do J = 1,8
A(I,J) = I + J
end do
end do
• Whole row/column
assignment
do I =1,5
A(I,:) = I
end do
• Initialization can be
done at the time of declaration
Assignment
• Whole,
part or individual array elements can be assigned
A = ...
A(:,i) = ...
A(i,j) = …
•
The rhs should be appropriate type
•
Lifting of scalar to suitable types may
be required
•
with READ statements
read *, ((A(i,j),j = 1, 3), I = 1, 4)
Using matrix variables
•
Matrix variables can be accessed,
individually, in sections or as a whole
•
Used in expressions on the right hand
side of any assignment
•
Intrinsic functions on base types
lifted to matrix types
•
Eg. Abs, Sin, Cos, Tan, Log, Sqrt can
be applied to a matrix variable
– Sin(A)
is a similar matrix in which each entry is Sin of the corresponding entries in
A
Other intrinsic functions
•
LBOUND(A,d)
– lower bound of index
in the dimension d
•
LBOUND(A)
- list of lower bounds
•
UBOUND
- upper bound, similar
•
SIZE(A,d)
- number of entries in dimension d
•
size(A)
- total no. of elements
•
SHAPE(A)
- returns the `shape' of A
–
Extent in a dimension is the no. of
entries in that dimension
– Shape
is an one dimensional array of extents(one entry per dimension)
Transformational
Intrinsic Functions
• Dot_Product(A,B)
- dot product of one dimensional arrays of A and B
• MATMUL(A,B)
- Matrix multiplication on conformable matrices A and B
• RESHAPE(A,B)
- B is a one-dimensional shape array
– Entries
in A are converted into an array of shape B
– Column
major order used
• Example: Suppose
A = 2 5 6 7 and B = [6,2]
1
3 2 8
7
5 8 9
– Reshape(A,B)
= 2
7 3 6 8 8
1 5 5 2 7 9
•
Usually used for initializing a matrix
from a linear list of elements
Masked Assignment
•
A
more generalized selection is possible using WHERE construct
•
Suppose,
you want to multiply all entries > 0 by 2,
and all other entries set to 0 then
where
(A > 0)
A = 2 * A
elsewhere
A = 0
end
where
•
Note: Reference to an array has many connotations
– context dependent
Accessing Matrix variables
•
When a matrix is accessed, the index
values should be valid
•
illegal values lead to run-time error -
Array index exceeding bounds
• Compiler
optionally inserts code for the check
Generalized Arrays
•
Multi-dimensional arrays are possible
•
All array operations, like declaration,
initialization and use are similar
•
Rank of an array is the number of
dimensions
•
One-dimensional array is of rank 1,
matrix of rank 2 etc.
• Arrays
of up to rank 7 are allowed in Fortran
Memory Allocation
•
Arrays are allocated memory by the
compiler
•
The allocation is static - done at
compile time
•
More and larger arrays, larger the
memory requirement
•
Array use and their size requirements
should be done with care
–
indiscriminate use would result in
wastage of memory
• Use
arrays only when all the data in the arrays are required at the same time in
memory
Allocatable Arrays
•
Allocatable
arrays is a solution to memory wastage problem
•
When
the size of an input data set is unknown, better to use the following:
real, dimension(), allocatable :: A
integer, dimension(:), allocatable
:: B
•
This
is a declaration of an Array A and B of rank 1 and 2 respectively
•
Only
ranks specified, the extent decided dynamically
•
When
A ( and B) initialized, the extents are decided and allocated
• This enables avoiding
static allocation of conservative estimate of required space
Allocate Construct
•
Allocatable
arrays are allocated memory using explicit instruction:
allocate(A(n), i)
•
This
indicates the extent of A is the value of n
•
This
is an external routine that may succeed or fail
•
Succeeds
when the memory allocation is successful
•
The
external procedure sends a value 0 via the parameter i
•
Typically
the size is input by the user which is used in the allocation
•
Allocated
memory can be deallocated using
deallocate(A,i)
• This succeeds
provided the value returned via i is 0
Illustration
Linear
Systems of Equations
•
Most commonly occurring problem, the
original motivation for matrices
•
solve a system of n equations in n
variables
a11x1
+ a12x2 + ... + a1nxn = b1
a12x2 +
a22x2 + ... + a2nxn = b2
...
an1x1 +
an2x2 + … + annxn = bn
• aij,,
bj are all real numbers
Gaussian Elimination
•
choose
any equation and any variable with non zero coefficient ( called pivot) in the
equation
•
eliminate
this variable from all other equations by adding a multiple of chosen equation
•
repeat
with remaining equations
•
solve
one equation in one variable
•
back
substitute value of variable to find others
• two steps,
elimination and back substitution
Program
real,
dimension(:,:), allocatable :: a
integer
:: n, i, j
real,
dimension(:), allocatable :: x
read
*, n ! Number of variables
allocate(x(n),
stat=i)
if
( i /= 0) then
print *, "allocation of x
failed"
stop
endif
allocate(a(n,n+1),
stat=i)
if
( i /= 0) then
print *, "allocation of array a
failed"
stop
endif
do
i = 1,n
print *, "enter coefficients of
equation", i
read
*, a(i, 1:n+1)
end
do
do
i = 1,n
a(i, i:n+1) = a(i,i:n+1)/a(i,i) ! make coefficient of x_i 1.0
do j = i+1,n
a(j,i:n+1) = a(j,i:n+1) -
a(i,i:n+1)*a(j,i)
end do ! eliminate x_i
end
do
do
i = n, 1, -1
x(i) = a(i,n+1) -
sum(a(i,i+1:n)*x(i+1:n))
end
do ! sum of a null array is 0.0
print
*, "solution is"
print
*, x(1:n)
deallocate(a,
x, stat=i)
if
( i /= 0) then
print *, "deallocation failed"
stop
endif
Elimination
•
a(1:n+1,1:n+1) contains the
coefficients, x(1:n) the computed values of
variables
•
assumes a(i,i) /= 0.0 at every step
•
true for many special types of matrices
•
problem if abs(a(i,i)) is too small
•
elimination needs to be done only once
for different right hand sides
•
only back substitution needs to be done
• reduces
operations from n3 to n2
Pivoting
•
swap rows and columns to make a(i,i)
large
•
partial pivoting - swap row i with row
containing maxval(abs(a(i:n,i)))
–
what if it is 0.0?
•
complete pivoting- swap row and column
to make a(i,i) = maxval(abs(a(i:n,i:n)))
–
what if it is still 0.0?
–
this changes order of the variables
• gives
more accurate results but more time