Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

my first program

luvfort
Beginner
1,224 Views
Hello all,

i've been watching this forum for a while. I took some suggestions and wrote a program to add/subtract two any size matrix prescribed by the user! please take a look at it and give suggestions for improvement.

[cpp]!** This program adds two matrices of any size
!   The user inputs the size of matrix
!   The matrix has to be input in normal way [1 2]
!                                            [3 4]
!   output will be in the same way
!*******************************
! subroutine that adds matrices*
!*******************************
module m_add
implicit real*8(a-h, o-z)
contains
subroutine matrixadd(s,d,m,n)
dimension a(m,n),b(m,n),s(m,n),d(m,n)
write(*,*) 'enter the 1st matrix'
read(*,*) a
write(*,*)'enter the 2nd matrix'
read(*,*) b
s=a+b
d=a-b
end subroutine
end module 
!***************************!
! Main program              !
!***************************!
program addm
use m_add
implicit real*8 (a-h, o-z)
real*8, allocatable :: a(:,:),b(:,:),s(:,:),d(:,:)
write(*,*) 'enter the size of the matrix'
read(*,*) m,n
allocate(a(m,n),b(m,n),s(m,n),d(m,n))
call matrixadd(s,d,m,n)
print*, 'Matrix Addition'
do j=1,n; print 10,(s(i,j),i=1,m)
enddo
print*, 'Matrix subtraction'
do j=1,n; print 10, (d(i,j),i=1,m)
enddo
10 format(10f10.1/)
end program ! addm[/cpp]

0 Kudos
10 Replies
Les_Neilson
Valued Contributor II
1,224 Views

Welcome to the forum.
Just some minor comments, only on style - but style is a personal preference anyway, others may have different opinions.

I prefer to use "implicit none" and then specify variables explicitly. That way spelling errors (typos) may be caught more easily.
I also prefer, when possible, to declare one variable per line - often makes future edits easier to do. When used witha source control system it is also easier to see what has changed when comparing the histories of a file.
The same with executable statements
do j=1,n; print 10, etc
I would write as two lines.

I allocate one array at a time with error checking - when working on commercial projects a "graceful error trap" is better than a program failure. (with consequent loss of user data. This is A Bad Thing !)

Using modules isA Good Thing.
I often code modules as follows :

module X
Putthe data variables including allocatables here

contains

Initialise routine(s) to allocate the arrays andassign initial values to all variables

Asubroutine to reallocate_arrays.For dynamic programs where the size of the data "grows"- retaining the original values if necessary.

Routines tomanipulate the data,e.g. perform some calculations as you have done.

Maybe Get and Set routines to get the value of a variable or assign a value to a variable - helps prevent accidental overwrite of values.

and so on.

As I say a personal style preference.

Les
0 Kudos
John4
Valued Contributor I
1,224 Views
IMPLICIT NONE is always a good idea. Also, since you're using modules, you might consider dropping the last two arguments in matrixadd (using, for example, "s(:,:),d(:,:)" instead of "s(m,n),d(m,n)"). Your subroutine only has four arguments, so those arguments might not be a problem, but as the number of arguments increases, it could give you some headaches.

Also, try to always use the INTENT attribute for your function/subroutine arguments and avoid declarations like real*8 (for portability purposes). So, in my opinion, the beginning of your subroutine would look better this way:

subroutinematrixadd(s, d)
integer, parameter :: wp = KIND(1.d0)
real(wp), intent(OUT) :: s(:,:), d(:,:)
real(wp), allocatable :: a(:,:), b(:,:)
integer :: m, n
...
m = SIZE(s, 1)
n = SIZE(s, 2)
allocate (a(m, n), b(m, n))
...


0 Kudos
luvfort
Beginner
1,224 Views
Hi Les , John

Thank you very much for you feedback !!!!
this really helps me improve my programming skills, sorry I was busy with other works, so I couldn't reply soon

So I combined both of your suggestion and here is the improvised code, i guess :)

