# What is the most convenient way to create a matrix with given elements?

Dear all,

This must be a very dumb question.
When I read a matlab code, just say, a simple 2 by 2 matrix A, it can be written as

``````A = [1 2; 3 4]
``````

Now in Fortran, do I have to things like below?

``````reshape( [1, 3, 2, 4], [2,2]   )
``````

I know I can always use reshape, but, is there more direct and convenient way to construct a Matrix?

I am asking this because in the new Fortran standard, we can already construct 1D array like

``````B = [1, 2, 3, 4, 5]
``````

It is already very similar with python/julia/matlab.
It makes me think that perhaps modern Fortran can also construct 2D matrix like python/julia/matlab?

Thank you very much in advance!

2 Likes

I think `reshape` is the only intrinsic possibility. But it is not too difficult to use with a bit of elegant writing, like,

``````integer(IK) , parameter     :: nd = 3_IK, np = 5_IK
real(RK)    , parameter     :: Sample(nd,np) =  reshape([ 0.706046088019609031832846377421_RK, 0.031832846377421276922984960890_RK, 0.276922984960890706046088019609_RK &
, 0.046171390631154097131781235848_RK, 0.097131781235848823457828327293_RK, 0.823457828327293046171390631154_RK &
, 0.694828622975817317099480060861_RK, 0.317099480060861950222048838355_RK, 0.950222048838355694828622975817_RK &
, 0.034446080502909438744359656398_RK, 0.438744359656398381558457093008_RK, 0.381558457093008034446080502909_RK &
, 0.765516788149002795199901137063_RK, 0.795199901137063186872604554379_RK, 0.186872604554379765516788149002_RK &
], shape = shape(Sample))

``````

Just pay attention to the column-wise ordering of the elements when reshape occurs. If you like the lines of the code to truly represent the rows of the matrix, you can simply apply the `transpose` intrinsic to the reshaped matrix,

``````! A lower triangle matrix.
real(RK)    , parameter :: MatLow(nd,nd) = transpose(reshape(   [ 1.00_RK,                 0._RK,                0._RK &
, 0.25_RK, +1.391941090707505_RK,                0._RK &
, 1.00_RK, -0.538815906080325_RK, 1.307546335452338_RK ], shape = shape(MatLow)))

``````
2 Likes

Unfortunately I think reshape is the only way as @shahmoradi said. However, I wish Fortran allowed the Matlab style matrix input. See this proposal:

4 Likes

Thank you very much @shahmoradi @certik !
Great solutions!

Perhaps, besides reshape trick, a way kind of like matlab is to input the matrix row by row, like below,

``````A(1,:) = [1,2]
A(2,:) = [3,4]
``````

By the way, I suddenly remember somewhere perhaps in Dr. Fortranâ€™s @sblionel youtube video,

I realized that the symbol ; can be used in Fortran, so, in one line, it can be,

``````A(1,:) = [1,2]; A(2,:) = [3,4]
``````
2 Likes

This Matlab syntax is awful. Itâ€™s kind of convenient, but it shows all the worst parts about how matlab treats everything as a matrix and has really weird semantics around assignment. @certik while youâ€™re looking at matrix literals, it might be a good idea to consider n dimensional array literals. Julia added these as of 1.6, and they are pretty nice. We use the rule of n semi-colons indicates a new â€śrowâ€ť in the nth dimension. For example

``````A = [1 2 3
4 5 6
;;;
7 8 9
0 1 2]
``````

produces a 2x3x2 array. This is nice for people working in higher dimensions (largely physicists).

3 Likes