I'm using codeblocks and gnu compiler to run Fortran code but I noticed something very strange.
Once I have an array (1,2,3,...,16)
if I want to reshape to a 4x4 matrix I use the built-in reshape
function, which should in theory use a column-major order for the numbers and so give (1 5 9 13; 2 6 10 14; 3 7 11 15; 4 8 12 16)
;
instead I get (1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16)
.
This is a major inconsistency, I wonder if it is related to using codeblocks or what.
Anyone else with this problem and/or an idea about the reason and a solution.
Asked
Active
Viewed 213 times
-1

Ian Bush
- 6,996
- 1
- 21
- 27

Domenico Bianchi
- 21
- 6
-
4Fortran uses column-major ordering. And thus reshape produces the array `(1 5 9 13; ...`. Please show us your code, then we can argue better. – jack Mar 08 '21 at 20:03
-
Please show your code and use code formatting for better readability, – JAlex Mar 08 '21 at 22:13
-
Thank u very much, i didnt post the code because it was very basic. i'll do next time for sure. – Domenico Bianchi Mar 09 '21 at 11:40
1 Answers
1
I could not replicate the issue with Intel Fortran oneAPI HPC
and code for reference
program FortranConsole1
use, intrinsic :: iso_fortran_env
implicit none
interface show
procedure show_matrix_i, show_matrix_r, show_matrix_d
end interface
integer :: row(16), matrix(4,4)
real(real64) :: A(4,4)
row = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
matrix = reshape( row, [4, 4])
call show(matrix)
A = dble(matrix)
A = sqrt( matmul( transpose(A), A) )
call show(A, 8)
call show(A, 12)
call show(A, 16)
contains
subroutine show_matrix_i(A, w)
! Display the matrix 'A' in columns
! A : the array of integers
! w : the column width. Default = 5
integer, intent(in) :: A(:,:)
integer, intent(in), optional :: w
integer :: i,j,n,m, wt
character(len=16) :: fmt
if(present(w)) then
wt = w
else
wt = 5
end if
n = size(A,1)
m = size(A,2)
write( fmt, "(a,g0,a)") "(*(g",wt,".0))"
write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine
subroutine show_matrix_r(A, w)
! Display the matrix 'A' in columns
! A : the array of real numbers
! w : the column width. deafult = 12
! s : sig. figures w-5 (calculated)
real(real32), intent(in) :: A(:,:)
integer, intent(in), optional :: w
integer :: i,j,n,m,dg,wt
character(len=16) :: fmt
if(present(w)) then
wt = w
else
wt = 12
end if
dg = wt-5
n = size(A,1)
m = size(A,2)
write( fmt, "(a,g0,a,g0,a)") "(*(g",wt,".",dg,"))"
write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine
subroutine show_matrix_d(A,w)
! Display the matrix 'A' in columns
! A : the array of dble numbers
! w : the column width. default = 12
! Converts 'A' into single precision and calls `show_matrix_r`
real(real64), intent(in) :: A(:,:)
integer, intent(in), optional :: w
call show_matrix_r(real(A),w)
end subroutine
end program FortranConsole1
with results

JAlex
- 1,486
- 8
- 19
-
1Thank u very much. I went to sleep and tried again and now all works how it should be and how it has always done. Maybe yesterday i was allucinating (me or codeblocks! i dont konw what to think. Thank you very much to conferm and clarify the solution. Do you happen to know a faster way to print the matrix without using for exampe the print statement multiple times? – Domenico Bianchi Mar 09 '21 at 11:31
-
@DomenicoBianchi - glad the gods aligned again. As far as display a matrix, there might be a way with an implied do loop but I am really bad at text formatting with Fortran. Typically I have several functions under the program `contains` keyword with the generic name `show` that handle the display of vectors and matrices in columns etc. – JAlex Mar 09 '21 at 13:36
-
-
@DomenicoBianchi - I added some formatting code to the answer that might ease your pain with displaying matrices of integers, reals or doubles. – JAlex Mar 09 '21 at 15:57
-
Thank you! i read the link you provided and studied your code, i like it and i appreciated a lot the effort. Thanks very much. – Domenico Bianchi Mar 09 '21 at 23:43