I aim to divide elements of two different interval vectors, alpha, and gamma, and want to store the resultant intervals in a vector form. I am trying to run this code in Pluto-Julia but not getting the results:
using IntervalArithmetic, Plots, PlutoUI, Arblib, RecursiveArrayTools, StaticArrays
begin
α = [(200..225); (225..250); (250..275); (275..300)]
γ = [(2..2.25); (2.25..2.5); (2.5..2.75); (2.75..3)]
local kk = 0
for i in 1:4
for j in 1:4
ol = α[i]/γ[j]
kk = kk + 1
end
end
@show ol
end
I expect that the resultant interval vector should contain 16 elements (4*4). I think there is a syntax error. I would be great help for me if code is provided for generalized case, means i and j will not be just 4 and 4 but can be changed.
I don't know why you are using a begin
block, but if you intend to use a hard scope, the best choice is to wrap it in a function (Also, it's possible to use the let
block, but I won't recommend it generally) and the bein
blocks do not introduce a new scope.
α = [(200..225); (225..250); (250..275); (275..300)]
Instead, you can separate elements of a container via comma or semicolon. In your case, you can do it like this:
julia> α = [(200, 225); (225, 250); (250, 275); (275, 300)]
4-element Vector{Tuple{Int64, Int64}}:
(200, 225)
(225, 250)
(250, 275)
(275, 300)
begin
blocks do not introduce a new scope (read here about scopes in Julia), then you don't need to declare the local
variable (unless there is further code that you didn't provide in the question).for
loop in a container:julia> begin
α = [(1, 5); (5, 10); (10, 15); (15, 20)]
β = [(3, 6); (6, 9); (9, 12); (12, 15)]
kk = 0
ol = Matrix{NTuple{2, Float64}}(undef, 4, 4)
for i in 1:4
for j in 1:4
ol[i, j] = (α[i][1]/β[j][1], α[i][2]/β[j][2])
kk += 1
end
end
end
julia> ol
4×4 Matrix{Tuple{Float64, Float64}}:
(0.333333, 0.833333) (0.166667, 0.555556) (0.111111, 0.416667) (0.0833333, 0.333333)
(1.66667, 1.66667) (0.833333, 1.11111) (0.555556, 0.833333) (0.416667, 0.666667)
(3.33333, 2.5) (1.66667, 1.66667) (1.11111, 1.25) (0.833333, 1.0)
(5.0, 3.33333) (2.5, 2.22222) (1.66667, 1.66667) (1.25, 1.33333)
julia> kk
16
Note that the result is a 4*4 Matrix (as you expected) with 16 elements.
ol = Matrix{NTuple{2, Float64}}(undef, 4, 4)
?Matrix
with a size
of 4*4 in which elements are Tuples with a length
of 2 and the Float64
element type.ol[i, j] = (α[i][1]/β[j][1], α[i][2]/β[j][2])
?i
'th element of the α
by the first member of the j
'th element of the β
(in the α[i][1]/β[j][1]
), and the second member of the i
'th element of the α
by the second member of the j
'th element of the β
(in the α[i][2]/β[j][2]
) and replace the result with the [i, j]
element of the ol
.Here is a similar structure using the IntervalArithmetic.jl
package:
using IntervalArithmetic
begin
α = [(1..5); (5..10); (10..15); (15..20)]
β = [(3..6); (6..9); (9..12); (12..15)]
kk = 0
ol = Matrix{Interval{Float64}}(undef, 4, 4)
for i in 1:4
for j in 1:4
ol[i, j] = α[i]/β[j]
kk += 1
end
end
end
Then if I check for the ol
and the kk
:
julia> ol
4×4 Matrix{Interval{Float64}}:
[0.166666, 1.66667] [0.111111, 0.833334] [0.0833333, 0.555556] [0.0666666, 0.416667]
[0.833333, 3.33334] [0.555555, 1.66667] [0.416666, 1.11112] [0.333333, 0.833334]
[1.66666, 5] [1.11111, 2.5] [0.833333, 1.66667] [0.666666, 1.25]
[2.5, 6.66667] [1.66666, 3.33334] [1.25, 2.22223] [1, 1.66667]
julia> typeof(ol[1, 1])
Interval{Float64}
julia> kk
16
Since this approach is what you desire, we can write it least a little bit better. First, I begin by defining a function. Second, we can use Iterators.product
to avoid nested for
loop:
function div_intervals(first_itv::T, second_itv::T) where T<:Vector{Interval{Float64}}
m, n = length(first_itv), length(second_itv)
ol = Matrix{Interval{Float64}}(undef, m, n)
for (i_idx, j_idx) in Iterators.product(1:m, 1:n)
ol[i_idx, j_idx] = first_itv[i_idx]/second_itv[j_idx]
end
return ol
end
This function is written dynamic and can be applied on the α
and β
with the type of Vector{Interval{Float64}}
in any length. Also, we can make it even better by using broadcasting in a for
loop:
function div_intervals2(first_itv::T, second_itv::T) where T<:Vector{Interval{Float64}}
m, n = length(first_itv), length(second_itv)
ol = Matrix{Interval{Float64}}(undef, m, n)
for j_idx in eachindex(second_itv)
ol[:, j_idx] .= first_itv./second_itv[j_idx]
end
return ol
end
julia> div_intervals2(α, β)
4×4 Matrix{Interval{Float64}}:
[0.166666, 1.66667] [0.111111, 0.833334] [0.0833333, 0.555556] [0.0666666, 0.416667]
[0.833333, 3.33334] [0.555555, 1.66667] [0.416666, 1.11112] [0.333333, 0.833334]
[1.66666, 5] [1.11111, 2.5] [0.833333, 1.66667] [0.666666, 1.25]
[2.5, 6.66667] [1.66666, 3.33334] [1.25, 2.22223] [1, 1.66667]
julia> div_intervals2(α, β) == div_intervals(α, β)
true