Fortran Coder

查看: 27167|回复: 28
打印 上一主题 下一主题

[讨论] 一个数组运算的问题

[复制链接]

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
跳转到指定楼层
楼主
发表于 2017-8-4 18:27:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
遇到一个数组片段的问题。

代码1:
do i=1,size(ia_index,2)
  ra_val(ia_index(1,i)) = ra_val(ia_index(1,i)) + ra_add(i)
  ra_val(ia_index(2,i)) = ra_val(ia_index(2,i)) + ra_add(i)
enddo

代码2:
  ra_val(ia_index(1,:)) = ra_val(ia_index(1,:)) + ra_add
  ra_val(ia_index(2,:)) = ra_val(ia_index(2,:)) + ra_add

我一直以为代码1和2得到的结果是一样的,今天遇到一个问题发现并不一样,代码1的结果是正确的,当ia_index(1,:)表示的某个下标索引出现1-2次的时候,两段代码结果一致,当出现3次的时候,代码1可以累加,代码2中ra_val索引指向的成员就只有最后一个值,没有累加。不知何故!

事实上,我最初使用代码2之前,由于不放心,是做过实验的:
[Fortran] 纯文本查看 复制代码
program main
 implicit none
   integer :: ia(5),ib(9)
   ia = [1,5,5,5,2]
   ib = 0
   ib(ia) = ib(ia) + [1,1,1,1,1]
   write(*,*) ib
   stop
 end program

结果见附件图片,无误,能够叠加我才这么写的,真是郁闷了...
还请大伙指点,先谢谢了!


aa.jpg (15.14 KB, 下载次数: 543)

aa.jpg
分享到:  微信微信
收藏收藏1 点赞点赞 点踩点踩

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2017-8-5 04:48:18 | 只看该作者
It's hard to check why ? May be we need more code !

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
板凳
 楼主| 发表于 2017-8-5 10:21:45 | 只看该作者
我编了一组数据:
[Fortran] 纯文本查看 复制代码
program main
implicit none
  real :: ra_val1(11),ra_val2(11),ra_add(9)
  integer :: ia_index(2,9)
  
  integer :: i
   
  ra_add = [0.014000,0.016500,0.016500,0.014000,0.014000,0.014750,0.014750,0.010750,0.010750]
  
  ia_index(:,1) = [ 1  , 2  ]
  ia_index(:,2) = [ 1  , 9  ]
  ia_index(:,3) = [ 1  , 11 ]
  ia_index(:,4) = [ 2  , 3  ]
  ia_index(:,5) = [ 3  , 4  ]
  ia_index(:,6) = [ 4  , 8  ]
  ia_index(:,7) = [ 4  , 10 ]
  ia_index(:,8) = [ 5  , 6  ]
  ia_index(:,9) = [ 6  , 7  ]
  

  
  ra_val1 = 0.
  ra_val2 = 0.
  
  ! 写法1
  do i=1,9
    ra_val1(ia_index(1,i)) = ra_val1(ia_index(1,i)) + ra_add(i)
    ra_val1(ia_index(2,i)) = ra_val1(ia_index(2,i)) + ra_add(i)
  enddo
  
  ! 写法2
  ra_val2(ia_index(1,:)) = ra_val2(ia_index(1,:)) + ra_add
  ra_val2(ia_index(2,:)) = ra_val2(ia_index(2,:)) + ra_add
  
  
  write(*,"(A6,2A12)") "No.","Val1","Val2"
  do i=1,11
    write(*,"(I6,2F12.6)") i,ra_val1(i),ra_val2(i)
  enddo
  
  stop
end program

aa.jpg (29.29 KB, 下载次数: 507)

aa.jpg

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
地板
 楼主| 发表于 2017-8-5 10:23:01 | 只看该作者
本帖最后由 andy8496 于 2017-8-5 10:27 编辑
fcode 发表于 2017-8-5 04:48
It's hard to check why ? May be we need more code !

上面的代码为什么写法1和2结果不同?理解不了,我认为结果应该是一样的,都是写法1的结果。还请老大赐教!

47

帖子

3

主题

0

精华

大师

F 币
1634 元
贡献
119 点

规矩勋章

5#
发表于 2017-8-5 15:52:06 | 只看该作者
本帖最后由 维尼猴 于 2017-8-5 15:58 编辑

哇塞,竟然能这样操作,但感觉可能和缓存的处理有关系吧

我试了一下,比如加个 中间变量  temp

[Fortran] 纯文本查看 复制代码
temp = ia_index(1,:)
ra_val3(temp ) = ra_val3(temp ) + ra_add


这样处理之后是可以累加的,可能是你数组声明成  2,9 的问题,内存不够连续??
来我试试  9,2 的

诶………………我试了一下,失败了,把  ia_index 交换了维数也没有得到对应效果

47

帖子

3

主题

0

精华

大师

F 币
1634 元
贡献
119 点

规矩勋章

6#
发表于 2017-8-5 16:00:59 | 只看该作者
我补充测试了一下,似乎下标数组不能取切片

[Fortran] 纯文本查看 复制代码
program main
implicit none
  integer :: ia(5),ib(9)
  ia = [1,5,5,5,2]
  ib = 0
  ib(ia) = ib(    ia  (:)   ) + [1,1,1,1,1]
  write(*,*) ib
  stop
end program


只是在你原来例子上给ia加了个切片操作,就不能累加了

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
7#
 楼主| 发表于 2017-8-5 21:29:22 | 只看该作者
唉,我都忘了我哪些地方用了这种写法,但是肯定不止目前发现的这个位置。真是郁闷了!
要是能通过什么编译选项能设置解决就好了!
谢了!

47

帖子

3

主题

0

精华

大师

F 币
1634 元
贡献
119 点

规矩勋章

8#
发表于 2017-8-6 16:07:59 | 只看该作者
andy8496 发表于 2017-8-5 21:29
唉,我都忘了我哪些地方用了这种写法,但是肯定不止目前发现的这个位置。真是郁闷了!
要是能通过什么编译 ...

我感觉这种有些“讨巧”的语法,还是少用心里更安一些呢

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

9#
发表于 2017-8-6 17:22:43 | 只看该作者
ia_index的第1行数据为啥非要设置重复元素?

131

帖子

34

主题

0

精华

宗师

F 币
1602 元
贡献
813 点
10#
 楼主| 发表于 2017-8-6 18:30:55 | 只看该作者
pasuka 发表于 2017-8-6 17:22
ia_index的第1行数据为啥非要设置重复元素?

这个是实际应用的需要。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-23 20:27

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表