Parseval
Parseval

Reputation: 843

For-loop where index does not start at 1 or 0 and is incremented by 30 instead of 1

I have the following:

include("as_mod.jl")

solvetimes = 50:200
timevector = Array{Float64}(undef,length(solvetimes))

for i in solvetimes
    global T
    T = i
    include("as_dat_large.jl")
    m, x, z = build_model(true,true)
    setsolver(m, GurobiSolver(MIPGap = 2e-2, TimeLimit = 3600))
    solve(m)

    timevector[i-49] = getsolvetime(m)
end

plot(solvetimes,log.(timevector),
title  = "solvetimes vs T", xlabel = "T", ylabel = "log(t)")

And this works great as long as my solvetimes vector is incremented by only 1. However, I'm interested in an 30-increment and it obviously does not work then since my timevector then goes out of bounds. Is there any way of solving this issue? I read about and attempted to use the push! function but to no avail.

I apologize if my question is not good but I don't see how to improve it. The question is essentially about for loops where the index does NOT start at 1 and is only incremented with 1 up to an upper bound, but rather a non-one increment and a start different from 0 or one, if that makes sense.

Upvotes: 0

Views: 240

Answers (1)

hckr
hckr

Reputation: 5583

The : syntax in 50:200 or 50:30:200 creates a range object in Julia. These range objects are not only iterable but also implement the method getindex which means that you can simply access the steps in the range with a[index] syntax as if it is an array.

julia> solvetimes = 50:30:200 # 50, 80, 110, 140, ...
50:30:200

julia> solvetimes[3]
110

You can solve your problem in several ways.

First, you can introduce an itercount variable to count the number of iterations and know at which index of timevector you will put the solve-time.

solvetimes = 50:30:200 # increment by 30
timevector = Vector{Float64}(undef,length(solvetimes))

itercount = 1
for i in solvetimes
    ...

    timevector[itercount] = getsolvetime(m)
    global itercount
    itercount += 1
end

Other way would be to create an empty timevector and push!.

solvetimes = 50:30:200 # increment by 30
timevector = Float64[] # an empty Float64 vector

for i in solvetimes
    ...

    push!(timevector, getsolvetime(m)) # push the value `getsolvetime(m)` into `timevector`
end

push! operation may require julia to allocate memory and copy data to compensate increasing array size, hence might not be very efficient, although it does not really matter in your problem.

Another way would be to iterate from 1 to length of solvetimes. Your loop control variable is still incremented one-by-one but now it represents the index in solvetimes rather than the time point.

solvetimes = 50:30:200 # increment by 30
len = length(solvetimes)

timevector = Vector{Float64}(undef, len)

for i in 1:len
    global T
    T = solvetimes[i]
    ...

    timevector[i] = getsolvetime(m)
end

With these modifications, kth value in timevector, timevector[k] stands for the solve-time for solvetime[k].

You might also find other ways to solve the issue, like using Dicts etc.

Upvotes: 4

Related Questions