Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

array

Status
Not open for further replies.

dudu73

Programmer
Sep 14, 2010
4
BR
I'm beginning to learn computer programming. I have to do a program in fortran 95 which gives the following account:
1 - generate a 4x4 matrix "A" where I can give the values that I want to each element.
2 - take one element, for example, Aij = A32
3 - multiply A32 by its four nearest neighbors and make the sum of the results, eg, A32xA31+A32xA33+A32xA22+A32xA42.
4-Add all the elements of this matrix and compare with the sum of the four elements mentioned above.
5 - depending on the outcome of the comparison between this two sum, I should change the element A32 by another number and repeat the step again. then I do the same procedure for each element of the array.
6 - then I want to print and write this matrix as a 4x4.
This is called the Metropolis algorithm for two-dimensional Ising model.
I'm not able to do this, so I wish someone would do me a small example for this program, step by step, very didactic way because I am a beginning programmer.
Thanks.
 
Sorry but this looks like home work.

Try to solve your problem first. If you have troubles, then post your program : we will try to help you with advices.

But nobody wants to do your work... which is really rather easy!
 
First, thanks for your reply.

Well, as I said in the first message, I'm a beginner, and this problem may seem easy to you but not for me.

This is not a homework. I will work with computacinal simulation method in problems of solid state physics. So I need to learn a programming language well. I'm starting with a problem that is "simple", at least to you.

I'm still working on this program, but he started to return erro.

program testa_atr_matr
implicit none
real::somamat1,somamat2,deltaE,somamult
real, dimension(4,3) :: a
real, dimension(4,3) :: b
integer :: i, j

do i= 1,4
do j= 1,3
a(i,j)= -1
end do
end do

print*, "Matriz A:"
print"(3(f12.5))",((a(i,j), j= 1,3), i= 1,4)

somamat1=sum(a)
print*,''
print*,somamat1
print*,''

do i= 1,4
do j= 1,3

print*,'valor de a(i,j)=',i,j,a(i,j)
pause

a(i,j)=-a(i,j)
print*,'novo valor de a(i,j)=',i,j,a(i,j)
print*,''

if((i==1).and.(j==1))then
somamult=a(i,j)*a(i,j+3)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+3,j)

Else if((i==1).and.(j/=1.and.j/=4))then
somamult=a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-1,j)+a(i,j)*a(i+3,j)

Else if((i==1).and.(j==4))then
somamult=a(i,j)*a(i,j-1)+a(i,j)*a(i,j-3)+a(i,j)*a(i-1,j)+a(i,j)*a(i+3,j)

Else if((i/=1.and.i/=4).and.(j==1))then
somamult=a(i,j)*a(i,j+3)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)

Else if((i==4).and.(j==1))then
somamult=a(i,j)*a(i,j+3)+a(i,j)*a(i,j+1)+a(i,j)*a(i-3,j)+a(i,j)*a(i-1,j)

Else if((i==4).and.(j/=1.and.j/=4))then
somamult=a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-3,j)+a(i,j)*a(i-1,j)

Else if((i==4).and.(j==4))then
somamult=a(i,j)*a(i,j-1)+a(i,j)*a(i,j-3)+a(i,j)*a(i-3,j)+a(i,j)*a(i-1,j)

Else
somamult=a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)

print*,'i=',i,'j=',j,'somamult=',somamult

End if
pause

end do
end do

somamat2=sum(a)
print*,'somamat2=',somamat2
pause

deltaE=somamat2-somamat1
print*,'deltaE=',deltaE
pause

b= a
!print*, "Matriz A:"
!print"(3(f12.5))", ((a(i,j), j= 1,3), i= 1,4)
Print*, "Matriz B:"
print"(3(f12.5))", ((b(i,j), j= 1,3), i= 1,4)
end program testa_atr_matr
 
I see clearly a bug in your program. Your array A has the dimension (4,3) which is too small for your programming. Look at the lines 32-33 :

Code:
if((i==1).and.(j==1))then
  somamult=a(i,j)*a(i,j+3)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+3,j)

