Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

I put up my thumb... and it blotted out the planet Earth. -- Neil Armstrong


devel / comp.lang.fortran / Count function using defined array values

SubjectAuthor
* Count function using defined array valuesnano3174
+- Re: Count function using defined array valuesgah4
`- Re: Count function using defined array valuesEdmondo Giovannozzi

1
Re: Count function using defined array values

<9501c667-b315-4348-9b24-267ef2f999ffn@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=3338&group=comp.lang.fortran#3338

  copy link   Newsgroups: comp.lang.fortran
X-Received: by 2002:a05:622a:1001:b0:3ef:2db1:6e63 with SMTP id d1-20020a05622a100100b003ef2db16e63mr3942822qte.10.1682281492646;
Sun, 23 Apr 2023 13:24:52 -0700 (PDT)
X-Received: by 2002:ac8:5e0e:0:b0:3e8:316e:3dd4 with SMTP id
h14-20020ac85e0e000000b003e8316e3dd4mr4277039qtx.11.1682281492502; Sun, 23
Apr 2023 13:24:52 -0700 (PDT)
Path: i2pn2.org!rocksolid2!i2pn.org!weretis.net!feeder6.news.weretis.net!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.fortran
Date: Sun, 23 Apr 2023 13:24:52 -0700 (PDT)
In-Reply-To: <72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2601:602:9700:4689:a59c:dbd4:d2fc:1a3f;
posting-account=gLDX1AkAAAA26M5HM-O3sVMAXdxK9FPA
NNTP-Posting-Host: 2601:602:9700:4689:a59c:dbd4:d2fc:1a3f
References: <72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <9501c667-b315-4348-9b24-267ef2f999ffn@googlegroups.com>
Subject: Re: Count function using defined array values
From: gah4@u.washington.edu (gah4)
Injection-Date: Sun, 23 Apr 2023 20:24:52 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 3123
 by: gah4 - Sun, 23 Apr 2023 20:24 UTC

On Sunday, April 23, 2023 at 12:01:20 PM UTC-7, nano3174 wrote:
> This program originally was a test program to see if I could count numbers
> in a specific range. Now I am making a program to do the same thing,
> but for 4 different columns separately (20 bins for each column b,c,d,e.)
> So, for column b I want 20 bins with the complete bin range going from (-3 to 3).
> For example, bin1 for column b will count how many numbers in that column
> are in the range (-3 to -2.7), bin2 would count for the range (-2.7, -2.4), etc..
> I want the bin width and each bin range to be the same for each column so
> that each column is counted for the same ranges.

> Originally, I had a horribly inefficient program (which worked) but in the end
> I had 80 if statements (20 for each column.) I wanted to see if I could use
> arrays and the count function to reduce it to just 4 lines.
> I have seen suggestions in the comments to have an array which looks like:

It should work with scalar instead of arrays for upper and lower.

Maybe it isn't a problem in your case, but some worry about cumulative
rounding, adding the binary representation of 0.3 multiple times.

Otherwise, I might have done:

bin = 20.0*(b(k)-(-3.0))/(3.0-(-3.0))+1
if(bin>=1 .and. bin <=20) binb(bin) = binb(bin) +1

The above statements are done once, instead of 20 times,
though each one might take longer than one of the comparisons,
it should be faster than 20. (You need that for each of
b, c, d, e, though it might also be done in a loop.)

At the beginning you mentioned efficiency, but I believe that your
program does just as much comparing and assigning as the
version with 80 if statements.

In fact, loop unrolling is an optimization that some compilers
(and people) do, replacing loops with separate statements.

Count function using defined array values

<72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=3339&group=comp.lang.fortran#3339

  copy link   Newsgroups: comp.lang.fortran
X-Received: by 2002:ac8:5a54:0:b0:3ef:3da0:5de7 with SMTP id o20-20020ac85a54000000b003ef3da05de7mr3868837qta.12.1682276479286;
Sun, 23 Apr 2023 12:01:19 -0700 (PDT)
X-Received: by 2002:a05:6214:bd1:b0:5ef:4789:6c33 with SMTP id
ff17-20020a0562140bd100b005ef47896c33mr2101911qvb.2.1682276478989; Sun, 23
Apr 2023 12:01:18 -0700 (PDT)
Path: i2pn2.org!rocksolid2!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.fortran
Date: Sun, 23 Apr 2023 12:01:18 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=75.110.65.170; posting-account=KpmLlAoAAADce00Wtw_rV8Xryp6Apl4H
NNTP-Posting-Host: 75.110.65.170
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>
Subject: Count function using defined array values
From: sparklezaxe152@gmail.com (nano3174)
Injection-Date: Sun, 23 Apr 2023 19:01:19 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: nano3174 - Sun, 23 Apr 2023 19:01 UTC

This program originally was a test program to see if I could count numbers in a specific range. Now I am making a program to do the same thing, but for 4 different columns separately (20 bins for each column b,c,d,e.) So, for column b I want 20 bins with the complete bin range going from (-3 to 3). For example, bin1 for column b will count how many numbers in that column are in the range (-3 to -2.7), bin2 would count for the range (-2.7, -2.4), etc.. I want the bin width and each bin range to be the same for each column so that each column is counted for the same ranges. Originally, I had a horribly inefficient program (which worked) but in the end I had 80 if statements (20 for each column.) I wanted to see if I could use arrays and the count function to reduce it to just 4 lines. I have seen suggestions in the comments to have an array which looks like:

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))

but lower and upper must be arrays instead of scalars... Here is my program thus far:

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

I have tried to remedy the lower - upper scalar issue by implementing an idea someone had on another post of mine, to make lower-> lower(I:) and upper -> upper(:I) , but it does not use the correct i-th values for the upper and lower arrays that I defined earlier with a do loop. Any suggestions or help is greatly appreciated. Thank you!

Re: Count function using defined array values

<487b89fc-d9e6-4c7d-81f6-b5ace6060de1n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=3351&group=comp.lang.fortran#3351

  copy link   Newsgroups: comp.lang.fortran
X-Received: by 2002:a05:620a:11bb:b0:74e:2afd:f91f with SMTP id c27-20020a05620a11bb00b0074e2afdf91fmr871560qkk.7.1682681412458;
Fri, 28 Apr 2023 04:30:12 -0700 (PDT)
X-Received: by 2002:ac8:5eca:0:b0:3ef:26ed:cb2f with SMTP id
s10-20020ac85eca000000b003ef26edcb2fmr2606447qtx.3.1682681411922; Fri, 28 Apr
2023 04:30:11 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.fortran
Date: Fri, 28 Apr 2023 04:30:11 -0700 (PDT)
In-Reply-To: <72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=192.107.52.63; posting-account=2VbiMAoAAADZ_2MR3YxvYmpYWYw9FTXX
NNTP-Posting-Host: 192.107.52.63
References: <72d5fd55-7c84-497a-a377-676743d35820n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <487b89fc-d9e6-4c7d-81f6-b5ace6060de1n@googlegroups.com>
Subject: Re: Count function using defined array values
From: edmondo.giovannozzi@gmail.com (Edmondo Giovannozzi)
Injection-Date: Fri, 28 Apr 2023 11:30:12 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: Edmondo Giovannozzi - Fri, 28 Apr 2023 11:30 UTC

Il giorno domenica 23 aprile 2023 alle 21:01:20 UTC+2 nano3174 ha scritto:
> This program originally was a test program to see if I could count numbers in a specific range. Now I am making a program to do the same thing, but for 4 different columns separately (20 bins for each column b,c,d,e.) So, for column b I want 20 bins with the complete bin range going from (-3 to 3).. For example, bin1 for column b will count how many numbers in that column are in the range (-3 to -2.7), bin2 would count for the range (-2.7, -2.4), etc.. I want the bin width and each bin range to be the same for each column so that each column is counted for the same ranges. Originally, I had a horribly inefficient program (which worked) but in the end I had 80 if statements (20 for each column.) I wanted to see if I could use arrays and the count function to reduce it to just 4 lines. I have seen suggestions in the comments to have an array which looks like:
>
> 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))
>
> but lower and upper must be arrays instead of scalars... Here is my program thus far:
>
> 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
>
> I have tried to remedy the lower - upper scalar issue by implementing an idea someone had on another post of mine, to make lower-> lower(I:) and upper -> upper(:I) , but it does not use the correct i-th values for the upper and lower arrays that I defined earlier with a do loop. Any suggestions or help is greatly appreciated. Thank you!

First of all I would define a subroutine that will update the bin count, so in the loop you will just call this subroutine.

do j=1,4000
read(7,*) a, b, c, d, e
call update_bin_count(a, bina, lower, upper)
call update_bin_count(b, binb, lower, upper)
call update_bin_count(c, binc, lower, upper)
call update_bin_count(d, bind, lower, upper)
call update_bin_count(e, bine, lower, upper)
end do

As suggested before I will use:

bin = 20.0*(b(k)-(-3.0))/(3.0-(-3.0))+1
if(bin>=1 .and. bin <=20) binb(bin) = binb(bin) +1

inside the update_bin_count if the bins are regular, otherwise a simple loop will be fine:

subroutine update_bin_count(v, bin, lower, upper)
real v, bin(:), lower(:), upper(:)
integer :: i
do i = 1, size(bin)
if (v >= lower(i) .and. v < upper(i)) then
bin(i) = bin(i) + 1
exit
endif
enddo
end subroutine

The routine should be inside a module otherwise is not going to work as it is using assumed shape arrays.
By the way, every Fortran routine should be defined inside a module in a new software.
Now this is scaling as the number of elements by the number of bins as you can see.

If you have a huge number of elements and a huge number of irregular bins, you may need a different algorithm.

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor