You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将分箱计数结果存入一维数组(Fortran代码优化)

Fortran分箱计数代码优化问题

需求描述

我需要将每个分箱(bin1、bin2、bin3…)的计数结果存入一维数组,当前代码中的if语句过于冗余,急需优化。具体需求是:

  • 统计4列数据(b、c、d、e)中数值落在指定区间的次数
  • 每个分箱的计数单独存入对应一维数组(如bin1计数存binb数组,bin2存binc数组等)
  • 分箱范围统一为-3到3,步长0.3,共20个分箱
  • 原本用80个if语句实现了功能,希望通过数组和count函数简化代码

问题现状

参考建议定义了lower和upper数组存储分箱区间,但调用对应索引的区间值时出错,当前代码如下:

program mean_analysis
    implicit none
    
    integer i, j, k, N, l
    double precision a, b, c, d, e
    integer binb(1:20),binc(1:20),bind(1:20),bine(1:20)
    real lower(1:20),upper(1:20)

    
    character(100) event
    
    upper(1)=-2.7
    lower(1)=-3
    

    
    
    open(unit = 7, file="zpc_initial_momenta.dat")
        do l=2,20
            lower(l)=lower(l-1)+.3
            upper(l)=upper(l-1)+.3  
        end do
        
        do k=1, 10
            read(7,'(A)') event
            do j=1,4000
            read(7,*) a, b, c, d, e
            do i=1,20
        binb(i)=binb(i)+count(b>=lower(i:) .and. b<upper(:i))
        binc(i)=binc(i)+count(c>=lower(i:) .and. c<upper(:i))
        bind(i)=bind(i)+count(d>=lower(i:) .and. d<upper(:i))
        bine(i)=bine(i)+count(e>=lower(i:) .and. e<upper(:i))   
        
        end do
        end do
        end do
                
    close(7)
            
    open(unit = 8, file="outputanalysis.dat")
        Write(8,*) 'The bins in each column are as follows:'
        Write(8,*) 'FIRST COLUMN (MOMENTUM IN X DIRECTION)'
        write(8,*) binb
        
    close(8)
    
end program

问题分析

  1. count函数用法错误:lower(i:)和upper(:i)是长度不匹配的数组切片,而当前是单个数值与单个分箱区间比较,不需要用数组切片,直接调用lower(i)和upper(i)即可。
  2. 分箱计数数组未初始化:Fortran默认不会将整数数组初始化为0,未初始化的binb、binc等数组会包含随机值,导致计数结果错误。
  3. 分箱区间初始化逻辑冗余:手动设置第一个分箱的上下限容易出错,直接通过循环计算更简洁可靠。

修正后的代码

program mean_analysis
    implicit none
    
    integer i, j, k, l
    double precision a, b, c, d, e
    integer binb(1:20), binc(1:20), bind(1:20), bine(1:20)
    real lower(1:20), upper(1:20)
    character(100) event
    
    ! 初始化所有分箱计数数组为0,避免随机初始值干扰
    binb = 0
    binc = 0
    bind = 0
    bine = 0
    
    ! 批量初始化分箱区间:从-3开始,步长0.3,共20个分箱
    do l = 1, 20
        lower(l) = -3.0 + (l-1)*0.3
        upper(l) = lower(l) + 0.3
    end do
    
    open(unit = 7, file="zpc_initial_momenta.dat")
        do k = 1, 10
            read(7,'(A)') event
            do j = 1, 4000
                read(7,*) a, b, c, d, e
                ! 遍历每个分箱,判断当前数值是否在区间内并计数
                do i = 1, 20
                    if (b >= lower(i) .and. b < upper(i)) binb(i) = binb(i) + 1
                    if (c >= lower(i) .and. c < upper(i)) binc(i) = binc(i) + 1
                    if (d >= lower(i) .and. d < upper(i)) bind(i) = bind(i) + 1
                    if (e >= lower(i) .and. e < upper(i)) bine(i) = bine(i) + 1
                end do
            end do
        end do
    close(7)
            
    open(unit = 8, file="outputanalysis.dat")
        write(8,*) '各列分箱统计结果如下:'
        write(8,*) '第一列(X方向动量)'
        write(8,*) binb
        write(8,*) '第二列(Y方向动量)'
        write(8,*) binc
        write(8,*) '第三列(Z方向动量)'
        write(8,*) bind
        write(8,*) '第四列(总动量)'
        write(8,*) bine
    close(8)
    
end program

优化说明

  • 初始化分箱计数数组为0,彻底解决随机初始值导致的计数错误。
  • 简化分箱区间初始化逻辑,通过循环直接计算每个分箱的上下限,避免手动设置的误差。
  • 替换错误的count函数用法,改用直接的if判断——单个数值与单个区间比较时,这种写法更高效且易读。
  • 补充了其他列的输出,让结果更完整。

内容的提问来源于stack exchange,提问作者Garrett Leigh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:17:19