Fortran中的稀疏存储:仅读取和写入 [英] Sparse Storage in Fortran: Only Reading and Writing

查看:199
本文介绍了Fortran中的稀疏存储:仅读取和写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有多个维度的数组(目标是允许约100个),每个维度的大小约为2 ^ 10,我只需要在其中存储约1000个双精度系数.除了读取和写入该数组外,我不需要对该数组做任何操作.该代码是用Fortran 90编写的.

I have an array with multiple dimensions (the goal is to allow for about 100) and each dimension has a size of about 2^10 and I only need to store in it about 1000 double precision coefficients. I don't need to do any operation with this array aside from reading and writing into it. The code is written in Fortran 90.

我认为,如果我的图书馆像此答案中提到的图书馆之一那样,我将能够存储这样做,但是会针对简单的读写操作进行优化吗?是否有一个最有效的图书馆?

I assume that if I a library like one of the ones mentioned in this answer I would be able to store the do this, but would this be optimized for the simple reading and writing operations? Is there a library that would be most efficient for that purpose?

编辑:通过"简单的读写操作",我的意思是.假设

By "simple reading and writing operations" I mean the following. Suppose

REAL(8), DIMENSION(1000)   :: coeff1
INTEGER, DIMENSION(1000,5) :: index

我想定义coeff2将值存储在coeff1中,然后在index中的索引处读取它,即

I want to define coeff2 to store the values in coeff1 and then read itat the indices in index, that is

DO i = 1,1000
     index(i,:) = [something]
     coeff1(i)  = [another something]
     coeff2(index(i,1),index(i,2),index(i,3),index(i,4),index(i,5)) = coeff1(i)
ENDDO

然后,对于任何i,我想访问

Then, for any i I would like to access the value of

coeff2(index(i,1),index(i,2),index(i,3),index(i,4),index(i,5))

尽快.能够快速执行此操作是我所说的"有效".

as quickly as possible. Being able to do this fast is what I mean by "efficient".

由于[something]中的索引最多为2 ^ 10,因此我目前将coeff2定义如下:

Since the indices in [something] are at most 2^10 I am currently defining coeff2 as follows:

REAL(8), DIMENSION(2**10,2**10,2**10,2**10,2**10) :: coeff2

但是这特别浪费内存,因为我需要将维数(现在是5)增加到100的数量级,并且此数组的大多数元素都等于0.因此,另一种与效率相关的度量我的想法是,随着我增加尺寸数,存储coeff2所需的内存不应爆炸.

but this is too wasteful of memory specially since I need to increase the number of dimensions, now 5, to the order of 100 and most elements of this array are equal to 0. So, another measure of efficiency that is relevant to me is that the memory necessary to store coeff2 should not explode as I increase the number of dimensions.

推荐答案

好吧,对我来说,数据的性质和使用方式还不是很清楚.

Well, It's still not totally clear to me the nature of your data and the way you want to use it.

如果您需要索引不连续的索引数据, 稀疏矩阵可能是一个答案,并且已经在Internet上实现了许多解决方案(如您提供的链接中所示).但是,也许对于我想您想做的事情来说,这是过大的选择.也许一个简单的数据类型可以满足您的目的,就像这样:

If what you need is indexed data, whose indices are not consecutive, Sparse matrix can be an answer, and there are many solutions already implemented over the internet (as shown in the link you provided). But maybe it would be overkill for what I think you are trying to do. Maybe a simple datatype could serve your purpose, like this:

program indexed_values
  implicit none

  type :: indexed
    integer :: index
    real(8) :: value
  end type

  integer, parameter :: n_coeffs = 1000
  integer, parameter :: n_indices = 5
  integer :: i

  real(8), dimension(n_coeffs) :: coeff1
  integer, dimension(n_coeffs, n_indices) :: index
  type(indexed), dimension(n_coeffs, n_indices) :: coeff2
  type(indexed) :: var

  do i = 1, n_coeffs
    index(i, :) = [1, 2, 4, 16, 32] * i ! your calc here
    coeff1(i) = real(i * 3, 8) ! more calc here
    coeff2(i, :)%index = index(i, :)
    coeff2(i, :)%value = coeff1(i)
  end do

  ! that's how you fetch the indices and values by stored position
  var = coeff2(500, 2)
  print*, var%index, var%value ! outputs: 1000   1500.0

  ! that's how you fetch a value by its index
  print*, fetch_by_index(coeff2(500, :), 1000) ! outputs: 1500.0

contains

  real(8) function fetch_by_index(indexed_pairs, index)
    type(indexed), dimension(:) :: indexed_pairs
    integer, intent(in) :: index
    integer :: i

    do i=1, size(indexed_pairs)
      if(index == indexed_pairs(i)%index) then
        fetch_by_index = indexed_pairs(i)%value
        return
      end if
    end do
    stop "No value stored for this index"
  end
end

如果按索引升序存储索引(无需遍历整个列表以失败),则可以改进所提供的按索引获取值的功能.此外,如果您将coeff1的常数结果赋给每一行的所有索引,则您甚至可以做得更好,甚至根本不需要coeff2数组,只需将coeff1用于值和索引用于索引,然后将它们与位置相关联即可.

The provided function for fetching values by its indices could be improved if your indices will be alwyas stored in ascending order (no need to traverse the whole list to fail). Moreover, if you will assing a constant result of coeff1 to all the indices at each row, you could do even better and just not having a coeff2 array at all, just have coeff1 for values and index for the indices, and correlate them by position.

这篇关于Fortran中的稀疏存储:仅读取和写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