Trying to implement dynamic arrays, but...

  • Follow


Hi,
I am new to this group.
I have been trying to implement some code F95 that should had
presented output
in squares sides 1x1, 2x2 up to 5x5. The code shows the result on
lines instead of squares. What is wrong?
Please see the code below.

PROGRAM mat_5
	IMPLICIT NONE
	INTEGER, DIMENSION(:,:), ALLOCATABLE :: x
	INTEGER :: i

	DO i = 1, 5
		ALLOCATE(x(i,i))
		CALL m(x, i)
		x = RESHAPE( x, (/ i,i /) )
		WRITE(*,*) x
		DEALLOCATE(x)
	END DO

CONTAINS
	SUBROUTINE m(x, i)
		IMPLICIT NONE
		INTEGER :: i
		INTEGER, DIMENSION(i,i) :: x
		x(:,:) = i

	END SUBROUTINE m
END PROGRAM mat_5

Output:
1
2222
333333333
etc
5:s 25 of them

Thanks in advance!
0
Reply Lesson_Learnt 11/14/2010 1:39:40 PM

Hello,

By writing the entire array as one item,
you're writing it in storage order.

If you want to write the array row by row,
you must do so explicitly.

On 2010-11-14 08:39:40 -0500, Lesson_Learnt said:

> Hi,
> I am new to this group.
> I have been trying to implement some code F95 that should had
> presented output
> in squares sides 1x1, 2x2 up to 5x5. The code shows the result on
> lines instead of squares. What is wrong?
> Please see the code below.
> 
> PROGRAM mat_5
> 	IMPLICIT NONE
> 	INTEGER, DIMENSION(:,:), ALLOCATABLE :: x
> 	INTEGER :: i
> 
> 	DO i = 1, 5
> 		ALLOCATE(x(i,i))
> 		CALL m(x, i)
> 		x = RESHAPE( x, (/ i,i /) )
> 		WRITE(*,*) x
> 		DEALLOCATE(x)
> 	END DO
> 
> CONTAINS
> 	SUBROUTINE m(x, i)
> 		IMPLICIT NONE
> 		INTEGER :: i
> 		INTEGER, DIMENSION(i,i) :: x
> 		x(:,:) = i
> 
> 	END SUBROUTINE m
> END PROGRAM mat_5
> 
> Output:
> 1
> 2222
> 333333333
> etc
> 5:s 25 of them
> 
> Thanks in advance!


-- 
Cheers!

Dan Nagle

0
Reply Dan 11/14/2010 2:10:23 PM


Hello,

I'm not a Fortran expert, but I think I can help: The WRITE() function
will put everything in one line, regardless of the shape of the array.
The WRITE function does not "pretty-print" a two-dimensional array so
that it looks like a matrix. For example, try this:

program test
    implicit none

    integer, dimension(:,:), allocatable :: x
    integer :: i

    allocate(x(3,3))

    x(1,1) =3D 11; x(1,2) =3D 12; x(1,3) =3D 13;
    x(2,1) =3D 21; x(2,2) =3D 22; x(2,3) =3D 23;
    x(3,1) =3D 31; x(3,2) =3D 32; x(3,3) =3D 33;

    write (*,*) x
end program


Incidentally, if you don't mind me commenting on your code:


> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ALLOCATE(x(i,i))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CALL m(x, i)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D RESHAPE( x, (/ i,i /) )

You don't need to "RESHAPE" x. It already has the right shape. And I
see no need to put m(x,i) into a separate routine, since all it does
is "x =3D i":

> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IMPLICIT NONE
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER :: i
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER, DIMENSION(i,i) :: x
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x(:,:) =3D i

Instead of "x(:,:) =3D i" you can just write "x =3D i" and it does the
same thing. All in all, my rewrite of your program would be:

program mat_5
    implicit none

    integer, dimension(:,:), allocatable :: x
    integer :: i

    do i =3D 1, 5
            allocate(x(i,i))
            x =3D i
            write(*,*) x
            deallocate(x)
    end do
end program

Cheers,
Daniel.
0
Reply Daniel 11/14/2010 2:14:04 PM

