Fortran 77 compilation for IRI 2016 model - fortran
I've been trying to compile the IRI model lately, somewhat unsuccessfully. I've downloaded the IRI 2016 + common files + indices files, and using the test file to, well, test. I'm using gfortran (though the code is in fortran 77) with the -std=legacy flag (to remove unnecessary warnings, but I think the code is compiled as fortran 2003 or something). The linking/compilation command I'm using is:
gfortran -std=legacy -o iri iritest.for irisub.for irifun.for iritec.for iridreg.for igrf.for cira.for iriflip.for
This gives me the iri.exe executable, and yields a few warnings of the form:
Warning: Array reference at (1) out of bounds in loop beginning at (2)
(at compile time).
When I run the executable and enter the inputs through the console, I'm getting the following flags:
Note: The following floating-point exceptions are signalling: IEEE_UNDERFLOW_FLAG IEEE_DENORMAL
and the code apparently does what it's supposed to (outputs a nonempty file named fort.7 with the results). I've read that the IEEE flags I'm getting are rather common, and that I can disregard them, but the out of range warnings are a bit more concerning to me.
I'm also getting the following warnings:
igrf.for:298:10:
296 | DO 3 N=3,3333
| 2
297 | C*****CORRECTOR (FIELD LINE TRACING)
298 | P(1,N)=P(1,N-1)+STEP12*(5.*P(4,N)+8.*P(4,N-1)-P(4,N-2))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:298:17:
296 | DO 3 N=3,3333
| 2
297 | C*****CORRECTOR (FIELD LINE TRACING)
298 | P(1,N)=P(1,N-1)+STEP12*(5.*P(4,N)+8.*P(4,N-1)-P(4,N-2))
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:298:37:
296 | DO 3 N=3,3333
| 2
297 | C*****CORRECTOR (FIELD LINE TRACING)
298 | P(1,N)=P(1,N-1)+STEP12*(5.*P(4,N)+8.*P(4,N-1)-P(4,N-2))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:298:47:
296 | DO 3 N=3,3333
| 2
297 | C*****CORRECTOR (FIELD LINE TRACING)
298 | P(1,N)=P(1,N-1)+STEP12*(5.*P(4,N)+8.*P(4,N-1)-P(4,N-2))
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:298:56:
296 | DO 3 N=3,3333
| 2
297 | C*****CORRECTOR (FIELD LINE TRACING)
298 | P(1,N)=P(1,N-1)+STEP12*(5.*P(4,N)+8.*P(4,N-1)-P(4,N-2))
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:299:10:
296 | DO 3 N=3,3333
| 2
......
299 | P(2,N)=P(2,N-1)+STEP12*(5.*P(5,N)+8.*P(5,N-1)-P(5,N-2))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:299:17:
296 | DO 3 N=3,3333
| 2
......
299 | P(2,N)=P(2,N-1)+STEP12*(5.*P(5,N)+8.*P(5,N-1)-P(5,N-2))
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:299:37:
296 | DO 3 N=3,3333
| 2
......
299 | P(2,N)=P(2,N-1)+STEP12*(5.*P(5,N)+8.*P(5,N-1)-P(5,N-2))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:299:47:
296 | DO 3 N=3,3333
| 2
......
299 | P(2,N)=P(2,N-1)+STEP12*(5.*P(5,N)+8.*P(5,N-1)-P(5,N-2))
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:299:56:
296 | DO 3 N=3,3333
| 2
......
299 | P(2,N)=P(2,N-1)+STEP12*(5.*P(5,N)+8.*P(5,N-1)-P(5,N-2))
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:302:10:
296 | DO 3 N=3,3333
| 2
......
302 | P(8,N)=STEP2*(P(1,N)*P(4,N)+P(2,N)*P(5,N))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:302:24:
296 | DO 3 N=3,3333
| 2
......
302 | P(8,N)=STEP2*(P(1,N)*P(4,N)+P(2,N)*P(5,N))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:302:31:
296 | DO 3 N=3,3333
| 2
......
302 | P(8,N)=STEP2*(P(1,N)*P(4,N)+P(2,N)*P(5,N))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:302:38:
296 | DO 3 N=3,3333
| 2
......
302 | P(8,N)=STEP2*(P(1,N)*P(4,N)+P(2,N)*P(5,N))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:302:45:
296 | DO 3 N=3,3333
| 2
......
302 | P(8,N)=STEP2*(P(1,N)*P(4,N)+P(2,N)*P(5,N))
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:303:13:
296 | DO 3 N=3,3333
| 2
......
303 | C0=P(1,N-1)**2+P(2,N-1)**2
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:303:25:
296 | DO 3 N=3,3333
| 2
......
303 | C0=P(1,N-1)**2+P(2,N-1)**2
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:304:13:
296 | DO 3 N=3,3333
| 2
......
304 | C1=P(8,N-1)
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:305:14:
296 | DO 3 N=3,3333
| 2
......
305 | C2=(P(8,N)-P(8,N-2))*0.25
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:305:21:
296 | DO 3 N=3,3333
| 2
......
305 | C2=(P(8,N)-P(8,N-2))*0.25
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:306:14:
296 | DO 3 N=3,3333
| 2
......
306 | C3=(P(8,N)+P(8,N-2)-C1-C1)/6.0
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:306:21:
296 | DO 3 N=3,3333
| 2
......
306 | C3=(P(8,N)+P(8,N-2)-C1-C1)/6.0
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:307:13:
296 | DO 3 N=3,3333
| 2
......
307 | D0=P(6,N-1)
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:308:14:
296 | DO 3 N=3,3333
| 2
......
308 | D1=(P(6,N)-P(6,N-2))*0.5
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:308:21:
296 | DO 3 N=3,3333
| 2
......
308 | D1=(P(6,N)-P(6,N-2))*0.5
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:309:14:
296 | DO 3 N=3,3333
| 2
......
309 | D2=(P(6,N)+P(6,N-2)-D0-D0)*0.5
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:309:21:
296 | DO 3 N=3,3333
| 2
......
309 | D2=(P(6,N)+P(6,N-2)-D0-D0)*0.5
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:310:13:
296 | DO 3 N=3,3333
| 2
......
310 | E0=P(7,N-1)
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
igrf.for:311:14:
296 | DO 3 N=3,3333
| 2
......
311 | E1=(P(7,N)-P(7,N-2))*0.5
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:311:21:
296 | DO 3 N=3,3333
| 2
......
311 | E1=(P(7,N)-P(7,N-2))*0.5
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:312:14:
296 | DO 3 N=3,3333
| 2
......
312 | E2=(P(7,N)+P(7,N-2)-E0-E0)*0.5
| 1
Warning: Array reference at (1) out of bounds (3333 > 100) in loop beginning at (2)
igrf.for:312:21:
296 | DO 3 N=3,3333
| 2
......
312 | E2=(P(7,N)+P(7,N-2)-E0-E0)*0.5
| 1
Warning: Array reference at (1) out of bounds (3331 > 100) in loop beginning at (2)
igrf.for:314:15:
296 | DO 3 N=3,3333
| 2
......
314 | 4 T=(Z-P(3,N-1))/STEP
| 1
Warning: Array reference at (1) out of bounds (3332 > 100) in loop beginning at (2)
This is what I'm getting with gfortran compiler. I don't get any when using the Intel Fortran compiler.
Now, when I'm trying to compile the same model with a custom script instead of the test script in iritest.for, I get the same out of range warnings at compile time and a few errors at runtime, as well as a fort.7 file containing only -1s (which is the value for "no value/result"). The errors/flags at runtime are:
Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG
and
201301** OUT OF RANGE **
The file IG_RZ.DAT which contains the indices Rz12 and IG12
currently only covers the time period (yymm) : 0- 0
In that custom script I'm only calling the subroutine IRI_SUB present in the irisub.for file, with inputs declared within the script+read from a text file. I've made sure to include the lines that are mandatory to include (see iritest.for). The inputs from the text file are indeed read (verified with a few WRITE). I know the custom script worked at some point in time because it's from a thesis made in the laboratory I'm currently working for. I've run out of ideas as of what I can try to debug this. I've tried the same with IRI 2012 and I'm getting the exact same flags/warnings/errors. Has anyone any idea of what I can try next?
EDIT: I've been able to get the custom script to yield results, but I'm not sure they are the right ones, since I've used the Intel Fortran compiler (and this one does not give me any warning anymore).
Related
How to increase the verbosity level of SCIP solver log
I have the following SCIP solver log time | node | left |LP iter|LP it/n| mem |mdpt |frac |vars |cons |cols |rows | 0.0s| 1 | 0 | 4 | - | 6k| 0 | 0 | 6 | 200 | 6 | 200 | 0.0s| 1 | 0 | 7 | - | 6k| 0 | 0 | 8 | 200 | 8 | 200 | 0.0s| 1 | 0 | 10 | - | 6k| 0 | 0 | 9 | 200 | 9 | 200 | 0.0s| 1 | 0 | 10 | - | 6k| 0 | 0 | 9 | 200 | 9 | 200 | 0.0s| 1 | 0 | 10 | - | 6k| 0 | 0 | 9 | 200 | 9 | 200 | 0.0s| 1 | 0 | 10 | - | 6k| 0 | 0 | 9 | 200 | 9 | 200 | I want the log to be more verbose, as in display a new line at each LP iteration. So far I only came across SCIP_CALL( SCIPsetIntParam(scip, "display/verblevel", 5)); This is increasing but not as much as I want and not where I want. Essentially I would like to have lines at LP iter 4, 5, 6, 7, 8, 9 and 10 too.
You cannot print a line of SCIP output at every LP iteration. You can set display/freq to 1, then SCIP will display a line at every node. Additionally you can set display/lpinfo to true, then the LP solver will print additional information. I don't think any LP solver will print you a line for every LP iteration though . Do you use SCIP with SoPlex? Edit: Looked and you can set the SoPlex frequency to 1 with the parameter "--int:displayfreq". I don't think you can set this through the SCIP api though. If you only want to solve the LP you could just do it in SoPlex or you would have to edit the lpi_spx2 source code.
Plot graph from within Mata
Consider the following toy matrix in mata: mata: A 1 2 +-----------------+ 1 | 6555 140 | 2 | 7205 135 | 3 | 6255 140 | 4 | 7272 138 | 5 | 10283 133 | 6 | 8244 136 | 7 | 6909 144 | 8 | 7645 138 | 9 | 12828 134 | 10 | 6538 137 | +-----------------+ If I want to draw a scatter plot using this matrix, I first need to transfer it to Stata and then also convert it to variables with the svmat command: mata: st_matrix("A", A) svmat A list, separator(0) +-------------+ | A1 A2 | |-------------| 1. | 6555 140 | 2. | 7205 135 | 3. | 6255 140 | 4. | 7272 138 | 5. | 10283 133 | 6. | 8244 136 | 7. | 6909 144 | 8. | 7645 138 | 9. | 12828 134 | 10. | 6538 137 | +-------------+ twoway scatter A1 A2 Is there a way to directly draw the graph without leaving mata?
One can plot a mata matrix without first converting it to Stata variables as follows: twoway scatter matamatrix(A) See help twoway_mata for more details. Edit by #PearlySpencer: This can be run directly from within mata using the stata() function: mata: stata("twoway scatter matamatrix(A)")
An alternative approach is to use the community-contributed mata function mm_plot(): mata: mm_plot(A, "scatter") This is part of the moremata collection of functions and must thus be downloaded first: ssc install moremata
Creating a variable that increments by one if new value found in another
I have the following (sorted) variable: 35 35 37 37 37 40 I want to create a new variable which will increment by one when a new number comes up in the original variable. For example: 35 1 35 1 37 2 37 2 37 2 40 3 I thought about using the by or bysort commands but none of them seems to solve the problem. This looks like something many people need, but I couldn't find an answer.
You are just counting how often a value differs from the previous value. This works also for observation 1 as any reference to a value for observation 0 is returned as missing, so in your example 35 is not equal to missing. clear input x 35 35 37 37 37 40 end gen new = sum(x != x[_n-1]) list, sepby(new) +----------+ | x new | |----------| 1. | 35 1 | 2. | 35 1 | |----------| 3. | 37 2 | 4. | 37 2 | 5. | 37 2 | |----------| 6. | 40 3 | +----------+ by would be pertinent if you had blocks of observations to be treated separately. One underlying principle here is that true or false comparisons (here, whether two values are unequal) are evaluated as 1 if true and 0 is false.
#Nick beat me to it by a couple of minutes but here's another -cleaner- way of doing this: clear input foo 35 35 37 37 37 40 end egen counter = group(foo) list +---------------+ | foo counter | |---------------| 1. | 35 1 | 2. | 35 1 | 3. | 37 2 | 4. | 37 2 | 5. | 37 2 | |---------------| 6. | 40 3 | +---------------+ This approach uses the egen command and its associated group() function. There are also a couple of options for this function, with missing being perhaps the most useful. From the command's help file: "...missing indicates that missing values in varlist (either . or "") are to be treated like any other value when assigning groups, instead of as missing values being assigned to the group missing..." clear input foo 35 35 . 37 37 37 40 . end egen counter = group(foo), missing sort foo list +---------------+ | foo counter | |---------------| 1. | 35 1 | 2. | 35 1 | 3. | 37 2 | 4. | 37 2 | 5. | 37 2 | |---------------| 6. | 40 3 | 7. | . 4 | 8. | . 4 | +---------------+ Instead of: drop counter egen counter = group(foo) sort foo list +---------------+ | foo counter | |---------------| 1. | 35 1 | 2. | 35 1 | 3. | 37 2 | 4. | 37 2 | 5. | 37 2 | |---------------| 6. | 40 3 | 7. | . . | 8. | . . | +---------------+ Another option is label: "... The label option returns integers from 1 up according to the distinct groups of varlist in sorted order. The integers are labeled with the values of varlist or the value labels, if they exist..." Using the example without the missing values: egen counter = group(foo), label list +---------------+ | foo counter | |---------------| 1. | 35 35 | 2. | 35 35 | 3. | 37 37 | 4. | 37 37 | 5. | 37 37 | |---------------| 6. | 40 40 | +---------------+
Rolling sum with unbalanced panel with non-even times in Stata
I have an unbalanced daily panel where entries occur at uneven times. I would like to generate the rolling sum of some variable x over the past 365 days. I can think of two ways to do this, but the first is memory hungry and the second is processor hungry. Is there a third alternative that avoids these problems? Here are my two solutions. Is there a third solution without memory or speed problems? clear set obs 200 set seed 2001 /* panel variables */ generate id = 1 + int(2*runiform()) generate time = mdy(1, 1, 2000) + int(10*365*runiform()) format time %td duplicates drop xtset id time /* data */ generate x = runiform() /* first approach is to fill the panel with `tsfill` */ /* then remove "seasonality" with `s.` */ tsfill generate sx = sum(x) generate ssx = s365.sx /* second approach without `tsfill` */ /* but nested loop is fairly slow */ drop if missing(x) generate double ssx_alt = 0 forvalues i = 1/`= _N' { local j = `i' local delta = time[`i'] - time[`j'] while ((`j' > 0) & (`delta' < 365) & (id[`i'] == id[`j'])) { local x = cond(missing(x[`j']), 0, x[`j']) replace ssx_alt = ssx_alt + `x' in `i' local j = `j' - 1 local delta = time[`i'] - time[`j'] } }
The sum over the last # days is the difference between two cumulative sums, the cumulative sum to now and the cumulative sum to # days ago. The extension to panel data is easy, but not shown here. I don't think gaps disturb this principle once you have applied tsfill. . set obs 20 obs was 0, now 20 . gen t = _n . gen y = 100 + _n . gen sumy = sum(y) . tsset t time variable: t, 1 to 20 delta: 1 unit . gen diff = sumy - L10.sumy (10 missing values generated) . l +------------------------+ | t y sumy diff | |------------------------| 1. | 1 101 101 . | 2. | 2 102 203 . | 3. | 3 103 306 . | 4. | 4 104 410 . | 5. | 5 105 515 . | |------------------------| 6. | 6 106 621 . | 7. | 7 107 728 . | 8. | 8 108 836 . | 9. | 9 109 945 . | 10. | 10 110 1055 . | |------------------------| 11. | 11 111 1166 1065 | 12. | 12 112 1278 1075 | 13. | 13 113 1391 1085 | 14. | 14 114 1505 1095 | 15. | 15 115 1620 1105 | |------------------------| 16. | 16 116 1736 1115 | 17. | 17 117 1853 1125 | 18. | 18 118 1971 1135 | 19. | 19 119 2090 1145 | 20. | 20 120 2210 1155 | +------------------------+
add a new item to vector and shift it remaining part to right
I am trying to put a new item to vector, and shift remaining items. How can I do that ? Ex vector ------------------------------------------------------- | 1 | 2 | 3 | 4 | 5 | 9 | 10 | 15 | 21 | 34 | 56 | 99 | ------------------------------------------------------- ^ new item = 14, it should be added to ^ After insertion, vector ------------------------------------------------------------ | 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 21 | 34 | 56 | 99 | ------------------------------------------------------------ ^ ^ ^-shifted to right by one-^
Check the vector::insert() function. vector<int> vec ; // Add elements to vec vec.insert(vec.begin() + position, new_item);
Use insert. vector<int> v {1,2,3,5}; v.insert (v.begin() + 3, 4); //v is now {1,2,3,4,5} You can also insert ranges of elements and other cool stuff, similar to the vector constructor.
if you don't know the exact position you want to insert it then vec.insert() is not going to work well. vec.push_back(15); std::sort(vec.begin(), vec.end());