Fortran循环,再次求教大神,有数据和code,多谢!

f
ftmit
楼主 (未名空间)

首先多谢各路大神在我前边帖子中的建议和帮助!

还是那个如何设计fortran循环体能节省计算时间的问题。我试了一下,计算速度还是
太慢,这次把具体的数据形式和code贴出来,恳请各路大神出手相助,非常着急出结果,灌水paper,先谢谢了。

1,表一是控制参数,共29个参数,tt1,tt2,tt3,...,tt29,每个参数有1100个数据

2,表二是备选数据,除了第一列的流速(FV)之外,其余的29列参数uu1,uu2,uu3,...,uu29.和表一中的29个控制参数tt1,tt2,tt3,...,tt29,在物理意义上是一样的,可以理解为一一对应关系,每列有34000000个数据

3,需要找出表二中满足如下条件的全部流速值,FV(i)

条件1:该流速值所对应的参数值,大于在表一中所相对应参数的最小值,小于最大值。

条件2:该流速值的选取,不但要单独判断这29个参数,而且还要判断这29个参数的全部组合,每种组合都以组合的参数之和作为判据。(即,在29个参数中,取1个,2个,3个,...29个参数的情况,表一参数tt共有536870911种,表二参数uu也有536870911种
,它们是一一对应的,组合数计算在表三)。

条件3:流速FV的选取,必须同时满足这29个参数全部组合的最大最小值要求

4,总结一下,就是根据表一各参数的最大值和最小值,确定表二中相对应参数的范围
,从而挑选出表二的流速值。问题是要求考虑29个参数的全部组合,实在太大了,到底应该怎样设计这个结构,才能节约计算时间,恳请各路大神出手指点迷津,多谢了!

................................................
多谢蝗虫的帮助!补充以下三点:

1,tt和uu每列都要对应,它们的组合也要对应。

tt本身,行也要对应,即,对于任意一行,tt1,tt2,tt3,...,tt29, 都要保持在同一行上,至于行号,就无所谓上下了。

uu也一样,行也要对应,即,对于任意一行,uu1,uu2,uu3,...,uu29, 还有那个流速FV,都要保持在同一行上,至于行号,就无所谓上下了。

2, 29个参数合并的问题,举个列子您就明白了。

比如: tt1和tt2合并,有tt(:)=tt1(:)+tt2(:),这其实就相当于,比在表中的那29个参数基础之上,又多出了一个参数了。因为tt1(:)+tt2(:)的最小值,并不等于,tt1(:)的最小值加上tt2(:)的最小值,最大值也同理。

3, 被拒绝过一次的FV,可以直接跳过下一次的筛选

已经被选上一次的FV,必须要经过下一次筛选,因为最终的FV是要满足所有的组合要求。
............................................

另,

我的做法是这样的:把29个参数的全部组合(共有536870911种),按取1个,2个,3个,...29个参数的情况分成29份(如表三中所列),分开计算,同时也能把34000000这个数值逐次降低,以求加快速度,但还是太慢了。具体code如下:

第一步:考虑29个参数组合(1种可能)
maxtt = maxval(tt(:,1)+tt(:,2)+tt(:,3)+...tt(:,29))
mintt = minval(tt(:,1)+tt(:,2)+tt(:,3)+...tt(:,29))
uuu(:) = uu(:,1)+uu(:,2)+uu(:,3)+...uu(:,29)
C
do i = 1, 34000000
if ((uuu(i).lt.mintt).or.(uuu(i).gt.maxtt)) then
FV(i) = 0
else
endif
enddo
C
n1 = 0
do i = 1, 34000000
if (FV(i).ne.0) then
n1 = n1 + 1
FV(n1) = FV(i)
C
do j = 1, 29
uu(n1,j) = uu(i,j)
enddo
else
endif
enddo

