在 Julia 中使用“for”循环将元素存储在 Vector 中

Kan*_*rma 7 julia interval-arithmetic

我的目标是划分两个不同间隔向量 alpha 和 gamma 的元素,并希望以向量形式存储结果间隔。\n我尝试在 Pluto-Julia 中运行此代码,但没有得到结果:

\n
using IntervalArithmetic, Plots, PlutoUI, Arblib, RecursiveArrayTools, StaticArrays\n\nbegin\n    \xce\xb1 = [(200..225); (225..250); (250..275); (275..300)]\n    \xce\xb3 = [(2..2.25); (2.25..2.5); (2.5..2.75); (2.75..3)]\n    local kk = 0\n    for i in 1:4\n        for j in 1:4\n            ol = \xce\xb1[i]/\xce\xb3[j]\n            kk = kk + 1\n        end\n    end\n    @show ol\nend\n
Run Code Online (Sandbox Code Playgroud)\n

我预计生成的区间向量应包含 16 个元素 (4*4)。我认为存在语法错误。如果为通用情况提供代码,这对我会有很大帮助,这意味着 i 和 j 不仅仅是 4 和 4,而是可以更改的。

\n

phi*_*ler 6

没有语法错误,但您从未分配给数组。您仅在每次迭代中覆盖局部标量ol

\n

为了得到你想要的结果,你需要构建一个实际的矩阵。矩阵理解可能是最易读的简短版本(使用普通浮点数,因为我没有加载间隔包):

\n
julia> \xce\xb1 = [200, 225, 250, 275]; \xce\xb3 = [2, 2.25, 2.5, 2.75];\n\njulia> [a / g for a in \xce\xb1, g in \xce\xb3]\n4\xc3\x974 Matrix{Float64}:\n 100.0   88.8889   80.0   72.7273\n 112.5  100.0      90.0   81.8182\n 125.0  111.111   100.0   90.9091\n 137.5  122.222   110.0  100.0\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以使用广播,但是您必须更改其中一个向量的方向:

\n
julia> \xce\xb1 ./ permutedims(\xce\xb3)\n4\xc3\x974 Matrix{Float64}:\n 100.0   88.8889   80.0   72.7273\n 112.5  100.0      90.0   81.8182\n 125.0  111.111   100.0   90.9091\n 137.5  122.222   110.0  100.0\n
Run Code Online (Sandbox Code Playgroud)\n


Sha*_*yan 3

我不知道你为什么要使用块begin,但如果你打算使用硬作用域,最好的选择是将其包装在函数中(另外,可以使用块let,但我不会\一般不推荐)并且这些bein块不会引入新的范围。

\n
    \n
  1. 代码的第一个问题是使用双点,这在 Julia 中对于分隔元素没有意义。
  2. \n
\n
\n

\xce\xb1 = [(200..225); (225..250);(250..275);(275..300)]

\n
\n

相反,您可以通过逗号或分号分隔容器的元素。对于你的情况,你可以这样做:

\n
julia> \xce\xb1 = [(200, 225); (225, 250); (250, 275); (275, 300)]\n4-element Vector{Tuple{Int64, Int64}}:\n (200, 225)\n (225, 250)\n (250, 275)\n (275, 300)\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 由于这些begin块不会引入新的作用域(请阅读此处有关 Julia 中的作用域的信息),因此您不需要声明local变量(除非您在问题中未提供更多代码)。
  2. \n
  3. 如果您打算使用循环for在容器中存储算术运算的结果:
    \n一种方法是首先定义初始化的容器,然后更新它们的值(因为看起来您打算采用这种方法。尽管结构可以改进很多另外,我不会改变OP的整体代码结构,而是改变以下代码块中的内容):
  4. \n
\n
julia> begin\n           \xce\xb1 = [(1, 5); (5, 10); (10, 15); (15, 20)]\n           \xce\xb2 = [(3, 6); (6, 9); (9, 12); (12, 15)]\n           kk = 0\n\n           ol = Matrix{NTuple{2, Float64}}(undef, 4, 4)\n           for i in 1:4\n               for j in 1:4\n                   ol[i, j] = (\xce\xb1[i][1]/\xce\xb2[j][1], \xce\xb1[i][2]/\xce\xb2[j][2])\n                   kk += 1\n               end\n           end\n       end\n\njulia> ol\n4\xc3\x974 Matrix{Tuple{Float64, Float64}}:\n (0.333333, 0.833333)  (0.166667, 0.555556)  (0.111111, 0.416667)  (0.0833333, 0.333333)\n (1.66667, 1.66667)    (0.833333, 1.11111)   (0.555556, 0.833333)  (0.416667, 0.666667)\n (3.33333, 2.5)        (1.66667, 1.66667)    (1.11111, 1.25)       (0.833333, 1.0)\n (5.0, 3.33333)        (2.5, 2.22222)        (1.66667, 1.66667)    (1.25, 1.33333)\n\njulia> kk\n16\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,结果是一个包含16 个元素的 4*4 矩阵(如您所料)。