You use a(i,j+3) which means a(1,4). 4 is greater than the maximum column number.

As I think that you have chosen the dimensions 4 and 3 just for a simple test (I am possibly wrong), I suggest to replace these two dimensions by variables (m and n for instance). You just have to define them as parameters. After that, it will be very easy to modify them without touching the rest of the program :

Code:
INTEGER,PARAMETER :: m=4,n=5 ! choose values > 4
REAL :: a(m,n),b(m,n)

a=-1

DO i=1,m
  DO j=1,n

    somamult=0

    IF(i==1) THEN
      somamult=somamult+a(i+1,j)+a(i+3,j)
    ELSE IF(i == m) THEN
      somamult=somamult+a(i-1,j)+a(i-3,j)
    ELSE
      somamult=somamult+a(i-1,j)+a(i+1,j)
    ENDIF

    IF(j==1) THEN
      somamult=somamult+a(i,j+1)+a(i,j+3)
    ELSE IF(j == n) THEN
      somamult=somamult+a(i,j-1)+a(i,j-3)
    ELSE
      somamult=somamult+a(i,j-1)+a(i,j+1)
    ENDIF

    somamult=sumamult*a(i,j)

    ..

  ENDDO
ENDDO

Notice also how I have simplified your programming in treating bounds on i and j independently.

I have several other questions/remarks :

- you change the sign of a(i,j) at the line 28. Why ? (this is not a part you mentioned in your first post).

- for points at the boundary of the matrix you use i+3 if i==1 or i-3 if i==m. I don't know why but I don't like that (i+3 is too far from i)... Check your algorithm please... I just expected to not taking into account missing coordinates, with a possible scaling factor 2 ... but again I could be wrong.

- you do your computations more or less as expected => somamult and deltaE. But you never modify the matrix a using these results ! You should modify a(i,j) (or b(i,j)) in your loops.

- at the end, you write B=A : so the matrix B, obviously will contains -A (in taking for A the original matrix).

- at last, I also expected a sort of convergence loop enclosing everything, with a test stopping that convergence loop when the matrix has not been modified during the current iteration.

That's all for the moment



 
I forgot something : you should activate all debug flags of your compiler.

For instance, with g95 (a free compiler), I use :

Code:
-g -fbounds-check -Wall

The second flags would have allow you to detect immediately an index outside the bounds of your array.
 
My friend FJacq,

I've been working your advices. My program become something more complex. So I have worked it in blocks.

I want to send the flowchart of the algorithm (written in. doc) to you but I do not know how to do it.

By the way, I will send you one part ( one block) of my program. If you make it work, I send the entire program.

1 - generate an mxn matrix "A" with all elements negative .
2 - sum1 = ... A2,2*A2,1+A2,2*A2,3+A2,2*A1,2+A2,2*A3,2 +...+
A3,4*A3,3+A3,4*A3,5+A3,4*A4,4+A3,4*A2,4+...
Store sum1
3 - Do A1,1=-A1,1 and repeat the previous step (but this time we will call it sum2). Store sum2
4 - Delta=sum2-sum1
5 - if Delta <0, then "A" become this new configuration, with A1,1 positive.
6- if Delta >= 0, there are other way.
7 - go to the A1,2 element and repeat all steps.

It will be more easy if I had a way to send you the algorithm.

But, any way, follow the block, and the entire program.

BLOCK UNSOLVED

program teste2
implicit none
real:: somamult,SAb
integer, parameter::m=4
integer, parameter::n=3
integer::i,j,a(m,n)

a=-1
somamult=0
print*,a
pause

do i= 1,m !D - início
do j= 1,n !E - fim

a(i,j)=-a(i,j)

print*,'vai começar',a
pause

if((i==1).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i/=1.and.i/=m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)

print*,'elemento ij',i,j,'somamult='somamult
!Here appear this error:
!F95(40) : error 773 - Variable SOMAMULT follows another operand (possible unexpected space?)
!what is this?