第二步:考虑28个参数组合(29种可能)
do i1 = 1, 2
do i2 = i1+1, 3
do i3 = i2+1, 4
do i4 = i3+1, 5
do i5 = i4+1, 6
do i6 = i5+1, 7
do i7 = i6+1, 8
do i8 = i7+1, 9
do i9 = i8+1, 10
do i10 = i9+1, 11
do i11 = i10+1, 12
do i12 = i11+1, 13
do i13 = i12+1, 14
do i14 = i13+1, 15
do i15 = i14+1, 16
do i16 = i15+1, 17
do i17 = i16+1, 18
do i18 = i17+1, 19
do i19 = i18+1, 20
do i20 = i19+1, 21
do i21 = i20+1, 22
do i22 = i21+1, 23
do i23 = i22+1, 24
do i24 = i23+1, 25
do i25 = i24+1, 26
do i26 = i25+1, 27
do i27 = i26+1, 28
do i28 = i27+1, 29
maxtt = maxval(tt(:,i1)+tt(:,i2)+tt(:,i3)+...tt(:,i28))
mintt = maxval(tt(:,i1)+tt(:,i2)+tt(:,i3)+...tt(:,i28))
uuu(1:n1)=uu(1:n1,i1)+uu(1:n1,i2)+uu(1:n1,i3)+...+uu(1:n1,i28)
C
do i = 1, n1
if ((FV(i).eq.0).or.(uuu(i).lt.mintt).or.(uuu(i).gt.maxtt)) then
FV(i) = 0
else
endif
enddo
......
enddo
C
n2 = 0
do i = 1, n1
if (FV(i).ne.0) then
n2 = n2 + 1
FV(n2) = FV(i)
C
do j = 1, 29
uu(n2,j) = uu(i,j)
enddo
else
endif
enddo
第三步:考虑1个参数组合(29种可能)
......
第四步:考虑27个参数组合(407种可能)
.......
第五步:考虑2个参数组合(407种可能)
..........
第六步:考虑26个参数组合(3654种可能)
..........
第七步:考虑3个参数组合(3654种可能)
.........
.........
........
最后一步:考虑15个参数组合(77558760种可能)
.............

t
tofunao

你这样不如找个搞计算的合作, 然后给人家在paper上挂个名。
为啥一定要用Fortran呢? Fortran也可以跟c接口啊。
做了profiling analysis没有, 哪一步或几步是瓶颈,速度最慢?
【 在 ftmit (八戒) 的大作中提到: 】
: 首先多谢各路大神在我前边帖子中的建议和帮助!
: 还是那个如何设计fortran循环体能节省计算时间的问题。我试了一下,计算速度还是
: 太慢,这次把具体的数据形式和code贴出来,恳请各路大神出手相助,非常着急出结果
: ,灌水paper,先谢谢了。
: 1,表一是控制参数,共29个参数,tt1,tt2,tt3,...,tt29,每个参数有1100个数据
: 2,表二是备选数据,除了第一列的流速(FV)之外,其余的29列参数uu1,uu2,uu3,...
: ,uu29.和表一中的29个控制参数tt1,tt2,tt3,...,tt29,在物理意义上是一样的,可以
: 理解为一一对应关系,每列有34000000个数据
: 3,需要找出表二中满足如下条件的全部流速值,FV(i)
: 条件1:该流速值所对应的参数值,大于在表一中所相对应参数的最小值,小于最大
: ...................

H
Huangchong


没看懂怎么29个tt合并 但是 我觉得你至少应该 先把29个tt分别排序

如果后面的计算是求和的话 那岂不是只用知道每个tt列的最大值最小值就行了吗 干嘛还非得每
个都遍历一次

【 在 ftmit (八戒) 的大作中提到: 】
: 首先多谢各路大神在我前边帖子中的建议和帮助!
: 还是那个如何设计fortran循环体能节省计算时间的问题。我试了一下,计算速度还是
: 太慢,这次把具体的数据形式和code贴出来,恳请各路大神出手相助,非常着急出结果
: ,灌水paper,先谢谢了。
: 1,表一是控制参数,共29个参数,tt1,tt2,tt3,...,tt29,每个参数有1100个数据
: 2,表二是备选数据,除了第一列的流速(FV)之外,其余的29列参数uu1,uu2,uu3,...
: ,uu29.和表一中的29个控制参数tt1,tt2,tt3,...,tt29,在物理意义上是一样的,可以
: 理解为一一对应关系,每列有34000000个数据
: 3,需要找出表二中满足如下条件的全部流速值,FV(i)
: 条件1:该流速值所对应的参数值,大于在表一中所相对应参数的最小值,小于最大
: ...................

