- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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(:,:)
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))
...
...
m = SIZE(s, 1)
n = SIZE(s, 2)
allocate (a(m, n), b(m, n))
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Les,
I still have to look into reallocate arrays, thanq very much
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Les Neilson
And the source of some of my grey hairs :-)
Les
grey hair is the sign of wisdom :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!).

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page