On 14 Nov, 15:10, Dan Nagle <danna...@verizon.net> wrote:
> Hello,
>
> By writing the entire array as one item,
> you're writing it in storage order.
>
> If you want to write the array row by row,
> you must do so explicitly.
>
> On 2010-11-14 08:39:40 -0500, Lesson_Learnt said:
>
>
>
>
>
> > Hi,
> > I am new to this group.
> > I have been trying to implement some code F95 that should had
> > presented output
> > in squares sides 1x1, 2x2 up to 5x5. The code shows the result on
> > lines instead of squares. What is wrong?
> > Please see the code below.
>
> > PROGRAM mat_5
> > =A0 =A0IMPLICIT NONE
> > =A0 =A0INTEGER, DIMENSION(:,:), ALLOCATABLE :: x
> > =A0 =A0INTEGER :: i
>
> > =A0 =A0DO i =3D 1, 5
> > =A0 =A0 =A0 =A0 =A0 =A0ALLOCATE(x(i,i))
> > =A0 =A0 =A0 =A0 =A0 =A0CALL m(x, i)
> > =A0 =A0 =A0 =A0 =A0 =A0x =3D RESHAPE( x, (/ i,i /) )
> > =A0 =A0 =A0 =A0 =A0 =A0WRITE(*,*) x
> > =A0 =A0 =A0 =A0 =A0 =A0DEALLOCATE(x)
> > =A0 =A0END DO
>
> > CONTAINS
> > =A0 =A0SUBROUTINE m(x, i)
> > =A0 =A0 =A0 =A0 =A0 =A0IMPLICIT NONE
> > =A0 =A0 =A0 =A0 =A0 =A0INTEGER :: i
> > =A0 =A0 =A0 =A0 =A0 =A0INTEGER, DIMENSION(i,i) :: x
> > =A0 =A0 =A0 =A0 =A0 =A0x(:,:) =3D i
>
> > =A0 =A0END SUBROUTINE m
> > END PROGRAM mat_5
>
> > Output:
> > 1
> > 2222
> > 333333333
> > etc
> > 5:s 25 of them
>
> > Thanks in advance!
>
> --
> Cheers!
>
> Dan Nagle- D=F6lj citerad text -
>
> - Visa citerad text -

Thanks, shall continue finding a solution.
0
Reply Lesson_Learnt 11/14/2010 3:47:19 PM

On 14 Nov, 15:14, Daniel Carrera <dcarr...@gmail.com> wrote:
> Hello,
>
> I'm not a Fortran expert, but I think I can help: The WRITE() function
> will put everything in one line, regardless of the shape of the array.
> The WRITE function does not "pretty-print" a two-dimensional array so
> that it looks like a matrix. For example, try this:
>
> program test
> =A0 =A0 implicit none
>
> =A0 =A0 integer, dimension(:,:), allocatable :: x
> =A0 =A0 integer :: i
>
> =A0 =A0 allocate(x(3,3))
>
> =A0 =A0 x(1,1) =3D 11; x(1,2) =3D 12; x(1,3) =3D 13;
> =A0 =A0 x(2,1) =3D 21; x(2,2) =3D 22; x(2,3) =3D 23;
> =A0 =A0 x(3,1) =3D 31; x(3,2) =3D 32; x(3,3) =3D 33;
>
> =A0 =A0 write (*,*) x
> end program
>
> Incidentally, if you don't mind me commenting on your code:
>
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ALLOCATE(x(i,i))
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CALL m(x, i)
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D RESHAPE( x, (/ i,i /) )
>
> You don't need to "RESHAPE" x. It already has the right shape. And I
> see no need to put m(x,i) into a separate routine, since all it does
> is "x =3D i":
>
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IMPLICIT NONE
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER :: i
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER, DIMENSION(i,i) :: x
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x(:,:) =3D i
>
> Instead of "x(:,:) =3D i" you can just write "x =3D i" and it does the
> same thing. All in all, my rewrite of your program would be:
>
> program mat_5
> =A0 =A0 implicit none
>
> =A0 =A0 integer, dimension(:,:), allocatable :: x
> =A0 =A0 integer :: i
>
> =A0 =A0 do i =3D 1, 5
> =A0 =A0 =A0 =A0 =A0 =A0 allocate(x(i,i))
> =A0 =A0 =A0 =A0 =A0 =A0 x =3D i
> =A0 =A0 =A0 =A0 =A0 =A0 write(*,*) x
> =A0 =A0 =A0 =A0 =A0 =A0 deallocate(x)
> =A0 =A0 end do
> end program
>
> Cheers,
> Daniel.