H
Huangchong

先把tt没列的最大最小值算出来 然后把tt按最大值排个序 按最小值排个序 然后不管怎么组合 最小值是参加组合的各列里拍最后的 最大值是参加组合的各列里排最前的 难道不是这样吗?

同样 uu先各列排序 然后要砍掉哪些 直接从排序后的数据里切 然后按组合取各种集合 集合也只用拿排序后的索引数纪录 既快又省

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 没看懂怎么29个tt合并 但是 我觉得你只是应该 先把29个tt分别排序 如果后面的
: 计算是求和的话 那岂不是只用知道每个tt列的最大值最小值就行了吗 干嘛还非得每
: 个都遍历一次
: ..

f
ftmit

tt这个并不废多少时间,时间都是废在那个34000000中挑选FV

另外,29个tt合并的问题,举个列子你就明白了。

比如: tt1和tt2合并,

那么,有tt(:)=tt1(:)+tt2(:)

这其实就相当于,比在表中的那29个参数基础之上,又多出了一个参数了。

因为tt(:)的最小值,并不等于,tt1(:)的最小值加上tt2(:)的最小值
tt(:)的最大值,并不等于,tt1(:)的最大值加上tt2(:)的最大值

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 没看懂怎么29个tt合并 但是 我觉得你至少应该 先把29个tt分别排序
: 如果后面的计算是求和的话 那岂不是只用知道每个tt列的最大值最小值就行了吗 干
: 嘛还非得每
: 个都遍历一次
: ..

H
Huangchong

你的tt每行都是要对应的吗?

【 在 ftmit (八戒) 的大作中提到: 】
: tt这个并不废多少时间,时间都是废在那个34000000中挑选FV
: 另外,29个tt合并的问题,举个列子你就明白了。
: 比如: tt1和tt2合并,
: 那么,有tt(:)=tt1(:)+tt2(:)
: 这其实就相当于,比在表中的那29个参数基础之上,又多出了一个参数了。
: 因为tt(:)的最小值,并不等于,tt1(:)的最小值加上tt2(:)的最小值
: tt(:)的最大值,并不等于,tt1(:)的最小值加上tt2(:)的最大值

f
ftmit

恩,这也是一种办法。但有个问题,每一种组合的排序是不一样的,这样排序还是要放进那个产生不同组合的循环之内,在这个循环之内,排序34000000数组,那也是一场噩梦。

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 先把tt没列的最大最小值算出来 然后把tt按最大值排个序 按最小值排个序 然后
: 不管怎么组合 最小值是参加组合的各列里拍最后的 最大值是参加组合的各列里排最
: 前的 难道不是这样吗?
: 同样 uu先各列排序 然后要砍掉哪些 直接从排序后的数据里切 然后按组合取各种
: 集合 集合也只用拿排序后的索引数纪录 既快又省

H
Huangchong

被拒绝过一次的FV 或者已经被选上过一次的FV 可以在后续的筛选里跳过吗?

【 在 ftmit (八戒) 的大作中提到: 】
: tt这个并不废多少时间,时间都是废在那个34000000中挑选FV
: 另外,29个tt合并的问题,举个列子你就明白了。
: 比如: tt1和tt2合并,
: 那么,有tt(:)=tt1(:)+tt2(:)
: 这其实就相当于,比在表中的那29个参数基础之上,又多出了一个参数了。
: 因为tt(:)的最小值,并不等于,tt1(:)的最小值加上tt2(:)的最小值
: tt(:)的最大值,并不等于,tt1(:)的最小值加上tt2(:)的最大值

f
ftmit

更正一下,刚才理解错了您的意思了

tt和uu每列都要对应,它们的组合也要对应。

tt本身,行也要对应,即,对于任意一行,tt1,tt2,tt3,...,tt29, 要保持在同一行上,至于行号,就无所谓上下了。

uu也一样,行也要对应,即,对于任意一行,uu1,uu2,uu3,...,uu29, 还有那个流速FV,要保持在同一行上,至于行号,就无所谓上下了。

不知道我表达清楚了没?

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 你的tt每行都是要对应的吗?

f
ftmit

被拒绝过一次的FV,可以直接跳过下一次的筛选

