i'm trying to write a Fortran file with arrays of 2000 elements each, every 1000 program steps. At first, I tried to write it in the following way:
if(i.eq.1000)
open (21,file='eedf.res',status='unknown',position='append')
write(21,121) (eedf(le),le=1,2000)
close (21)
i=0
.
.
.
(eedf is then put equal to zero and the array is rebuilt in the following 1000 steps; we are inside a do-loop).
It works,producing a file with the arrays printed on rows, but the program that i use to plot these functions tells me that there are too much columns, and so the last half of columns are lost...
So, I want to write eedf in columns, the first with eedf after the first 1000 program step, the second with eedf after the following 1000 program step, and so on. How can i do that?
eedf(1) eedf(1)
eedf(2) eedf(2)
.
.
eedf(2000) eedf(2000)
Sorry if i've been verbose, i tried to put it in the clearest way.
Thanks a lot!
Related
enter image description here
I have a table in OpenOffice that contains a column with region's codes (column J). Using table functions, how to get all codes that appear more than 5 times and write them in one cell?
Normally I would recommend breaking this problem down into smaller parts using helper columns. Or better yet, move the data into LibreOffice Base which can easily work with distinct values.
However, I managed to come up with a rather large formula that seems to do what you asked. Enter it as an array formula.
=TEXTJOIN(",";1;IF(COUNTIF(исходник.J$2:J$552;исходник.J2:J552)>5;IF(ROW(исходник.J2:J552)=MATCH(исходник.J2:J552;исходник.J$2:J$552;0)+ROW(J$2)-1;исходник.J2:J552;"")))
I can't test this on your actual data since your example is only an image, but let's say that there are six of both 77 and 37. Then this would show 77,37 as the result.
Here is a breakdown. Look up the functions in LibreOffice Online Help for more information.
=TEXTJOIN(",";1; — Join all results into a single cell, separated by commas.
IF(COUNTIF(исходник.J$2:J$552;исходник.J2:J552)>5; — Find codes that occur more than 5 times. This is the same as what you wrote.
IF(ROW(исходник.J2:J552)= — Compare the next result to the row number that we are currently looking at.
MATCH(исходник.J2:J552;исходник.J$2:J$552;0)+ROW(J$2)-1; — Determine the first row that has this code. We do this to get unique results instead of 6 or more of each code in the result.
исходник.J2:J552;""))) — Return the code. (Your formula simply returns 1 here, which doesn't seem to be what you want.) If it doesn't match, return an empty string rather than 0, because TEXTJOIN ignores empty strings.
I have a matrix A(3,4) in Fortran , I want to write it on a text file like this:
A(1,1) A(2,1) A(3,1)
A(1,2) A(2,2) A(3,2)
A(1,3) A(2,3) A(3,3)
A(1,4) A(2,4) A(3,4)
I use below code. It has two problems at first it is overwritten for each i and it is written in rows. I would be gratful to guide me to solve it. Thanks
do i=1,4
open (unit=10,file="out.txt",action="write")
write (10,*) A(1,i) , A(2,i) , A(3,i)
close (10)
As mentioned by Ian, your file is overwritten for each i because your open statement is inside the loop. Fortran is reopening the file fresh for each i. Move the open statement to before the loop so it is only opened once.
Of course it is written in rows because the first index in a 2-D array is the row index. You can switch the indices if you wish. On the other hand, according to your first box, it appears as though you want the rows across the columns.
You say you need to write just some elements. As long as they are in a contiguous block, you will want to use an implied do loop in the write statement. It is much more concise and you can write large blocks without typing out a lot of variables specifically. It would look like this:
open (unit=10,file="out.txt",action="write")
do i=1,4
write (10,*) (A(j,i), j=1,3)
end do
close (10)
Again, this reverses rows and columns, if you want traditional representation, switch the i and j.
I've been trying to solve the problem in the title. Specifically, I have a .txt file with a few hundred real numbers between 0 and 100, and I need to:
Read the file
Separate the numbers in two groups (one for numbers >= 50, other for numbers < 50)
Write two parallel, compact (no white spaces or zeroes) columns so that each one contains one list.
I've been trying to do that by using WRITE(*,*) statements and using the advance="no" parameter because using arrays didn't work for me. The thing is, I can't get the two columns to be parallel. How can that be done? I don't need the code, just a guideline on how to proceed.
I have a file which is a table of 119 columns (separated by spaces) and around 50000 rows (lines). I would like to remove the duplicated entries, i.e. those rows which have all identical columns (119). I sketched this code:
PROGRAM deldup
IMPLICIT NONE
DOUBLE PRECISION PAR(119),PAR2(119)
INTEGER I,J,K,LINE,TREP
CHARACTER filename*40
c Get the input file name
CALL getarg(1,filename)
c File where the results will be stored.
OPEN(29, FILE="result.dat", STATUS='UNKNOWN')
c Current line number
LINE=0
c counting repeated points
TREP=0
101 LINE=LINE+1
OPEN(27, FILE=filename, STATUS='OLD')
c Verifying that we are not in the first line... and we read the
c corresponding one
IF (LINE.NE.1) THEN
DO K=1,LINE-1
READ(27,11,ERR=103,END=9999)
END DO
ENDIF
READ(27,11,ERR=103,END=9999) (PAR(I),I=1,119)
c Start comparing line by line looking for matches. If a match is
c found , close the
c file and open it again to read the next line. If the end of file is
c reached and not iqual rows found, write the line in "results.dat"
102 READ(27, 11,END=104, ERR=102) (PAR2(I),I=1,119)
DO J=1,119
IF ( PAR(J).NE.PAR2(J) ) THEN
GOTO 102
ELSEIF (J.EQ.119) THEN
TREP=TREP+1
GOTO 103
ENDIF
END DO
104 WRITE(29,11) (PAR(I),I=1,119)
103 CLOSE(27)
GOTO 101
9999 WRITE(*,*) "DONE!,", TREP, "duplicated points found!"
CLOSE(27)
CLOSE(28)
CLOSE(29)
11 FORMAT(200E14.6)
END
which actually works it is just super slow. Why? Is there any library that I can use? Sorry for my ignorance, I am completely new with Fortran77.
For each line you open and close the original file, which is very slow! To speed things up, you could just use rewind.
The main issue, though, is the complexity of your algorithm: O(n^2) [You compare each line to every other line]. As a start, I would keep a list of unique line, and compare against that list. If a new row is already listed, discard it - if not, it is a new unique row. This would reduce the complexity to O(n*m), with (hopefully) m << n (m is the number of unique rows). Sorting the rows will probably speed up the comparison.
The next remark would be to move from I/O to memory! Read in the complete file into an array, or at least keep the list of unique rows in memory. A 50,000x119 double precision array requires ~45MB of RAM, so I think this should be feasible ;-)
Write the result back in one piece in a final step.
First question: Why stick with Fortran 77? Since g95 and gfortran have come along, there is no real reason to use a standard that has been obsolete for more than twenty years.
The canonical way to remove duplicate is to sort them, remove duplicates, and then output them in the original order. If you use a good sorting algorithm such as quicksort or heapsort, this will give you O(n log n) performance.
One additional remark: It is also a good idea to put magic numbers such as 119 in your program into PARAMETER statements.
How to write a text or dat file in FORTRAN like a 2D array of integers and each time to enter a value, if in any row there is no value just insert in the start but if some values exists insert to the end of values. This insertion of values can be random, i.e. may be line number 100 first then 80 then 101 then 2. The number of entries in each line is also different.
I also need to use this file at the end but I think that will be easy as need line by line information.
Edit (what he ment possibly) :: How to write a text file in Fortran, like a 2D array of integers, each time adding one value? If there is an empty row with no values, insert one at the beginning of a row, but if there are already some values in that row, append the new value to the end of the row.
Have no idea what he was getting at with those random values and line numbers.
If you want to make decisions based on the input, read the line into a string. Then examine the contents of the string and decide which case of input. If you have numbers that you want to read, use an "internal read" to read them from the string. This question has a code example: Reading comment lines correctly in an input file using Fortran 90