从Fortran

时间:2018-11-21 19:37:44

标签: arrays fortran

我想要一个数组从Fortran中的数组中删除某个索引值之后的所有行。这意味着,如果数组的大小最初为p,则它将变为q,其中q是将删除所有内容的索引。

有关代码如下:

real(8), allocatable :: circlesx(:),circlesy(:)
allocate(circlesx(n**2-n))
allocate(circlesy(n**2-n))

do i=1,n-1
    do j=i+1,n
        call intersect2circles(stlo(i),stla(i),distance(i),stlo(j),stla(j),distance(j),ax,ay,bx,by,flag)
        if (flag==0) then
            circlesx(k)=ax
            circlesy(k)=ay
            circlesx(k+1)=bx
            circlesy(k+1)=by
            k=k+2
        endif
    enddo
enddo

该标志基本上检查两个圆是否相交。因此,如果没有交集,则不会为数组circlesxcirclesy分配任何值。我首先分配的数组的大小是n个圆的交点的最大数量= n^2-n。如果不分配它们,则会出现细分错误。

Reshape也没有用,尽管我在那儿做错了。这产生了无法分类的语句错误:-

reshape(circlesx,[ n**2-n-1 ])

我希望循环完成后,圈子数组的大小更改为k-2

所以我需要的是,如果n = 2,那么circlex和circley的大小为2,那么

circlesx=[0,0]
.
.
some calculations
.
.
circlesx=[1.2,0] ! only one value has been allocated
.
.
reshape the array accordingly
.
.
circlesx=[1.2]

在Fortran中有什么方法可以做到这一点?我正在使用f90文件扩展名并使用gfortran v7.3.0

1 个答案:

答案 0 :(得分:5)

围绕数组动态调整大小的问题通常在乎扩大数组。那是更难的问题。 1

但是,基本的考虑是相同的。考虑

integer, allocatable :: arr(:)
allocate(arr(3))
arr = [1, 2, 3]

end

有了内在赋值,我们从其他地方看到我们可以写

integer, allocatable :: arr(:)
arr = [1, 2, 3]

end

,并将arr分配给正确的形状作为分配的一部分。

我们已经看到它可以:扩大数组

arr = [arr, 4]

删除“不良值”:

arr = PACK(arr, arr>1.and.arr<4)

仅选择前几个元素就很简单

arr = arr(:q)

编译器需要特殊标志来正确编译此类代码的日子正在慢慢过去,但确实(特别是如果使用旧版本的话)请查看编译器文档以了解如何确保自动分配在固有分配上发生。


1 即使在没有动态内存分配的日子里,也可以简单地处理“较短”的数组。取一个您需要的静态大小的数组,并对使用了多少个元素进行簿记。在现代代码中,使用旧库时可能会看到这种伪像。