Storing a Variable with a Multi-Dimensional Index in Fortran

后端 未结 1 943
萌比男神i
萌比男神i 2021-01-16 06:05

Question

Consider the following code:

program example

  implicit none

  integer, parameter :: n_coeffs = 1000
  integer, parameter         


        
1条回答
  •  悲&欢浪女
    2021-01-16 06:30

    For any 5 dimensional index I need to obtain the associated coefficient, without knowing or calculating i. For instance, given [2,4,8,16,32] I need to obtain 3.0 without computing i.

      function findloc_vector(matrix, vector) result(out)
        integer, intent(in) :: matrix(:, :)
        integer, intent(in) :: vector(size(matrix, dim=2))
        integer :: out, i
    
        do i = 1, size(matrix, dim=1)
          if (all(matrix(i, :) == vector)) then
            out = i
            return
          end if
        end do
        stop "No match for this vector"
      end
    

    And that's how you use it:

    print*, coeff(findloc_vector(index, [2,4,8,16,32])) ! outputs 3.0
    

    I must confess I was reluctant to post this code because, even though this answers your question, I honestly think this is not what you really want/need, but you dind't provide enough information for me to know what you really do want/need.

    Edit (After actual code from OP):

    If I decrypted your code correctly (and considering what you said in your previous question), you are declaring:

    REAL(8), DIMENSION(L_max,L_max,2**(L_max),2**(L_max)) :: coeff_grid
    

    (where L_max = 9, so size(coeff_grid) = 21233664 =~160MB) and then populating it with:

    DO i = 1,count
        coeff_grid(J_index(i,1),J_index(i,2),J_index(i,3),J_index(i,4)) = J_coeff(i)
    ENDDO
    

    (where count is of the order of 1000, i.e. 0.005% of its elements), so this way you can fetch the values by its 4 indices with the array notation.

    Please, don't do that. You don't need a sparse matrix in this case either. The new approach you proposed is much better: storing the indices in each row of an smaller array, and fetching on the array of coefficients by the corresponding location of those indices in its own array. This is way faster (avoiding the large allocation) and much more memory-efficient.

    PS: Is it mandatory for you to stick to Fortran 90? Its a very old version of the standard and chances are that the compiler you're using implements a more recent version. You could improve the quality of your code a lot with the intrinsic move_alloc (for less array copies), the kind constants from the intrinsic module iso_fortran_env (for portability), the [], >, <, <=,... notation (for readability)...

    0 讨论(0)
提交回复
热议问题