Majd
Majd

Reputation: 348

Algorithm for progressive matrix

I want to construct a matrix like so:

[ 0 1 2 3 4 5 ....
  1 2 3 4 5 6 ....
  2 3 4 5 6 7 ....
  3 4 5 6 7 8 ....
  4 5 6 7 8 9 ....
  5 6 7 8 9 10 ... ] etc 

The main goal is to use the algorithm to put to the power the elements of an already existing matrix.

I am programming in Fortran, and I used the following code but it's not working:

do i = 1, m+1
  do j = 1, m+1
    do while ( w < 2*m )
      if ( i > j ) then
        ma(i,j) = 0
      else 
        w = i-1
        ma(i, j) = w
        w = w +1 
      end if
    end do
  end do
end do

Upvotes: 1

Views: 155

Answers (4)

Majd
Majd

Reputation: 348

Thanks for the feedback, I managed to do it using the following code:

do i = 1, m+1
  w = i-1
  do j = 1, m+1
    ma(i, j) = u**w
    w = w+1
  end do
end do

I would like to state that i'm using Fortran 90 and only 90 because of my circumstances, otherwise I would've went with c++, (university life !!).

Please note that I used the desired series to put to the power the elements of the matrix.

Finally, I noticed some "complex" answers maybe, or maybe I'm just a beginner, but i would really love to learn if there are some rules and or dos and don'ts and or advice to get better at coding ( scientific code, not development code).

Thank you very much for the feed back, and waiting for any responses.

Upvotes: 0

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8566

I suggest you to use an implied-do in the array constructor syntax, possibly initialized in the same declaration:

integer, parameter :: n = 10, m = 5
integer :: i, j
integer :: ma(m,n) = reshape([((i+j, j=0, m-1), i=0, n-1)], [m,n])

The [...] syntax is posible in Fortran 2003 or higher. (/.../) should be used otherwise. My result with gfortran v7.1.1 is:

do i = 1, m
  print *, ma(i, :)
end do

$gfortran test.f90 -o main
$main
           0           1           2           3           4           5           6           7           8           9
           1           2           3           4           5           6           7           8           9          10
           2           3           4           5           6           7           8           9          10          11
           3           4           5           6           7           8           9          10          11          12
           4           5           6           7           8           9          10          11          12          13

Note: The initialization in the declaration would only be possible if n and m are constants (parameter). You could initialize it normally in the program body, otherwise, with the same implied-do syntax. If you plan to read the values of m and n at runtime, you should make ma an allocatable array.

Upvotes: 2

fvalencar
fvalencar

Reputation: 1

I've seen that others already made an algorithm that solves your problem. But i also bring another algorithm that works for a non-square matrix. NI is the number of columns of the matrix, and NJ is the number of lines. MAT is the matrix you want.

PROGRAM MATRIX    
IMPLICIT NONE
    INTEGER                     ::  I, J, NI, NJ
    INTEGER, ALLOCATABLE        ::  MAT(:,:)

    NI = 8
    NJ = 5

    ALLOCATE(MAT(NI,NJ))

    DO I = 1, NI
        MAT(I,1) = I-1
    ENDDO

    DO J = 2,NJ
        MAT(:,J) = MAT(:,J-1) + 1 
    ENDDO

    DO J = 1, NJ
        WRITE(*,'(8I3)') MAT(:,J)
    ENDDO
END PROGRAM 

Upvotes: 0

Ian Bush
Ian Bush

Reputation: 7432

While there is nothing wrong with Rodrigo's answer personally I think it much clearer to just use two loops

ian@eris:~/work/stackoverflow$ cat floyd.f90
Program yes
  Implicit None
  Integer, Parameter :: n = 5
  Integer, Dimension( 1:n, 1:n )  :: elp
  Integer :: base, offset
  Integer :: i, j
  Do i = 1, n
     base = i - 1
     Do j = 1, n
        offset = j - 1
        elp( j, i ) = base + offset
     End Do
  End Do
  Do j = 1, n
     Write( *, '( 1000( i3, 1x ) )' ) elp( j, : )
  End Do
End Program yes
ian@eris:~/work/stackoverflow$ gfortran -Wall -Wextra -std=f2003 -fcheck=all -O floyd.f90 -o genesis
ian@eris:~/work/stackoverflow$ ./genesis 
  0   1   2   3   4
  1   2   3   4   5
  2   3   4   5   6
  3   4   5   6   7
  4   5   6   7   8

Upvotes: 0

Related Questions