本文介绍了Fortran:哪种方法可以更快速地更改数组的排名?(重塑与指针)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我们处理大型数组时,重要的是要考虑改变数组的秩和形状的代价,尤其是当它在多个子例程/函数中发生两次时.

When we deal with large arrays, it may be important to consider the cost of change of rank and shape of arrays specially when it happens a couple of times in multiple subroutines/functions.

我的问题的主要目的是将数组的排名从第二更改为第一,反之亦然...

要执行此操作,可以使用:

To do this one can use :

  1. RESHAPE声明
  2. POINTER变量.下面的代码显示了如何利用指针变量:

  1. RESHAPE statement
  2. POINTER variables. Below is a code which shows how to utilize pointer variables:

program test
    real, pointer :: a(:)
    real, pointer :: b(:,:)

    allocate(a(6))
    a = (/1,2,3,4,5,6/)
    b (1:2, 1:3) => a

    WRITE(*,*) 'b=',b(3,1)
end program test

问题:1.哪种方法更快?2.还有其他更快的方法吗?3.还有其他建议可以做这项工作吗?

Questions :1. Which method is faster?2. Is there any other faster method?3. Any other suggestion to do this work?

谢谢...

推荐答案

好,Fortran被设计为MATH的语言.我挖了一点,然后发现了Fortran中的以下几点.

Well, Fortran is designed to be the language of MATH. I dug a little bit and I came across the below points in Fortran.

解释要点之前的一些解释:

Some explanation before explaining the points :

我的子例程必须与1st rank数组一起使用.我在子程序的开头将2nd rank数组称为输入.然后,我需要将排名从第二更改为第一.在子例程的后面,我需要将等级更改回2.这种等级更改在代码中发生了3-4次.

My subroutine must work with 1st rank arrays. I am calling 2nd rank arrays as input at the beginning of the subroutine. Then, I need to change the rank from 2nd to 1st. Later in the subroutine, I need to change the rank back to 2. This changing of ranks is happening 3-4 times in the code.

  1. 使用等价语句:

这是最快的方法.记忆中没有任何变化,我认为这是最好的.但是,由于我在一个子例程中工作,因此以我的问题的属性冲突错误结尾.

This is the fastest method. Nothing changes in the memory and I thought it is the best. However, it ends with attribute conflict errors for my problem, because I am working inside a subroutine.

  1. 使用 Pointer 属性:

然后我尝试了指针.但是,似乎不可能将第二等级数组重新映射到第一等级数组.将第一级数组重新映射为第二级数组可以正常工作.

I have tried pointer then. But, it seems that it is not possible to remap a 2nd rank array into a 1st rank array. Remapping 1st rank to 2nd rank arrays works fine.

我编写的简单代码将第一级数组重新映射为第二级数组:

The simple code, I wrote to remap a 1st rank array into a 2nd rank array :

program ptrtest
real, pointer :: a(:)
real, pointer :: b(:,:)

allocate(b(1:2,1:3))
b = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /), shape(b)))
a(1:6) => b(:,:)

WRITE(*,*) a(4), b(2,2) ! to see if the remapped elements are same?
end program ptrtest

我收到的错误:

gfortran -Wall -o "POINTER" "POINTER.f90" (in directory: /home/vahid/Desktop)
POINTER.f90:12.14:
a(1:6) => b(:,:)
          1
Error: Rank remapping target must be rank 1 or simply contiguous at (1)
Compilation failed.
  1. RESHAPE 语句:

最慢的方法,可以执行任何类型的转换.基本上,它会为转换后的元素分配另一个存储位置,这既昂贵又要考虑内存效率和处理成本.

The slowest method which is able to do any type of transition. Basically, it assigns another memory locations for the transitioned element which is expensive, considering both memory efficiency and processing costs.

因此,Fortran 2003手册指出:(第2.2.4和5.2节)

数据对象的大小,形状,类型或长度类型参数可能是动态的,但不是等级或种类类型参数.

我不知道结果如何,但我认为数组的等级也应该是动态的.如果有任何错误,请更正.

I don't know the consequences, but I think the rank of arrays should be dynamic also. Please correct if any part is wrong.

这篇关于Fortran:哪种方法可以更快速地更改数组的排名?(重塑与指针)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 06:12