Julia, read data from text file (Fortran- like)

169 Views Asked by At

How to convert following simple Fortran to Julia?

integer n,i,ne,m,k(10,2)
real x(10),a(10)
open(1,'t.txt')
READ(1,*) n,ne
do  i=1,n
    READ(1,*) m,x(m)
end do
do  i=1,ne
      READ(1,*) m,a(m),(k(m,j),j=1,2)
end do
end

The contents of file t.txt could be

4 3
2  4.1
3  2.2
4  7.1
1  1.1
2  3.3  1  4
3  4.4  2  4
1  7.7  1  2

I'm old Fortraner. I made several attempts using readline without any luck..

3

There are 3 best solutions below

0
computationalMechanics On

I finally found a solution by using combination of 'split' and 'parse' functions to read the group of input data and assign them to variables. Reading such type of data though isn't as easy, direct and clear as in Fortran..

open("t.txt","r") do bb 
x=[]
k=[]
a=[]
strs=[]
strs = split(readline(bb))
n=parse(Int64, strs[1])
ne=parse(Int64, strs[2])   
for i in 1:n
  strs = split(readline(bb))
  m=parse(Int64, strs[1])
  x[m]=parse(Float64, strs[2])
end
for i in 1:ne
  strs = split(readline(bb))
  m=parse(Int64, strs[1])
  a[m]=parse(Float64, strs[2])
  k[m,1]=parse(Int64, strs[3])
  k[m,2]=parse(Int64, strs[4])
end
end
1
daycaster On

I don't know Fortran, and it's not clear what the results are supposed to be. But a rough guess at a not very idiomatic Julia equivalent is:

k = zeros(10, 2)
x = zeros(Float64, 10)
a = zeros(Float64, 10)

open("/tmp/t.txt") do f
    n, ne = map(n -> parse(Int, n), split(readline(f)))
    for i in 1:n
        m, _v = split(readline(f))
        x[parse(Int, m)] = parse(Float64, _v)
    end
    for i in 1:ne
        m, _v1, j, _v2 = split(readline(f))
        # eg (m, _v1, j, _v2) = ("2", "3.3", "1", "4")
        a[parse(Int, m)] = parse(Float64, _v1)
        k[parse(Int, m), parse(Int, j)] = parse(Float64, _v2)
    end
end
julia> k
10×2 Matrix{Float64}:
 2.0  0.0
 4.0  0.0
 0.0  4.0
 0.0  0.0
 0.0  0.0
 0.0  0.0
 0.0  0.0
 0.0  0.0
 0.0  0.0
 0.0  0.0

julia> x
10-element Vector{Float64}:
 1.1
 4.1
 2.2
 7.1
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

julia> a
10-element Vector{Float64}:
 7.7
 3.3
 4.4
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
1
Stepan Zakharov On

A revised version of OP's answer.

open("t.txt", "r") do io
    firstrow = split(readline(io))
    n, ne = parse.(Int, firstrow)

    x = fill(NaN, n)  # or memory alloc w/o filling `x = Vector{Float64}(undef, n)`
    for i in 1:n
        row = split(readline(io))
        m, x[m] = parse.((Int, Float64), row)
    end

    a = fill(NaN, ne)
    k = fill(0, (ne, 2))
    for i in 1:ne
        row = split(readline(io))
        m, a[m] = parse.((Int, Float64), row[1:2])  # or `@view row[1:2]`
        k[m, :] = parse.(Int, row[3:4])
    end

    @show x  # x = [1.1, 4.1, 2.2, 7.1]
    @show a  # a = [7.7, 3.3, 4.4]
    @show k  # k = [1 2; 1 4; 2 4]
end