Using large sparse 3x3 dp arrays that I need to access many times, I want to use sparse array storage to save on memory. Although there are numerous libraries for sparse matrix (CSR format, etc …), I did not find for arrays. I do not need to do any operations on these arrays. Only to write them initially and then to retrieve efficiently the data for M(nx,ny,nz). I may not need a whole library for such a simple thing. Would there be a piece of code to do this?
What do you mean by a “3x3 dp array” ? A 3x3 array has at most 9 elements. That is by no means “large”. Please provide more details on the retrieval patterns that you expect.
Yes my wording was confusing. I mean the array I read is M(nx,ny,nz)=real value or mostly zeros where nx, ny and nz are large integers. And I need to write M into a memory efficient format and to retrieve the values of M for any nx, ny, nz.
Welcome to the forum. Here are two ways to define a derived type to store the data.
module m1 type, public :: value_3d integer :: ix,iy,iz real :: val end type value_3d type, public :: array_3d type(value_3d), allocatable :: elements(:) end type array_3d end module m1 module m2 type, public :: array_3d integer, allocatable :: ix(:),iy(:),iz(:) ! (n) real , allocatable :: val(:) ! (n) end type array_3d end module m2
I think the second way might be better expressed through a parameterized derived type (PDT), so that sizes of
val are kept consistent. Someone more familiar with PDT may present a solution.
Here is my first-ever use of a PDT, following this tutorial by Iain Barrass
module m implicit none type :: array_3d(n) integer, len :: n integer :: ix(n),iy(n),iz(n) real :: x(n) end type array_3d end module m ! program main use m, only: array_3d implicit none type(array_3d(:)), allocatable :: arr integer :: n n = 2 allocate (array_3d(n) :: arr) arr%ix = [1,5] arr%iy = [6,3] arr%iz = [3,7] arr%x = [1.2,4.6] print*,arr end program main
It compiles and runs with gfortran 12 and Intel Fortran 2021.1 Build 20201112_000000, but with the gfortran the output is
2 1 5 6 3 3 7 1.20000005 4.59999990
and with Intel
1 5 6 3 3 7 1.200000 4.600000
so Intel does not print the
len parameter for a list-directed
write. Do both compilers conform to the standard here?
I suggest that you read about associative arrays . Beliavsky has written about representing the data using a PDT. For retrieving the stored information, you may use a hashing method or a search tree.
Several years ago, I used a hash algorithm for a similar situation where nx, ny, nz ranged from -100 to +100, and the table had about 1,000 entries (compared to the 8 million possible entries given the ranges of nx, ny, nz).
I was looking into the wrong direction with sparse arrays. PDT + hash algorithm is the right one.