Created
September 10, 2022 21:20
-
-
Save Mike3285/61c07c312ee861a53346e9c9f92c0455 to your computer and use it in GitHub Desktop.
for upwork
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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