[cpp]program main1
use m_add_sub
implicit none
real(suf), allocatable :: a(:,:),b(:,:)
real(suf), allocatable :: s(:,:),d(:,:)
print*, 'Enter the size of matrix'
read(*,*) m,n
allocate(a(m,n),b(m,n),s(m,n),d(m,n))
write(*,*) 'enter the 1st matrix'
do j=1,n 
read(*,*) (a(i,j),i =1,m)  
enddo 
write(*,*)'enter the 2nd matrix'
do j=1,n
read(*,*) (b(i,j),i=1,m)
enddo
call matrixadd(a,b)
end program ! addm

module m_add_sub

implicit none
integer , parameter :: suff =selected_real_kind(10,99)
integer i,j, m,n

contains

subroutine matrixadd(a,b)
real(suff), dimension(m,n), intent(in):: a,b
real(suff), dimension(m,n):: s,d
s=a+b
d=a-b
print*, 'Sum'
do j=1,n
print 10,(s(i,j),i=1,m)
enddo
print*, 'Difference'
do j=1,n
print 10,(d(i,j),i=1,m)
enddo
10 format(10f10.1,/)
return
end subroutine
end module
[/cpp]

0 Kudos
luvfort
Beginner
1,224 Views
Les,

I still have to look into reallocate arrays, thanq very much
0 Kudos
luvfort
Beginner
1,224 Views
John,
thanks
intent looks lil tricky. It can be used only for dummy variables. So if i want to use intent(in) and intent(out), in my case i have to use matrixadd(a,b,s,d). I still have to look deeper into 'intent' attribute !
0 Kudos
Les_Neilson
Valued Contributor II
1,224 Views
Quoting - luvfort
John,
thanks
intent looks lil tricky. It can be used only for dummy variables. So if i want to use intent(in) and intent(out), in my case i have to use matrixadd(a,b,s,d). I still have to look deeper into 'intent' attribute !

consider :
subroutine foo(M)
M is a dummy argumentIt is associated with whatever *actual* argument is used in thecall to the subroutine
call foo(5) M will have the value 5 (the actual argument)on entry to subroutine foo.
call foo(J) M will have whatever the valueof J (the actual argument) is.

integer, INTENT(IN) :: M implies the programmerpromises not tochange the value of M
M= 42would becaught by the compiler as a codingerror
foo can be called with literal numbers as well as variables as an actual argument.

INTENT(OUT) implies the value of M might change within the subroutine
M = 42 is acceptible
foo should never be called with literal numbers as actual arguments
(In theGood Old Days of many years ago I once chased a bug where someone called a subroutine with a literal value 1 instead of variable l (lower case L) which got assigned another value.Later in the code there was K = K+ 1 increment a counter but "1"no longer had the value "1" Fortunately todays compilersdon't let that happen.)

INTENT(INOUT) implies the value of M initially might be used within the subroutine AND its value might change
M = M + 42


There are complications involving aliasing and "side effects"where theINTENT(IN) may be bypassedbut you don't want to go there.

Les
0 Kudos
gib
New Contributor II
1,224 Views
Quoting - Les Neilson
(In theGood Old Days of many years ago I once chased a bug where someone called a subroutine with a literal value 1 instead of variable l (lower case L) which got assigned another value.Later in the code there was K = K+ 1 increment a counter but "1"no longer had the value "1" Fortunately todays compilersdon't let that happen.)
Ah, it takes me back! The old changed-value-of-a-constant bug. Character-building.
0 Kudos
Les_Neilson
Valued Contributor II
1,224 Views
Quoting - gib
Ah, it takes me back! The old changed-value-of-a-constant bug. Character-building.

And the source of some of my grey hairs :-)
Les
0 Kudos
luvfort
Beginner
1,224 Views
Quoting - Les Neilson

And the source of some of my grey hairs :-)
Les
thanks Les for lil bit more explanation on intent attribute

grey hair is the sign of wisdom :)
0 Kudos
wolfgang_knott
Beginner
1,224 Views
Quoting - luvfort
thanks Les for lil bit more explanation on intent attribute

grey hair is the sign of wisdom :)

When my hair was blond I had the constant "2" with a value of 3 (for weeks!).
0 Kudos
Reply