I thank you. The code is more(!) compact now, that=B4s good. However the
output is still the same ...
0
Reply Lesson_Learnt 11/14/2010 3:50:49 PM

> I'm not a Fortran expert, but I think I can help: The WRITE() function
> will put everything in one line, regardless of the shape of the array.


To my experience this is incorrect: output format "*" means that
you are satisfied with any correct output, regardless of the format.
The compiler can come up with any format. Sometimes this
takes more than 1 line, even if there is no
obvious reason for this...

Arjan
0
Reply Arjan 11/14/2010 3:53:47 PM

On 14 nov, 16:50, Lesson_Learnt <masa_overm...@yahoo.se> wrote:
> On 14 Nov, 15:14, Daniel Carrera <dcarr...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > Hello,
>
> > I'm not a Fortran expert, but I think I can help: The WRITE() function
> > will put everything in one line, regardless of the shape of the array.
> > The WRITE function does not "pretty-print" a two-dimensional array so
> > that it looks like a matrix. For example, try this:
>
> > program test
> > =A0 =A0 implicit none
>
> > =A0 =A0 integer, dimension(:,:), allocatable :: x
> > =A0 =A0 integer :: i
>
> > =A0 =A0 allocate(x(3,3))
>
> > =A0 =A0 x(1,1) =3D 11; x(1,2) =3D 12; x(1,3) =3D 13;
> > =A0 =A0 x(2,1) =3D 21; x(2,2) =3D 22; x(2,3) =3D 23;
> > =A0 =A0 x(3,1) =3D 31; x(3,2) =3D 32; x(3,3) =3D 33;
>
> > =A0 =A0 write (*,*) x
> > end program
>
> > Incidentally, if you don't mind me commenting on your code:
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ALLOCATE(x(i,i))
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CALL m(x, i)
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D RESHAPE( x, (/ i,i /) )
>
> > You don't need to "RESHAPE" x. It already has the right shape. And I
> > see no need to put m(x,i) into a separate routine, since all it does
> > is "x =3D i":
>
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IMPLICIT NONE
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER :: i
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 INTEGER, DIMENSION(i,i) :: x
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x(:,:) =3D i
>
> > Instead of "x(:,:) =3D i" you can just write "x =3D i" and it does the
> > same thing. All in all, my rewrite of your program would be:
>
> > program mat_5
> > =A0 =A0 implicit none
>
> > =A0 =A0 integer, dimension(:,:), allocatable :: x
> > =A0 =A0 integer :: i
>
> > =A0 =A0 do i =3D 1, 5
> > =A0 =A0 =A0 =A0 =A0 =A0 allocate(x(i,i))
> > =A0 =A0 =A0 =A0 =A0 =A0 x =3D i
> > =A0 =A0 =A0 =A0 =A0 =A0 write(*,*) x
> > =A0 =A0 =A0 =A0 =A0 =A0 deallocate(x)
> > =A0 =A0 end do
> > end program
>
> > Cheers,
> > Daniel.
>
> I thank you. The code is more(!) compact now, that=B4s good. However the
> output is still the same ...

Look up the formats that you can give with a write statement.

Alternatively:

do i =3D 1,size(x,2)
    write(*,*) x(:,i)
enddo

will write the rows of the matrix one at a time - between two writes
there will be
a newline (unless you use the advance =3D 'no' option)

Regards,

Arjen
0
Reply Arjen 11/14/2010 3:55:25 PM

On Nov 14, 4:50=A0pm, Lesson_Learnt <masa_overm...@yahoo.se> wrote:
> I thank you. The code is more(!) compact now, that=B4s good. However the
> output is still the same ...

Of course it is. What I wrote is 100% equivalent to what you wrote. I
was just showing you how to remove needless code. And Dan and I have
already said that there is nothing unusual about the WRITE function
putting everything in one line.

Daniel.
0
Reply Daniel 11/14/2010 3:58:14 PM

7 Replies
338 Views

(page loaded in 0.082 seconds)

Similiar Articles:













7/23/2012 9:46:16 PM


Reply: