Cours Fortran
Cours Fortran
Matthieu Marquillie
[email protected]
Université de Lille
Outline
1 Introduction
2 Fortran basics
3 Control constructs
4 Arrays
5 Procedures
6 Input/Output
Outline
1 Introduction
2 Fortran basics
3 Control constructs
4 Arrays
5 Procedures
6 Input/Output
Computer :
Hardware :
Memory (RAM) : store values during execution of a program (fast ).
CPU (central processor unit) : does the work.
Hard disk drive : store data permanently (slow ).
Keyboard : allow you to input information.
Screen, files, printer : output information.
Software :
Operating system : Unix, Linux, Windows, Mac-OS, ...
Editors : to write text (source code).
Fortran 90 program.
Compilers : transform source code in executable.
Assembler code :
Low level language :
Symbolic representation of the machine codes.
Specific for a given CPU architecture.
Complex, slow and not portable.
Fortran :
First High level compiled language :
Developped in IBM as a more practical alternative to assembly language.
ForTran : The IBM Mathematical Formula Translating System.
Successful only because the compiler could generate optimized code.
Versions History :
First IBM compiler in 1957.
1958-1962 : IBM Fortan II, IBM Fortran III and IBM Fortran IV.
Fortran 66 : First official standard (the way to portability )
Fortran 77 : add a number of significant extensions.
Fortran 90 (and 95) : Free source form, modules, array operations, dynamic memory,
basic object-oriented programming.
Fortran 2003 (and 2008) : nearly complete object oriented language and add some
interesting features.
This course : Fortran 90
Fortran 2003 not fully implemented in compilers :
http://fortranwiki.org/fortran/show/Fortran+2003+status
Fortran 90 sufficient for small and medium code, object oriented code only needed when
writing large applications or libraries.
Matthieu Marquillie Computer Programming using Fortran 90 6 of 91
Intro Basics Control Arrays Procedures I/O Syntax Representation Declarations Operators and expressions
Outline
1 Introduction
2 Fortran basics
Syntax
Representation
Declarations
Operators and expressions
3 Control constructs
4 Arrays
5 Procedures
6 Input/Output
Matthieu Marquillie Computer Programming using Fortran 90 7 of 91
Intro Basics Control Arrays Procedures I/O Syntax Representation Declarations Operators and expressions
Character set :
Characters :
26 letters
0-9
Special characters :
! * + ’’ < ( = > ) ; % / - : , ? ’ . & $
The space character.
The underscore.
uppercase = lowercase
Names :
Variables, program, subroutines, functions, modules.
Must start with a letter.
May only use letters, digits and the underscore.
May not be longer than 31 characters.
myresults, my_results, res1, res_1 ! valid names
_myresults, 1res ! not valid names
Program units :
Main program : only one.
Procedures : subroutine and function.
Modules
Statement ordering :
Variables declarations.
Executable statement.
program test ! type of unit and his name
implicit none
! Declaration of variables :
integer(4) :: myresult,data1,data2
! executable statements
read(10,*)data1,data2
myresult=data1+data2
print*,myresults
end program test ! end the unit
Source code :
program hello
implicit none
print*,’hello world’
end program hello
Numerical representation :
Numeric storage :
Bit : value of 1 or 0, 8 Bits make up 1 Byte .
variables are always stored in a multiple of a Byte :
1, 2, 4, 8, 16 Bytes → 8, 16, 32, 64, 128 Bits
Integer :
If n is the number of Bits used for numeric storage of an integer, the range of
representation of a signed integer is : −2n−1 ≤ i ≤ 2n−1 − 1
Numerical representation :
32 bits real number :
Representation : 1.2 ∗ 10−38 ≤ |r | ≤ 3.4 ∗ 10+38
6 significant digits.
64 bits real number :
Representation : 2.2 ∗ 10−308 ≤ |r | ≤ 1.8 ∗ 10+308
15 significant digits.
Intrinsic types :
Declaration :
General form of a declaration :
type[, attributes list] :: names
type : integer, real, character, ...
attributes : parameter, dimension, ...
parameter : value of the variable cannot be modified.
real(4),parameter :: pi=3.14
pi=4. !-> this is not possible, the compiler will make an error
implicit none :
If not present, there is implicit typing :
Variable starting with letters i-n : integer
Variable starting with others letters : real(4)
implicit none change this rule.
impose declaration of every variable.
better error management by the compiler.
mandatory in all units : program, subroutine, function, modules.
first instruction to appear after the unit name.
Declaration
program declaration
implicit none
integer(kind=2) :: k,l ! 16 bits integer
integer(kind=4) :: i1,j1 ! 32 bits integer
integer(4) :: i2,j2 ! 32 bits integer
integer :: i3,j3 ! 32 bits integer
integer(kind=8) :: m1,n1 ! 64 bits integer
integer(8) :: m2,n2 ! 64 bits integer
real :: x1 ! 32 bits real
real(kind=4) :: x2 ! 32 bits real
real(4) :: x3 ! 32 bits real
double precision :: y1 ! 64 bits real
real(kind=8) :: y2 ! 64 bits real
real(8) :: y3 ! 64 bits real
end program declaration
Declaration
program declaration
implicit none
character(len=1) :: c1 ! 1 character variable
character(1) :: c2 ! 1 character variable
character :: c3 ! 1 character variable
character(len=10) :: c4 ! 10 characters variable
character(10) :: c5 ! 10 characters variable
Writing constants:
Integer real(4) real(8)
0 0. 0.d0
+1 1. 1.d0
1 +1. +1.d0
123 1.0 1.0d0
-26 3.1415 3.1415d0
31415e-4 31415d-4
1.5e-19 1.5d-19
.0001 .0001d0
-2.5 -2.5d0
logical character
.true. ’text’
.false. ’Writing this’
"writing that"
Numeric operators :
Relationnal operators :
Logical operators :
Truth tables :
Unary operator
l .not.l
.true. .false.
.false. .true.
Binary operators
l1 l2 l1.and.l2 l1.or.l2 l1.eqv.l2 l1.neqv.l2
.true. .true. .true. .true. .true. .false.
.true. .false. .false. .true. .false. .true.
.false. .true. .false. .true. .false. .true.
.false. .false. .false. .false. .true. .false.
Examples
real(8) :: a
a=1/2 ! 1 and 2 are integer -> integer division -> conversion to real(8) : a=0.d0
a=1./2 ! 1. real(4), 2 converted to real(4) -> real division -> conversion to real(8)
! a=0.5d0 but with precision problem.
a=1.d0/2.d0 ! 1.d0 and 2.d0 are real(8), real(8) division -> a=0.5d0
Substrings :
Examples
character(10) :: c
c1=’abcdefghij’
print*,c(1:1) ! -> write ’a’ on screen
print*,c(3:6) ! -> write ’cdef’ on screen
Operator precedence :
Binary operators
Operator Precedence
** Highest
* and /
+ and -
//
<,<=,==,/=,>,>=
.not.
.and.
.or.
.eqv and .neqv Lowest
Outline
1 Introduction
2 Fortran basics
3 Control constructs
Conditional constructs
Loops constructs
4 Arrays
5 Procedures
6 Input/Output
IF statement :
Syntax
if (logical_expression) executable_statement
Examples
if (x>y) max=x
if (i==j .and. j/=k) l=i+j
if (a>=b .or. c<=d) min=a+c
Example 1 Example 2
if (x>y) then if (i==j .and. j/=k) then
max=x l=i+j
endif m=i-j
endif
Syntax Example 1
if (logical_expression) then if (x>y) then
executable_statements_1 max=x
else min=y
executable_statements_2 else
endif max=y
min=x
endif
Syntax Example 1
if (logical_expression_1) then if (a>b .and. c>d) then
executable_statements_1 x=a+c
elseif (logical_expression_2) then elseif (a>b .and c<d) then
executable_statements_2 x=a+d
. elseif (a<b .and c>d) then
elseif (logical_expression_n) then x=b+c
executable_statements_n elseif (a<b .and c<d) then
endif x=b+d
endif
Syntax Example 1
if (logical_expression_1) then if (a>b .and. c>d) then
executable_statements_1 x=a+c
elseif (logical_expression_2) then elseif (a<b .and c<d) then
executable_statements_2 x=b+d
. else
elseif (logical_expression_n) then x=0
executable_statements_n endif
else
executable_statements_default
endif
DO loops :
Indexed DO loop Infinite DO loop
do var=expr1,expr2,[expr3] do
executable_statements executable_statements
enddo enddo
var : loop variable which must be an integer. Never change the value of the
control variable inside the loop .
expr1 : integer expression, initial value of var.
expr2 : integer expression, terminating value of var.
expr3 : integer expression, increment (step). expr3 is optional. If absent, it
is assumed to be equal to 1.
The number of iterations is evaluated before execution of the loop. If this is
zero or negative, the loop is not executed.
Infinite loop needs special instructions to become useful.
Indexed DO loops :
Cycle Exit
do [var=expr1,expr2,[expr3]] do [var=expr1,expr2,[expr3]]
executable_statements_1 executable_statements_1
if (logical_expression) cycle if (logical_expression) exit
executable_statements_2 executable_statements_2
enddo enddo
Conditional exit and cycle can be used with infinite loop and indexed loop
If logical_expression is true, exit terminate the loop without executing
the following executable statements.
If logical_expression is true, cycle jump to the next iteration without
executing the following executable statements.
Infinite loop always need an exit instruction to terminate the loop.
Example 1 Example 2
do do i=1,1000
a=a+1. a=a+1.
if ((a>10.).and.(a<30.)) cycle if ((a>10.).and.(a<30.)) cycle
! following statements not executed ! following statements not executed
! if 10<a<30, jump to next iteration ! if 10<a<30, jump to next iteration
if (a>100.) exit if (a>100.) exit
! exit loop when a>100 ! exit loop when a>100 or i>1000
b=b+a b=b+a
enddo enddo
Outline
1 Introduction
2 Fortran basics
3 Control constructs
4 Arrays
Declaration
Terminology
Array manipulation
Dynamic arrays
Random arrays
5 Procedures
6 Input/Output
Matthieu Marquillie Computer Programming using Fortran 90 36 of 91
Intro Basics Control Arrays Procedures I/O Declaration Terminology Manipulation Dynamic Random
Declaration of arrays :
Declaration syntax
type, dimension(expr_1,...,expr_n) :: array1,array2,...
type :: array1(expr_1,...,expr_n),array2(expr_1,...,expr_n),...
Arrays (or matrices) hold a collection of different values of the same type.
n ≤ 7, the maximum number of dimensions of an array is 7.
expr_i indicate the extent in the corresponding dimension.
There is two way of specifying expr_i :
An integer variable (literal or constant). In this case, the lower bound of the dimension
is 1.
An expression of the form cst1:cst2 with cst1 and cst2 integer variable (literals
or constants) following cst1 ≤ cst2.
Declaration of arrays :
Examples 1
real(4), dimension(100,100) :: r1,r2,r3,r4,r5,r6
real(4) :: s1(100,100),s2(100,100),s3(100,100),s4(100,100),s5(100,100),s6(100,100)
Examples 2
real(8), dimension(100,100) :: r1
real(8), dimension(100,50) :: r2
real(8), dimension(50,100) :: r3
real(8), dimension(50,50) :: r4
real(8), dimension(25,100) :: r5
real(8), dimension(100,25) :: r6
real(8) :: s1(100,100),s2(100,50),s3(50,100),s4(50,50),s5(25,100),s6(100,25)
Declaration of arrays :
Examples 3
Lower bound examples : integer(4) :: r1(1:10,1:10),r2(10,10)
integer(4) :: s1(-10:1,-5:5),s2(-20:-10)
Examples 4
character(10),dimension(10,10) :: r1,r2
All intrinsic types can be defined as
logical :: s1(15,5),s2(-10,10)
arrays : real(4) :: t1(20,2)
real(8) :: t2(100)
integer(4) :: u1(100,100,100)
Array terminology :
Definition :
rank : number of dimensions.
bounds : upper and lower limits of indices.
extent : number of elements in dimension;
size : total number of elements.
shape : rank and extents;
conformable : same shape.
Conformance :
A scalar conforms to an array of any shape with the same value for every element.
Arrays used in the same expression must conform in their shape.
Array terminology :
Example
real(4), dimension(15) :: x
real(4), dimension(1:5,1:3) :: y,z
Example
Declaration :
real(4) :: x(3,2,3)
Order in memory :
x(1,1,1), x(2,1,1), x(3,1,1), x(1,2,1), x(2,2,1), x(3,2,1),
x(1,1,2), x(2,1,2), x(3,1,2), x(1,2,2), x(2,2,2), x(3,2,2),
x(1,1,3), x(2,1,3), x(3,1,3), x(1,2,3), x(2,2,3), x(3,2,3)
Examples 2 :
integer(4) :: i,j
real(4) :: a(15),b(-4:0,0:2),c(5,3),d(0:4,0:2)
do i=1,15
a(i)=0. ! sets all elements of a to zero
enddo
do j=1,3
do i=1,5
b(i-5,j-1)=c(i,j) ! sets all element of b to elements of c
enddo
enddo
Examples 1 :
real(4) :: a(15),b(-4:0,0:2),c(5,3),d(0:4,0:2)
a=0. ! sets whole array a to zero
b=c+d ! adds c and d then assigns result to b
b=sinc(c)+cos(d) ! functions are applied element by element
Examples 2 :
real(4) :: a(15),b(-4:0,0:2),c(5,3),d(0:4,0:2)
b=c*d-b**2 ! this is equivalent to concurrent execution of :
! b(-4,0) = c(1,1)*d(0,0)-b(-4,0)**2
! b(-3,0) = c(2,1)*d(1,0)-b(-3,0)**2
! ...
! b(-4,1) = c(1,2)*d(0,1)-b(-4,1)**2
! ...
! b(0,2) = c(5,3)*d(4,2)-b(0,2)**2
Examples 1 :
real(4) :: a(15),b(-4:0,0:2),c(5,3),d(0:4,0:2)
a(2:4)=0. ! sets a(2), a(3) and a(4) to zero
b(-1:0,1:2)=c(1:2,2:3)+1. ! adds one to the subsection of c and assigns
! to the subsection of b
Examples 2 :
a(:) ! the whole array
a(3:9) ! a(3) to a(9) in steps of 1
a(3:9:1) ! as above
a(m:n) ! a(m) to a(n)
a(m:n:k) ! a(m) to a(n) in steps of k
a(8:3:-1) ! a(8) to a(3) in steps of -1
a(8:3) ! a(8) to a(3) step 1 => zero size
a(m:) ! from a(m) to default upper bound
a(:n) ! from default lower bound to a(n)
a(::2) ! from default lower bound to upper bound, steps of 2
a(m:m) ! 1 element section (not a scalar!)
a(m) ! scalar element - not a section
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
x(1:3,1:4) x(2:6:2,1:7:3) x(2:5,7), x(2:5,7:7) x(1:6:2,1:8:2)
Dynamic arrays :
Arrays can be allocated dynamically :
Use the allocatable attribute.
Rank is fixed.
Declaration : Allocation 2 :
integer(4) :: n1,n2,n3,ierr read*,n2,n3
integer(4), allocatable :: t(:) allocate(x(n2,n3),stat=ierr)
real(4), allocatable :: x(:,:) if (ierr/=0) then
print*,’array t : allocation error’
stop
endif
Allocation 1 : Deallocation :
read*,n1 deallocate(t)
allocate(t(n1)) deallocate(x)
Random arrays:
example 1 : example 2 :
real(4) :: x(2,2) real(4) :: x(2,2)
! real random numbers 0 < x < 1 ! real random numbers 0 < x < 10
call random_number(x) call random_number(x)
x=x*10.
example 3 : example 4 :
real(4) :: x(2,2) real(4) :: x(2,2)
integer :: t(2,2) integer :: t(2,2)
! integer random numbers 0 < x < 10 ! integer random numbers -5 < x < 5
call random_number(x) call random_number(x)
t=int(x*10.1) x=int(x*10.1)-5
Outline
1 Introduction
2 Fortran basics
3 Control constructs
4 Arrays
5 Procedures
Subroutine
Function
Arguments
Function or Subroutine ?
Intrinsics subroutine and function
6 Input/Output
Matthieu Marquillie Computer Programming using Fortran 90 51 of 91
Intro Basics Control Arrays Procedures I/O Subroutine Function Arguments Function or Subroutine ? Intrinsics
Program Units
Subroutine example
Subroutine specifications
A subroutine is used with the instruction call followed by the name of the
subroutine with the list of arguments inside parenthesis.
n and a are the actual arguments, list_size and list are the dummy
arguments.
In the subroutine, only variables from the calling unit transmitted by
arguments are knows (here variables n and a).
dummy arguments have the same type as there actual arguments.
You can declare internal variables inside subroutines (here variable i).
In Fortran, arguments are passed by reference (In C, they are passed by value).
Function example
Function specifications
Local objects :
are created each time the procedure is invoked.
are destroyed when the procedure completes.
do not retain their values between calls.
do not exist in the program’s memory between calls.
Array argument
Array argument
Array argument
Function or subroutine ?
Array intrinsics
Intrinsics
Intrinsics
Module : example
Main program : example.f90 Module myio.f90
program example module my_io
use my_io
implicit none contains
integer,parameter :: n=10
real(4) :: a(n) subroutine print_list(list_size,list)
.... implicit none
call print_list(n,a) integer,intent(in) :: list_size
.... real(4),intent(in) :: list(list_size)
end program example integer :: i
do i=1,list_size
print’(1es17.8)’,list(i)
enddo
Modules :
print*,index
end program example
Timing in fortran 90
Outline
1 Introduction
2 Fortran basics
3 Control constructs
4 Arrays
5 Procedures
6 Input/Output
Introduction
Sequential access files
Direct access files
Format
Matthieu Marquillie Computer Programming using Fortran 90 69 of 91
Intro Basics Control Arrays Procedures I/O Intro Sequential Direct Format
OPEN :
open(unit=10,file=’file_name_1’,access=’sequential’,form=’formatted’)
open(unit=11,file=’file_name_2’,access=’direct’,form=’unformatted’,recl=32)
unit= :
Connect one file to one unit number (used in read/write statements).
Only use number ≥ 10
file= : name of the file (character variable).
access= : access type → sequential (default) or direct.
form= :
formatted (default for a sequential file).
unformatted (default for a direct access file).
recl= : length of record for direct access size (generally in Byte, but not always !)
CLOSE :
close(unit=10)
Each write or read statement write control words enclosing the data.
Sequential unformatted files are difficult to read with other programming language (C for
example). If you need to write binary data in Fortran and read the data in another
programming language use direct access unformatted files.
Matthieu Marquillie Computer Programming using Fortran 90 73 of 91
Intro Basics Control Arrays Procedures I/O Intro Sequential Direct Format
Example 1 :
integer :: i,j,l
real(8) :: x,y
open(10,file=’test.dat’,access=’direct’,recl=2*4+2*8 )
do l=1,10
call compute_routine(i,j,x,y)
write(10,rec=l )i,j,x,y
enddo
close(10)
Example 2 :
integer,parameter :: nx=128,ny=97
real(8) :: x(nx),y(ny),u(nx,ny,3)
open(10,file=’test.dat’,access=’direct’,recl=2*4+(nx+ny+nx*ny*3)*8 )
write(10,rec=1 )nx,ny,x,y,u
close(10)
File with only one big record → use this instead of unformatted sequential file when data
has to be read with other language.
Example 3 : How to read previous file when you don’t know nx and ny.
integer:: nx,ny
real(8),allocatable :: x(:),y(:),u(:,:,:)
open(10,file=’test.dat’,access=’direct’,recl=2*4 )
read(10,rec=1)nx,ny
close(10)
allocate(x(nx),y(ny),u(nx,ny,3))
open(10,file=’test.dat’,access=’direct’,recl=2*4+(nx+ny+nx*ny*3)*8 )
read(10,rec=1)nx,ny,x,y,u
close(10)
First read dimensions.
Then read full set of data.
Format specifications
Files output :
read(<unit number>,<format>)<variables>
write(<unit number>,<format>)<variables>
Screen output
read <format>,<variables>
print <format>,<variables>
Integer format
Code Output
integer :: i,j,k -12517561791
i=-125 ^-125^^1756^^1791
j=1756 -00125001756001791
k=1791
write(10,’(i4,i4,i4)’)i,j,k
write(10,’(i5,i6,i6)’)i,j,k
write(10,’(i6.5,i6.6,i6.6)’)i,j,k
Real format 1
Fw.d : write REAL with w characters including the decimal point and the sign,
d corresponding to the number of characters for the fractional part.
w ≥ d+2
Code Output
real :: x,y,z 3.14159^-15.137^799.4732
x=3.14159 ^^3.14^-15.1370^799.74329
y=-15.137
z=799.74328
write(10,’(f7.5,f8.3,f9.4)’)x,y,z
write(10,’(f6.2,f9.4,f10.5)’)x,y,z
Real format 2
Code Output
real :: x,y,z 0.314159E+01^-0.15137E+02
x=3.14159 ^0.79974323E+03
y=-15.137 3.141590E+00^-1.51370E+01
z=799.7432 ^7.99743225E+02
write(10,’(e12.6,e13.5)’)x,y
write(10,’(e15.8)’)z
write(10,’(es12.6,es13.5)’)x,y
write(10,’(es15.8)’)z
Character format
Code Output
character(len=9) :: c ^^^beethoven
c=’beethoven’ beetho
write(10,’(a12)’)c beethoven
write(10,’(a6)’)c
write(10,’(a)’)c
Format control
nX : space of n characters.
Code Output
real :: x,y,z 0.314159E+01^^^^^-0.15137E+02
x=3.14159 ; y=-15.137
write(10,’(e12.6,4X,e13.5)’)x,y
/ : go to newline
Code Output
real :: x,y,z 0.314159E+01
x=3.14159 ; y=-15.137 ^-0.15137E+02
write(10,’(e12.6,/,e13.5)’)x,y
Format repetition
Repetition factor :
Code Output
integer :: i,j,k ^-125^1756^1791
i=-125 ; j=1756 ; k=1791 ^-125^1756^1791
write(10,’(i5,i5,i5)’)i,j,k ^-125^^^1756^^^1791^^
write(10,’(3i5)’)i,j,k
write(10,’(3(i5,2X))’)i,j,k
Format scanning
The number of variables is less than the number of edit descriptors :
All unused edit descriptors are simply ignored.
Code Output
integer :: i,j,k ^-125^1756^1791
i=-125 ; j=1756 ; k=1791
write(10,’(6i5)’)i,j,k
Format scanning
Each time Fortran rescan the format, the following variables are written on a
new line.
Without grouping (parenthesis) Fortran rescan the format from the very
beginning.
With grouping (parenthesis) Fortran rescan the format starting with the
right-most left parenthesis (including its repetition factor).
Examples Examples
’( I6, 10X,I5, 3F10.2 )’ ’( F6.2, (2F4.1,2X,I4, 4(I7,F7.2)) )’
|------------------- |--------------------------
’( I6, 10X,I5, (3F10.2) )’ ’( F6.2, 2(2F4.1,2X,I4), 4(I7,F7.2) )’
|-------- |----------
’( I6,(10X,I5), 3F10.2 )’ ’( F6.2,(2(2F4.1,2X,I4), 4(I7,F7.2)) )’
|---------------- |-----------------------------
Implicit do loops
Implicit do loop can only be used on input/output statements.
Loop variable and parameters are integer variable and can be constants or
constant expressions.
Implicit loop are enclosed in parenthesis, inner parenthesis are executed first.
Examples 1D Examples 2D
integer, parameter :: n=20 integer, parameter :: n1=20,n2=10
integer :: i integer :: i,j
real(8) :: x(n) real(8) :: x(n1,n2)
Code Output
integer, parameter :: n1=4,n2=3 x(1,1) x(2,1) x(3,1) x(4,1)
integer :: i,j
real(8) :: x(n1,n2) x(1,2) x(2,2) x(3,2) x(4,2)
x(1,3) x(2,3) x(3,3) x(4,3)
do j=1,n2
write(10,’(10es17.8)’)(x(i,j),i=1,n1)
enddo
write(10,’(4es17.8)’)((x(i,j),i=1,n1),j=1,n2)
write(10,’(4es17.8)’)x
Code Output
integer, parameter :: n1=4,n2=3 x(1,1) x(1,2) x(1,3)
integer :: i,j
real(8) :: x(n1,n2) x(2,1) x(2,2) x(2,3)
x(3,1) x(2,2) x(3,3)
do i=1,n1 x(4,1) x(2,2) x(4,3)
write(10,’(10es17.8)’)(x(i,j),j=1,n2)
enddo
write(10,’(3es17.8)’)((x(i,j),j=1,n2),i=1,n1)