\n
    \n
  • Q1:什么意思ol = Matrix{NTuple{2, Float64}}(undef, 4, 4)
    \n这里,我定义了一个Matrixasize为4*4的Initialized,其中元素是alength为2且Float64元素类型的元组。
  • \n
  • Q2:正在发生什么ol[i, j] = (\xce\xb1[i][1]/\xce\xb2[j][1], \xce\xb1[i][2]/\xce\xb2[j][2])
    \n在这里,我试图将 the 第i一个元素的第一个成员除以(在 中)第一个元素\xce\xb1的第一个成员,以及 the第一个元素的第二个成员的第\' 个元素的第二个成员(在 中)并将结果替换为的元素。j\xce\xb2\xce\xb1[i][1]/\xce\xb2[j][1]i\xce\xb1j\xce\xb2\xce\xb1[i][2]/\xce\xb2[j][2][i, j]ol
  • \n
\n

更新

\n

这是使用该包的类似结构IntervalArithmetic.jl

\n
using IntervalArithmetic\n\nbegin\n    \xce\xb1 = [(1..5); (5..10); (10..15); (15..20)]\n    \xce\xb2 = [(3..6); (6..9); (9..12); (12..15)]\n    kk = 0\n\n    ol = Matrix{Interval{Float64}}(undef, 4, 4)\n    for i in 1:4\n        for j in 1:4\n            ol[i, j] = \xce\xb1[i]/\xce\xb2[j]\n            kk += 1\n        end\n    end\nend\n
Run Code Online (Sandbox Code Playgroud)\n

然后,如果我检查olkk

\n
julia> ol\n4\xc3\x974 Matrix{Interval{Float64}}:\n [0.166666, 1.66667]  [0.111111, 0.833334]  [0.0833333, 0.555556]     [0.0666666, 0.416667]\n [0.833333, 3.33334]  [0.555555, 1.66667]   [0.416666, 1.11112]       [0.333333, 0.833334]\n [1.66666, 5]         [1.11111, 2.5]        [0.833333, 1.66667]       [0.666666, 1.25]\n [2.5, 6.66667]       [1.66666, 3.33334]    [1.25, 2.22223]        [1, 1.66667]\n\njulia> typeof(ol[1, 1])\nInterval{Float64}\n\njulia> kk\n16\n
Run Code Online (Sandbox Code Playgroud)\n

既然这种方法是您想要的,那么我们至少可以把它写得更好一点。首先,我首先定义一个函数。其次,我们可以使用Iterators.product来避免嵌套for循环:

\n
function div_intervals(first_itv::T, second_itv::T) where T<:Vector{Interval{Float64}}\n    m, n = length(first_itv), length(second_itv)\n    ol = Matrix{Interval{Float64}}(undef, m, n)\n\n    for (i_idx, j_idx) in Iterators.product(1:m, 1:n)\n        ol[i_idx, j_idx] = first_itv[i_idx]/second_itv[j_idx]\n    end\n\n    return ol\nend\n
Run Code Online (Sandbox Code Playgroud)\n

该函数是动态编写的,可以应用于任意长度的\xce\xb1\xce\xb2类型Vector{Interval{Float64}}。此外,我们可以通过在循环中使用广播来使其变得更好for

\n
function div_intervals2(first_itv::T, second_itv::T) where T<:Vector{Interval{Float64}}\n    m, n = length(first_itv), length(second_itv)\n    ol = Matrix{Interval{Float64}}(undef, m, n)\n\n    for j_idx in eachindex(second_itv)\n        ol[:, j_idx] .= first_itv./second_itv[j_idx]\n    end\n\n    return ol\nend\n\njulia> div_intervals2(\xce\xb1, \xce\xb2)\n4\xc3\x974 Matrix{Interval{Float64}}:\n [0.166666, 1.66667]  [0.111111, 0.833334]  [0.0833333, 0.555556]     [0.0666666, 0.416667]\n [0.833333, 3.33334]  [0.555555, 1.66667]   [0.416666, 1.11112]       [0.333333, 0.833334]\n [1.66666, 5]         [1.11111, 2.5]        [0.833333, 1.66667]       [0.666666, 1.25]\n [2.5, 6.66667]       [1.66666, 3.33334]    [1.25, 2.22223]        [1, 1.66667]\n\njulia> div_intervals2(\xce\xb1, \xce\xb2) == div_intervals(\xce\xb1, \xce\xb2)\ntrue\n
Run Code Online (Sandbox Code Playgroud)\n

  • @PrzemyslawSzufel,是的,他没有提到这一点。这是一个具体案例。我认为OP打算用“...”来分隔元素。 (3认同)
  • 当您使用“IntervalArithmetic”包时,双点是完全正确的。RUTRA只是没有给出包名。 (2认同)
  • 该块很可能在那里,因为他们使用 Pluto.jl 并希望将代码放入单个单元格中(我已删除 Pluto 标签,因为它与问题无关)。 (2认同)