已经被选上一次的FV,必须要经过下一次筛选,因为最终的FV是要满足所有的组合要求。

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 被拒绝过一次的FV 或者已经被选上过一次的FV 可以在后续的筛选里跳过吗?

H
Huangchong

明白了

【 在 ftmit (八戒) 的大作中提到: 】
: 更正一下,刚才理解错了您的意思了
: tt和uu每列都要对应,它们的组合也要对应。
: tt本身,行也要对应,即,对于任意一行,tt1,tt2,tt3,...,tt29, 要保持在同一行上
: ,至于行号,就无所谓上下了。
: uu也一样,行也要对应,即,对于任意一行,tt1,tt2,tt3,...,tt29, 还有那个流速FV
: ,要保持在同一行上,至于行号,就无所谓上下了。
: 不知道我表达清楚了没?

H
Huangchong

那就利用拒绝来加速筛选

循环的时候从限制性最强的条件开始筛
比如 先找到tt每列的极值 然后从极值分布最小的单列开始拒绝uu 然后从极值最小的双列开始...最后才筛29列都考虑的 如果拒绝速度够快 应该可以明显加速筛选

【 在 ftmit (八戒) 的大作中提到: 】
: 被拒绝过一次的FV,可以直接跳过下一次的筛选
: 已经被选上一次的FV,必须要经过下一次筛选,因为最终的FV是要满足所有的组合要
求。

f
ftmit

我那个做法,就是利用拒绝加速,您看一下问题出在哪里?

第一步,先筛选29列组合一起的,这步只有1个组合循环×34000000个循环,因为有些
FV已经被拒绝了,所以34000000这个数值就降低一下(我测过了,第一步之后,下降到33843573)

第二步,在第一步筛选完之后的33843573基础上,做28个列组合,这步有29个组合循环x33843573.完事之后,再根据有些FV已经被拒绝了,把33843573这个数值又降低一下(下降到32452496)

依次类推,逐次降低那个34000000,但,等到了6个列组合,或者23个列组合的时候(
组合循环数4292145),仅仅就这一个组合,需要36个小时左右才能跑出过去,剩下的
那些更高的组合循环数,基本上就是噩梦了。

麻烦你看一下,到底哪里出问题了。

【 在 Huangchong (净坛使者) 的大作中提到: 】
: 那就利用拒绝来加速筛选
: 循环的时候从限制性最强的条件开始筛
: 比如 先找到tt每列的极值 然后从极值分布最小的单列开始拒绝uu 然后从极值最小
: 的双列开始...最后才筛29列都考虑的 如果拒绝速度够快 应该可以明显加速筛选
: 求。

H
Huangchong


单列的值区间应该比多列的窄 拒绝速度可能要快些 可以考虑先用单列 然后二列。。直到29列

再有 像以前说的 你可以把不同的组合放在不同的线程或者不同的机器上跑 反正它
们之间是完全独立的 分成多少份就加速多少倍

【 在 ftmit (八戒) 的大作中提到: 】
: 我那个做法,就是利用拒绝加速,您看一下问题出在哪里?
: 第一步,先筛选29列组合一起的,这步只有1个组合循环×34000000个循环,因为有些
: FV已经被拒绝了,所以34000000这个数值就降低一下(我测过了,第一步之后,下降到
: 33843573)
: 第二步,在第一步筛选完之后的33843573基础上,做28个列组合,这步有29个组合循环
: x33843573.完事之后,再根据有些FV已经被拒绝了,把33843573这个数值又降低一下(
: 下降到32452496)
: 依次类推,逐次降低那个34000000,但,等到了6个列组合,或者23个列组合的时候(
: 组合循环数4292145),仅仅就这一个组合,需要36个小时左右才能跑出过去,剩下的
: 那些更高的组合循环数,基本上就是噩梦了。
: ...................

f
ftmit

好的,我现在马上就试一下。

【 在 Huangchong(净坛使者) 的大作中提到: 】

: 单列的值区间应该比多列的窄 拒绝速度可能要快些 可以考虑先用单列 然后二列。。

: 直到29列

: 再有 像以前说的 你可以把不同的组合放在不同的线程或者不同的机器上跑
反正它

: 们之间是完全独立的 分成多少份就加速多少倍