coolsv
coolsv

Reputation: 781

Iteration index in a Julia for loop

I have to code a very simple for loop in Julia, which I reproduce below:

result=fill([],6,1)
E=rand(5,5)
D=3.27
k=2
for s in [0.5,0.75,1,1.25,1.5,2]
    result[??]=exp.(-(E.^2/D)/(2*s*k))
end

At each iteration, I want that the i-th element of result is filled with the result of the function, which uses the i-th element of the array [0.5,0.75,1,1.25,1.5,2]. So I don't know what to put inside of the brackets [??]. So far, I tried

for (index, value) in enumerate([0.5,0.75,1,1.25,1.5,2])
       result["$index"]=exp.(-(E.^2/D)/(2* "$value" *k))
end

but it doesn't work. Any hint?

Upvotes: 3

Views: 8656

Answers (2)

Iain Skett
Iain Skett

Reputation: 1001

You're currently initialising the results to be a one dimensional array, but they're actually two dimension. So you need to switch the results as follows

result = fill(Array{Float64}(undef,0,0),6,1)

You shouldn't need to do any conversion of the types and the following will just work.

for (index, value) in enumerate([0.5,0.75,1,1.25,1.5,2])
  result[index]=exp.(-(E.^2/D)/(2*value*k))
end

Rather than initialising the results, you can just map across the values as well which becomes a bit easier to read.

result = map(x -> exp.(-(E.^2/D)/(2*x*k)), [0.5, 0.75, 1, 1.25, 1.5, 2])

Some comments on performance

using BenchmarkTools

function t1()
  result=fill(Array{Float64}(undef,0,0),6,1)
  E=rand(5,5)
  D=3.27
  k=2
  for (index, value) in enumerate([0.5,0.75,1,1.25,1.5,2])
    result[index]=exp.(-(E.^2/D)/(2*value*k))
  end
end

function t2()
  E=rand(5,5)
  D=3.27
  k=2
  result = map(x -> exp.(-(E.^2/D)/(2*x*k)), [0.5, 0.75, 1, 1.25, 1.5, 2])
end

@btime t1() # 4.904 μs (49 allocations: 9.66 KiB)
@btime t2() # 4.812 μs (50 allocations: 9.64 KiB)

As you can see, no real difference in the performance. If you want to improve performance then it's easiest to try and pull the constants out of the inner loop.

function t3()
  E=rand(5,5)
  D=3.27
  k=2
  f = -(E.^2/D)/(2*k)
  result = map(x -> exp.(f/x),  [0.5, 0.75, 1, 1.25, 1.5, 2])
end

@btime t3() # 3.168 μs (31 allocations: 5.53 KiB) 

Upvotes: 5

Przemyslaw Szufel
Przemyslaw Szufel

Reputation: 42264

Assuming result should be a vector of matrices:

els = [0.5,0.75,1,1.25,1.5,2]
result=Vector{Matrix{Float64}}(undef, length(els))
E=rand(5,5)
D=3.27
k=2

for s in 1:length(els)
    result[s]=exp.(-(E.^2/D)/(2*s*k))
end

Upvotes: 2

Related Questions