bitWise
bitWise

Reputation: 709

How to use break in two for loops?

I've written a function which generates a discrete random variable and returns two indices.It seems that my code is wrong because the returned first index is always 4. Here is my code:

function inds(arr::Array{Float64, 2})
    probs = arr/sum(arr)
    u = rand()
    sum_prob = 0.0
    local ii, jj
    for i=1:size(arr)[1]
        for j=1:size(arr)[2]
            if sum_prob <= u < sum_prob + probs[i,j]
                ii = i
                jj = j
                break
            else
                sum_prob += probs[i,j]
            end
        end
    end
    return (ii, jj, probs[ii,jj])
end

Upvotes: 4

Views: 87

Answers (2)

StefanKarpinski
StefanKarpinski

Reputation: 33249

In this particular case because the two loops can be combined into one multi-iterator loop you can break them both if you do that:

function inds(arr::Array{Float64, 2})
    probs = arr/sum(arr)
    u = rand()
    sum_prob = 0.0
    local ii, jj
    for i=1:size(arr,1), j=1:size(arr,2)
        if sum_prob <= u < sum_prob + probs[i,j]
            ii = i
            jj = j
            break
        else
            sum_prob += probs[i,j]
        end
    end
    return (ii, jj, probs[ii,jj])
end

Note that since arrays are column-major in Julia—like Fortran and Matlab, but unlike C—it is probably faster to switch the loop order like this:

function inds(arr::Array{Float64, 2})
    probs = arr/sum(arr)
    u = rand()
    sum_prob = 0.0
    local ii, jj
    for j=1:size(arr,2), i=1:size(arr,1)
        if sum_prob <= u < sum_prob + probs[i,j]
            ii = i
            jj = j
            break
        else
            sum_prob += probs[i,j]
        end
    end
    return (ii, jj, probs[ii,jj])
end

Upvotes: 5

norok2
norok2

Reputation: 26886

Most likely, you do need to break from both loops. The standard way to do this is to use a boolean flag to exit from both loops, e.g.:

function inds(arr::Array{Float64, 2})
    is_done = false
    probs = arr/sum(arr)
    u = rand()
    sum_prob = 0.0
    local ii, jj
    for i=1:size(arr)[1]
        for j=1:size(arr)[2]
            if sum_prob <= u < sum_prob + probs[i,j]
                ii = i
                jj = j
                is_done = true
                break
            else
                sum_prob += probs[i,j]
            end
        end
        if is_done:
            break
        end
    end
    return (ii, jj, probs[ii,jj])
end

Upvotes: 4

Related Questions