pause

End if

end do !E - fim
end do !D - fim

SAb=somamult
print*,'SAb=',SAb

end program teste2

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

COMPLETE PROGRAM UNSOLVED TOO.

program testa_atr_matr
implicit none
real::somamult,r,w,energy,SA
real:: H,SAb,DE
real, parameter:: T=0.2
integer, parameter:: m=4 !I will choose other numbers after
integer, parameter:: n=3 !I will choose other numbers after

integer:: a(m,n),i,j,NU,G,k

NU=50 !number of elements
a=-1
somamult=0

do i= 1,m !A - início
do j= 1,n !B - início

if((i==1).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i/=1.and.i/=m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
End if

end do !B - fim
end do !A - fim

energy=somamult

print*,'matriz A'
print*,''
print*,a
print*,''
print*,'soma de a =',sum(a)
print*,''
print*,'energy=',energy
pause

g=0

Do k=0,NU !C - início
if (k==0)then
SA=energy
else if (k/=0.and.k<NU)then
SA=H
else if (k==NU)then
print*,'k =NU','NU=',NU
pause
print*,''
print*,'H=',H
print*,''
pause
print*,'matriz a'
print*,a
print*,'o programa acabou'
stop
end if


do i= 1,m !D - início
do j= 1,n !E - fim

somamult=0
a(i,j)=-a(i,j)

if((i==1).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i==1).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i+m-1,j)
Else if((i/=1.and.i/=m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==1))then
somamult=somamult+a(i,j)*a(i,j+n-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)
Else if((i==m).and.(j==n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j-(n-1))+a(i,j)*a(i-(m-1),j)+a(i,j)*a(i-1,j)
Else if((i/=1.and.i/=m).and.(j/=1.and.j/=n))then
somamult=somamult+a(i,j)*a(i,j-1)+a(i,j)*a(i,j+1)+a(i,j)*a(i+1,j)+a(i,j)*a(i-1,j)


End if

end do !E - fim
end do !D - fim

SAb=somamult
DE=SAb-SA

print*,'k=',k,'SA=',SA,'SAb=',SAb,'DE=',DE
pause

if (DE<=0)then
go to 1
else
Call random_number(r)
w=exp(-DE/T)

if (r<=w)then
go to 1
Else
a(i,j)=-a(i,j)
end if

if (G>0)then
DE=0
go to 2
else
H=energy
go to 3
end if

end if
1 do G=1,NU !F - início
end do !F - fim
2 H=SA+DE
3 continue

print*,'k=',k,'H=',H
pause


End do !C - fim

end program testa_atr_matr

 
Sorry but the algorithm is not clear :
- k in small or capital latters
- mention of ak when A is a 2D matrix
- a term SAkb never defined
- a random number r used for a strange purpose...

An algorithm must be precise without notation error.

The only thing I could add is the computation of the sum. A short way to program it is :

Code:
  sumall=0
  
  DO i=1,m
  DO j=1,n
    sum=0
    IF(i > 1) THEN ; sum=sum+a(i-1,j) ; ELSE ; sum=sum+a(m,j)
    IF(i < m) THEN ; sum=sum+a(i+1,j) ; ELSE ; sum=sum+a(1,j)
    IF(j > 1) THEN ; sum=sum+a(i,j-1) ; ELSE ; sum=sum+a(i,n)
    IF(j < n) THEN ; sum=sum+a(i,j+1) ; ELSE ; sum=sum+a(i,1)
    sumall=sumall+sum*a(i,j)
  ENDDO
  ENDDO

As I suggested in my previous post, replacing i-1 by i+3 when i == 1 was wrong. i-1 is replaced by m in that case (circular permutation). Indeed, the only clear part of the algorithm was the picture explaining how to determine neighbors.

But I can say nothing else : I don't understand the goal of that algorithm and I have not enough time to go deeper. I can't compare the algorithm description with your programming.

This only thing I could add about your programming is its form : please indent correctly because it looks random and the reading is painful.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top