Skip to content

Instantly share code, notes, and snippets.

@Mike3285
Created September 10, 2022 21:20
Show Gist options
  • Save Mike3285/61c07c312ee861a53346e9c9f92c0455 to your computer and use it in GitHub Desktop.
Save Mike3285/61c07c312ee861a53346e9c9f92c0455 to your computer and use it in GitHub Desktop.
for upwork
compile with Splus SHLIB -o filename.so ph2simon.f ....
cThis code is a "subroutine" and is meant to be called within another function by the subroutine's name
c All the arguments inside the parentheses () should be given when the subroutine is called, and be of the right datatype
c c Define the inputs for this subroutine
subroutine f2bdry(m, nmax, ep1, ep2, p0, p1, cp0, cp1, bdry, peten,
1 nmax1, bprob0, bprob1)
c------------------------------------------------------------------------------
c start variable declaration
implicit none
c to prevent confusion on variable types, see http://www.personal.psu.edu/jhm/f90/statements/implicit.html
c------------------------------------------------------------------------------
c integer values
integer m, nmax, bdry(nmax, 4), nmax1
c variables declared with double precision are floats with more significant numbers (fortran allocates more memory for these variables)
c we also declare the lenght of the arrays bprob0 and bprob1
c here we are declaring floating points numbers and arrays. Those with the parentheses are arrays, if there is more than one number
c it means the array is multi-dimensional (matrix)
double precision ep1, ep2, p0(m), p1(m), cp0(m), cp1(m), peten(nmax, 2),
1 bprob0(nmax1), bprob1(nmax1)
c this is for the variables that have only internal scope
double precision pet, ess, dn1, dn2, essn
integer i, n1, n2, n, r1, r, ind1, ind2, ind21, rr
c Starts the first cycle:
c the 100 tells me where the block of code ends, the number after the "do" is just a label used by old versions of fortran
c n=2, nmax tells me that the cycle stars with a variable n set to 2 and stops with n=nmax (gave me by input)
c the increment is 1 in ascendent order because of no specifications
c
c for the comments inside these nested cycles I will refer to a cycle by tells his stop line (the first parameter)
do 100 n = 2, nmax
c set the variable essn to be n converted into a float (with double of precision, so the dfloat)
essn = dfloat(n)
c for every cycle of the cycle100 we do another cycle with cursor n1 starting from "1" to "n-1" (increment=1)
c remember the "90" is just a label for the cycle
do 90 n1 = 1, n - 1
n2 = n - n1
c like the essn var, we convert n1 and n2 to floats and we assign then to "dn1" and "dn2"
dn1 = dfloat(n1)
dn2 = dfloat(n2)
c perform some operations with n1 and n2 and assign them to "ind1" and "ind2"
ind1 = n1 * (n1 + 3) / 2
ind2 = n2 * (n2 + 3) / 2
c another nested cycle for every cycle90 with "i" ranging from 1 to n+1
do 10 i=1, n + 1
c bprob0 and bprob1 are two arrays of floats given by input (see top). We know they must be arrays because here the program is trying
c to assign new values by accessing them by their index (so the brob0(i), i is the index)
c 0.0d0 means that I assign the variable to the zero-float, then I double the precision
c Direct assignment of a float would result in a standard precision float in memory (32), so we must declare it with this notation
c to increase the precision (64)
bprob0(i) = 0.0d0
bprob1(i) = 0.0d0
c here we have the stopline of the cycle10
10 continue
c declaring pet with double precision (like before)
pet = 1.0d0
c in this cycle50 we have another cursor we called "r1". Please note there is a third number in this cycle and it's negative.
c It's the step for the cycle and means this cycle is going to be "on reverse" and will cycle from "n1" to zero with steps -1
do 50 r1 = n1, 0, -1
ind21 = ind2
c Now we are taking the "pet" variable and we are assigning it a new value. The new value will be the old one minus the
c ind1-th element of the array p0 (given in the subroutine's input)
pet = pet - p0(ind1)
c Here we start with the cycle40, this one also has a negatie step and so it's iterating in reverse (from n2 + r1 to r1 with steps of -1)
do 40 r = n2 + r1, r1, -1
rr = r + 1
c Again like we did some lines before, we are assigning new values to an array by accessing them by their index. In this
c case the arrays are bprob0 and bprob1 at their position with index "rr" ("rr" should be an integer).
c We are assigning them their previous value plus the values in the arrays p"0 and "cp0" at the position in the parentheses
bprob0(rr) = bprob0(rr) + p0(ind1) * cp0(ind21)
c Same thing here for the other array, this time we are taking new values from the other arrays "p1" and "cp1"
bprob1(rr) = bprob1(rr) + p1(ind1) * cp1(ind21)
c decrease ind21 by 1 each iteration
ind21 = ind21 - 1
c Next is just a if, ".lt." can be confusing but it's just a old fortran way to use comparison operatorsc .lt. is just "lower than" so it can be replaced by "<"
c this if is checking if the element of "bprob0" at position "rr" is between two valuesc
c You can express this as "bprob0(rr) < ep1 and 1 -bprob0(rr) < ep2.
c The expression will evaluate to true when the two sides of the .and. evaluate both to true
c Uncomment the line below and comment the old one and will work anyway.
if ((bprob0(rr).lt.ep1) .and. (1-bprob1(rr).lt.ep2))
c if ((bprob0(rr) < ep1) .and. (1-bprob1(rr) < ep2))
1 then
c this code between then and endif will be executed only if the expression is true
c assigning a new value to "ess"
ess = dn1 + (1.0d0 - pet) * dn2
c as we did before, .lt. is just <
if (ess.lt.essn) then
c if (ess < essn) then
essn = ess
c "peten" should be given in input (see top of the script) and has two dimensions, so it's a matrix.
c First dimension has "nmax" items, and the second has two (see peten(nmax, 2) at top)
c so here we are just assigning new values to the internal matrixes of the arrays peten
peten(n, 1) = ess
peten(n, 2) = pet
csame as above, see bdry(nmax, 4) at the top of the script
bdry(n, 1) = r1 - 1
bdry(n, 2) = n1
bdry(n, 3) = r - 1
bdry(n, 4) = n
endif ! closing the first if
endif ! the second
40 continue ! closing cycle40
c after we finished doing cycle 40, we assingn to "rr" the value of r1 + 1
rr = r1 + 1
c here we start cycle 41
do 41 r = 1, r1, 1
c assign new values "bprob0(r1+1)" to the elements of bprob0 and bprob1 at position "r"
bprob0(r) = bprob0(r1+1)
bprob1(r) = bprob1(r1+1)
41 continue !cycle 41 ends
c after cycle 41 ends, we decrement "ind1" by 1
ind1 = ind1 -1
50 continue ! finishing cycle 50
90 continue ! finishing cycle 90
100 continue ! finishing cycle 100
return ! end of the program
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment