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.
There is no syntax error, but you never assign to an array. You only overwrite the local scalar ol in every iteration.
To get your desired result, you need to construct an actual matrix. Probably a matrix comprehension is the most readable short version (using plain floats, as I don't have your interval package loaded):
julia> α = [200, 225, 250, 275]; γ = [2, 2.25, 2.5, 2.75];
julia> [a / g for a in α, g in γ]
4×4 Matrix{Float64}:
100.0 88.8889 80.0 72.7273
112.5 100.0 90.0 81.8182
125.0 111.111 100.0 90.9091
137.5 122.222 110.0 100.0
You can also use broadcasting, but then you have to change the orientation of one of the vectors:
julia> α ./ permutedims(γ)
4×4 Matrix{Float64}:
100.0 88.8889 80.0 72.7273
112.5 100.0 90.0 81.8182
125.0 111.111 100.0 90.9091
137.5 122.222 110.0 100.0
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With