Single- and multi-dimensional Arrays
Julia, diğer teknik hesaplama dilleri gibi, birinci sınıf bir dizi uygulaması sunar. Çoğu teknik hesaplama dili, diğer konteynerler pahasına dizi uygulamalarına büyük önem verir. Julia dizileri özel bir şekilde ele almaz. Dizi kütüphanesi neredeyse tamamen Julia'nın kendisiyle uygulanmıştır ve performansını, Julia'da yazılan diğer kodlar gibi, derleyiciden alır. Bu nedenle, AbstractArray
'dan miras alarak özel dizi türleri tanımlamak da mümkündür. Özel bir dizi türü uygulamak için daha fazla ayrıntı için manual section on the AbstractArray interface'ya bakın.
Bir dizi, çok boyutlu bir ızgarada saklanan nesnelerin bir koleksiyonudur. Sıfır boyutlu dizilere izin verilir, bkz. this FAQ entry. En genel durumda, bir dizi Any
türünde nesneler içerebilir. Çoğu hesaplama amacı için diziler, Float64
veya Int32
gibi daha spesifik türde nesneler içermelidir.
Genel olarak, birçok diğer teknik hesaplama dillerinin aksine, Julia performans için programların vektörleştirilmiş bir tarzda yazılmasını beklemez. Julia'nın derleyicisi tür çıkarımı kullanır ve skalar dizi indeksleme için optimize edilmiş kod üretir, bu da programların performanstan ödün vermeden, okunabilir ve kullanışlı bir tarzda yazılmasına olanak tanır ve bazen daha az bellek kullanır.
In Julia, tüm fonksiyon argümanları passed by sharing (yani, işaretçilerle) geçilir. Bazı teknik hesaplama dilleri dizileri değerle geçirir ve bu, çağrılanların çağıranın bir değerini kazara değiştirmesini önlese de, dizilerin istenmeyen kopyalanmasını önlemeyi zorlaştırır. Gelenek olarak, !
ile biten bir fonksiyon adı, bir veya daha fazla argümanının değerini değiştireceğini veya yok edeceğini belirtir (örneğin, sort
ve sort!
ile karşılaştırın). Çağrılanlar, değiştirmek istemedikleri girdileri değiştirmediklerinden emin olmak için açık kopyalar yapmalıdır. Birçok değiştirmeyen fonksiyon, girdinin açık bir kopyasında sonuna eklenmiş !
ile aynı isimdeki bir fonksiyonu çağırarak ve o kopyayı döndürerek uygulanır.
Basic Functions
Function | Description |
---|---|
eltype(A) | the type of the elements contained in A |
length(A) | the number of elements in A |
ndims(A) | the number of dimensions of A |
size(A) | a tuple containing the dimensions of A |
size(A,n) | the size of A along dimension n |
axes(A) | a tuple containing the valid indices of A |
axes(A,n) | a range expressing the valid indices along dimension n |
eachindex(A) | an efficient iterator for visiting each position in A |
stride(A,k) | the stride (linear index distance between adjacent elements) along dimension k |
strides(A) | a tuple of the strides in each dimension |
Construction and Initialization
Bir dizi oluşturma ve başlatma için birçok işlev sağlanmıştır. Aşağıdaki bu tür işlevlerin listesinde, dims...
argümanına sahip çağrılar ya bir boyut boyutları demetini alabilir ya da değişken sayıda argüman olarak bir dizi boyut boyutunu alabilir. Bu işlevlerin çoğu ayrıca dizinin eleman türü olan birinci girdi T
'yi de kabul eder. T
türü atlanırsa, varsayılan olarak Float64
olarak ayarlanır.
Function | Description |
---|---|
Array{T}(undef, dims...) | an uninitialized dense Array |
zeros(T, dims...) | an Array of all zeros |
ones(T, dims...) | an Array of all ones |
trues(dims...) | a BitArray with all values true |
falses(dims...) | a BitArray with all values false |
reshape(A, dims...) | an array containing the same data as A , but with different dimensions |
copy(A) | copy A |
deepcopy(A) | copy A , recursively copying its elements |
similar(A, T, dims...) | an uninitialized array of the same type as A (dense, sparse, etc.), but with the specified element type and dimensions. The second and third arguments are both optional, defaulting to the element type and dimensions of A if omitted. |
reinterpret(T, A) | an array with the same binary data as A , but with element type T |
rand(T, dims...) | an Array with random, iid [1] and uniformly distributed values. For floating point types T , the values lie in the half-open interval $[0, 1)$. |
randn(T, dims...) | an Array with random, iid and standard normally distributed values |
Matrix{T}(I, m, n) | m -by-n identity matrix. Requires using LinearAlgebra for I . |
range(start, stop, n) | a range of n linearly spaced elements from start to stop |
fill!(A, x) | fill the array A with the value x |
fill(x, dims...) | an Array filled with the value x . In particular, fill(x) constructs a zero-dimensional Array containing x . |
Bu fonksiyonlara boyutları geçmenin çeşitli yollarını görmek için aşağıdaki örneklere bakın:
julia> zeros(Int8, 2, 3)
2×3 Matrix{Int8}:
0 0 0
0 0 0
julia> zeros(Int8, (2, 3))
2×3 Matrix{Int8}:
0 0 0
0 0 0
julia> zeros((2, 3))
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
Burada, (2, 3)
bir Tuple
ve ilk argüman — eleman türü — isteğe bağlıdır, varsayılan olarak Float64
'tür.
Array literals
Diziler, kare parantezlerle doğrudan da oluşturulabilir; [A, B, C, ...]
sözdizimi, virgülle ayrılmış argümanları elemanları olarak içeren bir boyutlu dizi (yani bir vektör) oluşturur. Sonuçta oluşan dizinin eleman tipi (eltype
) parantez içindeki argümanların türlerine göre otomatik olarak belirlenir. Tüm argümanlar aynı türdeyse, o zaman bu dizinin eltype
'ıdır. Eğer hepsi ortak bir promotion type türüne sahipse, o zaman convert
kullanılarak o türe dönüştürülür ve bu tür dizinin eltype
'ıdır. Aksi takdirde, herhangi bir şeyi tutabilen bir heterojen dizi — Vector{Any}
— oluşturulur; bu, hiçbir argüman verilmediğinde literal []
'yi de içerir. Array literal can be typed sözdizimi ile T[A, B, C, ...]
şeklindedir; burada T
bir türdür.
julia> [1, 2, 3] # An array of `Int`s
3-element Vector{Int64}:
1
2
3
julia> promote(1, 2.3, 4//5) # This combination of Int, Float64 and Rational promotes to Float64
(1.0, 2.3, 0.8)
julia> [1, 2.3, 4//5] # Thus that's the element type of this Array
3-element Vector{Float64}:
1.0
2.3
0.8
julia> Float32[1, 2.3, 4//5] # Specify element type manually
3-element Vector{Float32}:
1.0
2.3
0.8
julia> []
Any[]
Concatenation
Eğer köşeli parantezler içindeki argümanlar virgül yerine tek noktalı virgül (;
) veya yeni satırlarla ayrılmışsa, o zaman içerikleri dikey olarak birleştirilir ve argümanlar kendileri eleman olarak kullanılmaz.
julia> [1:2, 4:5] # Has a comma, so no concatenation occurs. The ranges are themselves the elements
2-element Vector{UnitRange{Int64}}:
1:2
4:5
julia> [1:2; 4:5]
4-element Vector{Int64}:
1
2
4
5
julia> [1:2
4:5
6]
5-element Vector{Int64}:
1
2
4
5
6
Benzer şekilde, eğer argümanlar sekmelerle, boşluklarla veya çift noktalı virgüllerle ayrılmışsa, o zaman içerikleri yatay olarak birleştirilir.
julia> [1:2 4:5 7:8]
2×3 Matrix{Int64}:
1 4 7
2 5 8
julia> [[1,2] [4,5] [7,8]]
2×3 Matrix{Int64}:
1 4 7
2 5 8
julia> [1 2 3] # Numbers can also be horizontally concatenated
1×3 Matrix{Int64}:
1 2 3
julia> [1;; 2;; 3;; 4]
1×4 Matrix{Int64}:
1 2 3 4
Tek bir noktalı virgül (veya yeni satır) ve boşluk (veya sekme) hem yatay hem de dikey olarak birleştirilerek birleştirilebilir.
julia> [1 2
3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> [zeros(Int, 2, 2) [1; 2]
[3 4] 5]
3×3 Matrix{Int64}:
0 0 1
0 0 2
3 4 5
julia> [[1 1]; 2 3; [4 4]]
3×2 Matrix{Int64}:
1 1
2 3
4 4
Boşluklar (ve sekmeler) noktalı virgüllerden daha yüksek bir önceliğe sahiptir, önce herhangi bir yatay birleştirme gerçekleştirir ve ardından sonucu birleştirir. Öte yandan, yatay birleştirme için çift noktalı virgül kullanmak, önce dikey birleştirmeleri gerçekleştirir ve ardından sonucu yatay olarak birleştirir.
julia> [zeros(Int, 2, 2) ; [3 4] ;; [1; 2] ; 5]
3×3 Matrix{Int64}:
0 0 1
0 0 2
3 4 5
julia> [1:2; 4;; 1; 3:4]
3×2 Matrix{Int64}:
1 1
2 3
4 4
Tam ;
ve ;;
birinci ve ikinci boyutta birleştirirken, daha fazla noktalı virgül kullanmak bu genel şemayı genişletir. Ayırıcıdaki noktalı virgül sayısı belirli boyutu belirtir, bu nedenle ;;;
üçüncü boyutta birleştirir, ;;;;
dördüncü boyutta ve devam eder. Daha az noktalı virgül önceliğe sahiptir, bu nedenle daha düşük boyutlar genellikle önce birleştirilir.
julia> [1; 2;; 3; 4;; 5; 6;;;
7; 8;; 9; 10;; 11; 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
Daha önce olduğu gibi, yatay birleştirme için boşluklar (ve sekmeler) herhangi bir sayıda noktalı virgülden daha yüksek önceliğe sahiptir. Bu nedenle, daha yüksek boyutlu diziler de satırlarını ilk olarak belirterek yazılabilir; elemanları, düzenlerine benzer bir şekilde metin olarak düzenlenmiştir:
julia> [1 3 5
2 4 6;;;
7 9 11
8 10 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
julia> [1 2;;; 3 4;;;; 5 6;;; 7 8]
1×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
1 2
[:, :, 2, 1] =
3 4
[:, :, 1, 2] =
5 6
[:, :, 2, 2] =
7 8
julia> [[1 2;;; 3 4];;;; [5 6];;; [7 8]]
1×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
1 2
[:, :, 2, 1] =
3 4
[:, :, 1, 2] =
5 6
[:, :, 2, 2] =
7 8
İkinci boyutta birleştirme anlamına gelse de, boşluklar (veya sekmeler) ve ;;
aynı dizi ifadesinde bir arada bulunamaz, aksi takdirde çift noktalı virgül sadece "satır devamı" karakteri olarak işlev görüyor olabilir. Bu, tek bir yatay birleştirmenin birden fazla satıra yayılmasına olanak tanır (satır sonunun dikey bir birleştirme olarak yorumlanmadan).
julia> [1 2 ;;
3 4]
1×4 Matrix{Int64}:
1 2 3 4
Sonlandırıcı noktalı virgüller, ayrıca sonlandırıcı uzunluk 1 boyutları eklemek için de kullanılabilir.
julia> [1;;]
1×1 Matrix{Int64}:
1
julia> [2; 3;;;]
2×1×1 Array{Int64, 3}:
[:, :, 1] =
2
3
Daha genel olarak, birleştirme cat
fonksiyonu aracılığıyla gerçekleştirilebilir. Bu sözdizimleri, kendileri de kolaylık sağlayan fonksiyon çağrıları için kısayollardır:
Syntax | Function | Description |
---|---|---|
cat | concatenate input arrays along dimension(s) k | |
[A; B; C; ...] | vcat | shorthand for cat(A...; dims=1) |
[A B C ...] | hcat | shorthand for cat(A...; dims=2) |
[A B; C D; ...] | hvcat | simultaneous vertical and horizontal concatenation |
[A; C;; B; D;;; ...] | hvncat | simultaneous n-dimensional concatenation, where number of semicolons indicate the dimension to concatenate |
Typed array literals
Belirli bir eleman türüne sahip bir dizi, T[A, B, C, ...]
sözdizimi kullanılarak oluşturulabilir. Bu, T
eleman türüne sahip, A
, B
, C
vb. elemanları içerecek şekilde başlatılmış 1 boyutlu bir dizi oluşturur. Örneğin, Any[x, y, z]
herhangi bir değeri içerebilen heterojen bir dizi oluşturur.
Birleştirme sözdizimi, sonuçtaki öğe türünü belirtmek için benzer şekilde bir tür ile ön eklenebilir.
julia> [[1 2] [3 4]]
1×4 Matrix{Int64}:
1 2 3 4
julia> Int8[[1 2] [3 4]]
1×4 Matrix{Int8}:
1 2 3 4
Comprehensions
Kapsamlar, dizileri oluşturmanın genel ve güçlü bir yolunu sağlar. Kapsam sözdizimi, matematikteki küme oluşturma notasyonuna benzer:
A = [ F(x, y, ...) for x=rx, y=ry, ... ]
Bu formun anlamı, F(x,y,...)
ifadesinin x
, y
vb. değişkenlerinin kendilerine verilen değerler listesindeki her bir değeri alarak değerlendirildiğidir. Değerler herhangi bir yinelemeli nesne olarak belirtilebilir, ancak genellikle 1:n
veya 2:(n-1)
gibi aralıklar ya da [1.2, 3.4, 5.7]
gibi açık değer dizileri şeklinde olur. Sonuç, değişken aralıklarının rx
, ry
vb. boyutlarının birleştirilmesiyle oluşan boyutlara sahip N-d yoğun bir dizi olup, her F(x,y,...)
değerlendirmesi bir skalar değer döndürür.
Aşağıdaki örnek, 1 boyutlu bir ızgara boyunca mevcut elemanın ve sol ve sağ komşusunun ağırlıklı ortalamasını hesaplar. :
julia> x = rand(8)
8-element Array{Float64,1}:
0.843025
0.869052
0.365105
0.699456
0.977653
0.994953
0.41084
0.809411
julia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]
6-element Array{Float64,1}:
0.736559
0.57468
0.685417
0.912429
0.8446
0.656511
Sonuç dizisi türü, hesaplanan öğelerin türlerine bağlıdır, tıpkı array literals gibi. Türü açıkça kontrol etmek için, bir tür anlayışın önüne eklenebilir. Örneğin, sonucu tek hassasiyetle istemiş olabilirdik, şöyle yazarak:
Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]
Generator Expressions
Kapsamlar, dıştaki köşeli parantezler olmadan da yazılabilir ve bu, bir jeneratör olarak bilinen bir nesne üretir. Bu nesne, değerleri talep üzerine üretmek için yinelemeli olarak kullanılabilir; bu, bir dizi ayırmak ve bunları önceden depolamak yerine (bkz. Iteration). Örneğin, aşağıdaki ifade bir dizi toplamını bellek ayırmadan hesaplar:
julia> sum(1/n^2 for n=1:1000)
1.6439345666815615
Bir argüman listesinde birden fazla boyutlu bir jeneratör ifadesi yazarken, jeneratörü sonraki argümanlardan ayırmak için parantezler gereklidir:
julia> map(tuple, 1/(i+j) for i=1:2, j=1:2, [1:4;])
ERROR: syntax: invalid iteration specification
Tüm virgülle ayrılmış ifadeler for
ifadesinden sonra aralıklar olarak yorumlanır. Parantez eklemek, map
için üçüncü bir argüman eklememizi sağlar:
julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])
2×2 Matrix{Tuple{Float64, Int64}}:
(0.5, 1) (0.333333, 3)
(0.333333, 2) (0.25, 4)
Jeneratörler iç fonksiyonlar aracılığıyla uygulanır. Dilin başka yerlerinde kullanılan iç fonksiyonlar gibi, kapsayıcı kapsamdan değişkenler iç fonksiyonda "yakalanabilir". Örneğin, sum(p[i] - q[i] for i=1:n)
kapsayıcı kapsamdan p
, q
ve n
değişkenlerini yakalar. Yakalanan değişkenler performans zorlukları yaratabilir; bkz. performance tips.
Üreticiler ve anlama ifadelerindeki aralıklar, birden fazla for
anahtar kelimesi yazarak önceki aralıklara bağlı olabilir:
julia> [(i, j) for i=1:3 for j=1:i]
6-element Vector{Tuple{Int64, Int64}}:
(1, 1)
(2, 1)
(2, 2)
(3, 1)
(3, 2)
(3, 3)
Bu tür durumlarda, sonuç her zaman 1-d'dir.
Üretilen değerler if
anahtar kelimesi kullanılarak filtrelenebilir:
julia> [(i, j) for i=1:3 for j=1:i if i+j == 4]
2-element Vector{Tuple{Int64, Int64}}:
(2, 2)
(3, 1)
Indexing
n boyutlu bir dizi A
içine indeksleme için genel sözdizimi:
X = A[I_1, I_2, ..., I_n]
her I_k
bir skalar tam sayı, bir tam sayı dizisi veya başka bir supported index olabilir. Bu, tüm boyut içindeki tüm indeksleri seçmek için Colon
(:
), bitişik veya adımlı alt bölümleri seçmek için a:c
veya a:b:c
biçimindeki aralıkları ve true
indekslerinde elemanları seçmek için boolean dizilerini içerir.
Eğer tüm indeksler skalar ise, o zaman sonuç X
, dizi A
'dan tek bir elemandır. Aksi takdirde, X
, tüm indekslerin boyutlarının toplamı kadar boyuta sahip bir dizi olur.
Eğer tüm indeksler I_k
vektörler ise, o zaman X
'in şekli (length(I_1), length(I_2), ..., length(I_n))
olacaktır; X
'in i_1, i_2, ..., i_n
konumunda A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]
değeri bulunacaktır.
Örnek:
julia> A = reshape(collect(1:16), (2, 2, 2, 2))
2×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
julia> A[1, 2, 1, 1] # all scalar indices
3
julia> A[[1, 2], [1], [1, 2], [1]] # all vector indices
2×1×2×1 Array{Int64, 4}:
[:, :, 1, 1] =
1
2
[:, :, 2, 1] =
5
6
julia> A[[1, 2], [1], [1, 2], 1] # a mix of index types
2×1×2 Array{Int64, 3}:
[:, :, 1] =
1
2
[:, :, 2] =
5
6
Sonuç dizisinin boyutunun son iki durumda nasıl farklı olduğunu not edin.
Eğer I_1
iki boyutlu bir matris haline getirilirse, o zaman X
, (size(I_1, 1), size(I_1, 2), length(I_2), ..., length(I_n))
şekline sahip n+1
boyutlu bir dizi haline gelir. Matris bir boyut ekler.
Örnek:
julia> A = reshape(collect(1:16), (2, 2, 2, 2));
julia> A[[1 2; 1 2]]
2×2 Matrix{Int64}:
1 2
1 2
julia> A[[1 2; 1 2], 1, 2, 1]
2×2 Matrix{Int64}:
5 6
5 6
Konum i_1, i_2, i_3, ..., i_{n+1}
değeri A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]
içerir. Skalarlarla indekslenmiş tüm boyutlar atılır. Örneğin, J
bir indeksler dizisi ise, o zaman A[2, J, 3]
sonucu size(J)
boyutunda bir dizi olur. j
'nci elemanı A[2, J[j], 3]
ile doldurulur.
Bu sözdiziminin özel bir parçası olarak, end
anahtar kelimesi, dizinleme parantezleri içindeki her boyutun son indeksini temsil etmek için kullanılabilir; bu, dizinlenen en içteki dizinin boyutuna bağlıdır. end
anahtar kelimesi olmadan dizinleme sözdizimi, getindex
çağrısına eşdeğerdir:
X = getindex(A, I_1, I_2, ..., I_n)
Örnek:
julia> x = reshape(1:16, 4, 4)
4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> x[2:3, 2:end-1]
2×2 Matrix{Int64}:
6 10
7 11
julia> x[1, [2 3; 4 1]]
2×2 Matrix{Int64}:
5 9
13 1
Indexed Assignment
n boyutlu bir dizi A
'da değer atamanın genel sözdizimi:
A[I_1, I_2, ..., I_n] = X
her I_k
bir skalar tam sayı, bir tam sayı dizisi veya başka bir supported index olabilir. Bu, tüm boyut içindeki tüm indeksleri seçmek için Colon
(:
), bitişik veya adımlı alt bölümleri seçmek için a:c
veya a:b:c
biçimindeki aralıkları ve true
indekslerinde elemanları seçmek için boolean dizilerini içerir.
Eğer tüm indeksler I_k
tam sayılarsa, o zaman A
'nın I_1, I_2, ..., I_n
konumundaki değer X
ile, gerekirse A
'nın convert
'sına eltype
'na yazılır.
Eğer herhangi bir indeks I_k
kendisi bir dizi ise, o zaman sağdaki X
da A[I_1, I_2, ..., I_n]
indekslemenin sonucuyla aynı şekle sahip bir dizi veya aynı sayıda elemana sahip bir vektör olmalıdır. A
'nın I_1[i_1], I_2[i_2], ..., I_n[i_n]
konumundaki değer, gerekirse dönüştürülerek X[i_1, i_2, ..., i_n]
ile üzerine yazılır. Eleman bazında atama operatörü .=
seçilen konumlar üzerinde X
'i broadcast kullanarak uygulamak için kullanılabilir:
A[I_1, I_2, ..., I_n] .= X
Tıpkı Indexing içinde olduğu gibi, end
anahtar kelimesi, atanan dizinin boyutuna bağlı olarak, indeksleme parantezleri içindeki her boyutun son indeksini temsil etmek için kullanılabilir. end
anahtar kelimesi olmadan indeksli atama sözdizimi, setindex!
çağrısına eşdeğerdir:
setindex!(A, X, I_1, I_2, ..., I_n)
Örnek:
julia> x = collect(reshape(1:9, 3, 3))
3×3 Matrix{Int64}:
1 4 7
2 5 8
3 6 9
julia> x[3, 3] = -9;
julia> x[1:2, 1:2] = [-1 -4; -2 -5];
julia> x
3×3 Matrix{Int64}:
-1 -4 7
-2 -5 8
3 6 -9
Supported index types
A[I_1, I_2, ..., I_n]
ifadesinde, her I_k
bir skalar indeks, skalar indekslerin bir dizisi veya skalar indekslerin bir dizisini temsil eden ve to_indices
ile dönüştürülebilen bir nesne olabilir:
Bir skalar indeks. Varsayılan olarak bu şunları içerir:
- Boolean olmayan tam sayılar
CartesianIndex{N}
gibi, aşağıdaki gibi daha fazla ayrıntı için (birden fazla boyutta uzananN
-demet tamsayıları gibi davranan)
Bir dizi skalar indeks. Bu şunları içerir:
- Tam sayılardan oluşan vektörler ve çok boyutlu diziler
- Boş diziler gibi
[]
, hiçbir öğe seçmeyen örneğinA[[]]
(A[] ile karıştırılmamalıdır) a:c
veyaa:b:c
gibi aralıklar,a
ilec
(dahil) arasında bitişik veya adımlı alt bölümleri seçer.- Herhangi bir
AbstractArray
alt türü olan özel bir skalar indeks dizisi CartesianIndex{N}
dizileri (aşağıda daha fazla ayrıntı için bakınız)
Bir dizi skalar indeksini temsil eden ve
to_indices
ile böyle bir diziye dönüştürülebilen bir nesne. Varsayılan olarak bu şunları içerir:Colon()
(:
), tüm bir boyuttaki veya tüm dizi üzerindeki tüm indeksleri temsil eder.- Boolean dizileri,
true
indekslerinde elemanları seçer (aşağıda daha fazla ayrıntı için bakınız)
Bazı örnekler:
julia> A = reshape(collect(1:2:18), (3, 3))
3×3 Matrix{Int64}:
1 7 13
3 9 15
5 11 17
julia> A[4]
7
julia> A[[2, 5, 8]]
3-element Vector{Int64}:
3
9
15
julia> A[[1 4; 3 8]]
2×2 Matrix{Int64}:
1 7
5 15
julia> A[[]]
Int64[]
julia> A[1:2:5]
3-element Vector{Int64}:
1
5
9
julia> A[2, :]
3-element Vector{Int64}:
3
9
15
julia> A[:, 3]
3-element Vector{Int64}:
13
15
17
julia> A[:, 3:3]
3×1 Matrix{Int64}:
13
15
17
Cartesian indices
Özel CartesianIndex{N}
nesnesi, birden fazla boyutu kapsayan bir N
-demet tam sayısı gibi davranan bir skalar indeksi temsil eder. Örneğin:
julia> A = reshape(1:32, 4, 4, 2);
julia> A[3, 2, 1]
7
julia> A[CartesianIndex(3, 2, 1)] == A[3, 2, 1] == 7
true
Tek başına düşünüldüğünde, bu nispeten önemsiz görünebilir; CartesianIndex
, birden fazla tam sayıyı bir araya getirerek tek bir çok boyutlu indeksi temsil eden bir nesne oluşturur. Ancak, diğer indeksleme biçimleri ve CartesianIndex
üreten iteratörlerle birleştirildiğinde, bu çok şık ve verimli kodlar üretebilir. Aşağıdaki Iteration ve daha ileri örnekler için this blog post on multidimensional algorithms and iteration adresine bakın.
CartesianIndex{N}
dizileri de desteklenmektedir. Bunlar, her biri N
boyutunu kapsayan bir dizi skalar indeksi temsil eder ve bazen noktasal indeksleme olarak adlandırılan bir indeksleme biçimini mümkün kılar. Örneğin, yukarıdan A
'nın ilk "sayfasından" köşegen elemanlarına erişimi sağlar:
julia> page = A[:, :, 1]
4×4 Matrix{Int64}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> page[[CartesianIndex(1, 1),
CartesianIndex(2, 2),
CartesianIndex(3, 3),
CartesianIndex(4, 4)]]
4-element Vector{Int64}:
1
6
11
16
Bu, dot broadcasting ile çok daha basit bir şekilde ifade edilebilir ve bunu normal bir tam sayı indeksi ile birleştirerek (A'dan ilk page
'i ayrı bir adım olarak çıkarmak yerine) yapılabilir. Aynı zamanda, iki sayfanın her ikisinden de aynı anda iki diyagonal çıkarmak için :
ile birleştirilebilir:
julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), 1]
4-element Vector{Int64}:
1
6
11
16
julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :]
4×2 Matrix{Int64}:
1 17
6 22
11 27
16 32
CartesianIndex
ve CartesianIndex
dizileri, bir boyutun son indeksini temsil etmek için end
anahtar kelimesi ile uyumlu değildir. CartesianIndex
veya bunların dizilerini içerebilecek indeksleme ifadelerinde end
kullanmayın.
Logical indexing
Sıklıkla mantıksal indeksleme veya mantıksal maske ile indeksleme olarak adlandırılan, bir boolean dizisi ile indeksleme, değerlerinin true
olduğu indekslerdeki öğeleri seçer. Bir boolean vektörü B
ile indeksleme, etkili bir şekilde findall(B)
tarafından döndürülen tamsayı vektörü ile indekslemeye eşdeğerdir. Benzer şekilde, N
-boyutlu bir boolean dizisi ile indeksleme, değerlerinin true
olduğu CartesianIndex{N}
vektörü ile indekslemeye etkili bir şekilde eşdeğerdir. Mantıksal bir indeks, indekslediği boyut(lar) ile aynı şekle sahip bir dizi olmalı veya sağlanan tek indeks olmalı ve indekslediği dizinin bir boyutlu yeniden şekillendirilmiş görünümünün şekliyle eşleşmelidir. Boolean dizilerini doğrudan indeks olarak kullanmak, öncelikle findall
çağırmaktan genellikle daha verimlidir.
julia> x = reshape(1:12, 2, 3, 2)
2×3×2 reshape(::UnitRange{Int64}, 2, 3, 2) with eltype Int64:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
julia> x[:, [true false; false true; true false]]
2×3 Matrix{Int64}:
1 5 9
2 6 10
julia> mask = map(ispow2, x)
2×3×2 Array{Bool, 3}:
[:, :, 1] =
1 0 0
1 1 0
[:, :, 2] =
0 0 0
1 0 0
julia> x[mask]
4-element Vector{Int64}:
1
2
4
8
julia> x[vec(mask)] == x[mask] # we can also index with a single Boolean vector
true
Number of indices
Cartesian indexing
N
boyutlu bir diziye indeksleme yapmanın sıradan yolu, tam olarak N
indeks kullanmaktır; her indeks, belirli bir boyuttaki konum(lar)ı seçer. Örneğin, üç boyutlu dizi A = rand(4, 3, 2)
içinde, A[2, 3, 1]
dizinin ilk "sayfasındaki" üçüncü sütunun ikinci satırındaki sayıyı seçecektir. Bu genellikle kartezian indeksleme olarak adlandırılır.
Linear indexing
Tam olarak bir i
indeksi verildiğinde, bu indeks artık dizinin belirli bir boyutundaki bir konumu temsil etmez. Bunun yerine, tüm diziyi doğrusal olarak kapsayan sütun-öncelikli yineleme sırasını kullanarak i
'nci öğeyi seçer. Bu, doğrusal indeksleme olarak bilinir. Temelde, diziyi vec
ile yeniden şekillendirilmiş gibi bir boyutlu bir vektör olarak ele alır.
julia> A = [2 6; 4 7; 3 1]
3×2 Matrix{Int64}:
2 6
4 7
3 1
julia> A[5]
7
julia> vec(A)[5]
7
Bir dizi A
içindeki lineer bir indeks, CartesianIndices(A)[i]
ile kartezyen indeksleme için bir CartesianIndex
'e dönüştürülebilir (bkz. CartesianIndices
), ve bir dizi N
kartezyen indeksi, LinearIndices(A)[i_1, i_2, ..., i_N]
ile bir lineer indekse dönüştürülebilir (bkz. LinearIndices
).
julia> CartesianIndices(A)[5]
CartesianIndex(2, 2)
julia> LinearIndices(A)[2, 2]
5
Dönüşümlerin performansında çok büyük bir asimetri olduğunu belirtmek önemlidir. Bir lineer indeksi bir dizi kartezyen indekse dönüştürmek, bölme ve kalanı alma gerektirirken, diğer yönde gitmek sadece çarpma ve toplama gerektirir. Modern işlemcilerde, tam sayı bölme, çarpmadan 10-50 kat daha yavaş olabilir. Bazı diziler — örneğin Array
— lineer bir bellek parçası kullanılarak uygulanmış ve uygulamalarında doğrudan bir lineer indeks kullanırken, diğer diziler — örneğin Diagonal
— arama yapmak için tam bir dizi kartezyen indekse ihtiyaç duyar (hangisinin hangisi olduğunu incelemek için IndexStyle
'ya bakın).
Dizi için tüm indeksler üzerinde dönerken, eachindex(A)
üzerinde döngü yapmak, 1:length(A)
üzerinde döngü yapmaktan daha iyidir. Bu, A
'nın IndexCartesian
olduğu durumlarda daha hızlı olacaktır, ayrıca OffsetArrays gibi özel indeksleme ile dizileri de destekleyecektir. Eğer sadece değerlere ihtiyaç varsa, o zaman diziyi doğrudan döngü ile geçmek daha iyidir, yani for a in A
.
Omitted and extra indices
Bunun yanı sıra, N
boyutlu bir dizi, belirli durumlarda N
'den daha az veya daha fazla indeks ile indekslenebilir.
İndeksler, yalnızca indekslenmeyen son boyutların hepsi bir uzunluğunda olduğunda atlanabilir. Diğer bir deyişle, son indeksler yalnızca, atlanan indekslerin bir in-bounds indeksleme ifadesi için alabileceği yalnızca bir olası değer olduğunda atlanabilir. Örneğin, boyutu (3, 4, 2, 1)
olan dört boyutlu bir dizi, atlanan boyut (dördüncü boyut) bir uzunluğunda olduğu için yalnızca üç indeks ile indekslenebilir. Doğrusal indekslemenin bu kuraldan önceliği olduğunu unutmayın.
julia> A = reshape(1:24, 3, 4, 2, 1)
3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64:
[:, :, 1, 1] =
1 4 7 10
2 5 8 11
3 6 9 12
[:, :, 2, 1] =
13 16 19 22
14 17 20 23
15 18 21 24
julia> A[1, 3, 2] # Omits the fourth dimension (length 1)
19
julia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1)
ERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3]
julia> A[19] # Linear indexing
19
A[]
kullanarak tüm indeksleri atladığınızda, bu anlam, bir dizideki tek bir öğeyi almak ve aynı zamanda yalnızca bir öğe olduğundan emin olmak için basit bir deyim sağlar.
Benzer şekilde, N
'den fazla indeks sağlanabilir eğer dizinin boyutunun ötesindeki tüm indeksler 1
(veya daha genel olarak d
o belirli boyut numarası olan axes(A, d)
'nin ilk ve tek elemanı) ise. Bu, vektörlerin tek sütunlu matrisler gibi indekslenmesine olanak tanır, örneğin:
julia> A = [8, 6, 7]
3-element Vector{Int64}:
8
6
7
julia> A[2, 1]
6
Iteration
Dizinin tamamı üzerinde yineleme yapmanın önerilen yolları şunlardır:
for a in A
# Do something with the element a
end
for i in eachindex(A)
# Do something with i and/or A[i]
end
İlk yapı, her bir elemanın değerine, ancak indeksine ihtiyaç duyduğunuzda kullanılır. İkinci yapıda, i
bir Int
olacaktır eğer A
hızlı lineer indeksleme ile bir dizi türüyse; aksi takdirde, bir CartesianIndex
olacaktır:
julia> A = rand(4, 3);
julia> B = view(A, 1:3, 2:3);
julia> for i in eachindex(B)
@show i
end
i = CartesianIndex(1, 1)
i = CartesianIndex(2, 1)
i = CartesianIndex(3, 1)
i = CartesianIndex(1, 2)
i = CartesianIndex(2, 2)
i = CartesianIndex(3, 2)
for i = 1:length(A)
ile karşılaştırıldığında, eachindex
kullanarak yineleme, herhangi bir dizi türü üzerinde verimli bir şekilde yineleme yapmanın bir yolunu sunar. Ayrıca, bu, OffsetArrays gibi özel indeksleme ile genel dizileri de destekler.
Array traits
Eğer özel bir AbstractArray
türü yazarsanız, hızlı doğrusal dizinleme özelliğine sahip olduğunu belirtebilirsiniz.
Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()
Bu ayar, MyArray
üzerinde eachindex
yinelemesinin tam sayılar kullanmasını sağlayacaktır. Bu özelliği belirtmezseniz, varsayılan değer IndexCartesian()
kullanılır.
Array and Vectorized Operators and Functions
Aşağıdaki operatörler diziler için desteklenmektedir:
- Unary aritmetik –
-
,+
- İkili aritmetik –
-
,+
,*
,/
,\
,^
- Karşılaştırma –
==
,!=
,≈
(isapprox
),≉
Matematiksel ve diğer işlemlerin uygun vektörleştirilmesini sağlamak için Julia provides the dot syntax f.(args...)
kullanır; örneğin sin.(x)
veya min.(x, y)
, diziler veya diziler ve skalarların karışımları üzerinde eleman bazında işlemler için (bir Broadcasting işlemi); bunlar, diğer nokta çağrılarıyla birleştirildiğinde tek bir döngüye "birleşme" avantajına da sahiptir, örneğin sin.(cos.(x))
.
Also, every binary operator supports a dot version that can be applied to arrays (and combinations of arrays and scalars) in such fused broadcasting operations, e.g. z .== sin.(x .* y)
.
Dikkat edin ki ==
gibi karşılaştırmalar tüm diziler üzerinde çalışır ve tek bir boolean yanıt verir. Eleman bazında karşılaştırmalar için .==
gibi nokta operatörlerini kullanın. (Karşılaştırma işlemleri için <
, yalnızca eleman bazında .<
versiyonu dizilere uygulanabilir.)
Ayrıca max.(a,b)
ile broadcast
'nın max
'yi a
ve b
üzerinde eleman bazında karşılaştırdığını, maximum(a)
'nın ise a
içindeki en büyük değeri bulduğunu unutmayın. Aynı ilişki min.(a, b)
ve minimum(a)
için de geçerlidir.
Broadcasting
Bazen, farklı boyutlardaki diziler üzerinde eleman bazında ikili işlemler gerçekleştirmek faydalı olabilir; örneğin, bir vektörü bir matrisin her sütununa eklemek. Bunu yapmanın verimsiz bir yolu, vektörü matrisin boyutuna kopyalamaktır:
julia> a = rand(2, 1); A = rand(2, 3);
julia> repeat(a, 1, 3) + A
2×3 Array{Float64,2}:
1.20813 1.82068 1.25387
1.56851 1.86401 1.67846
Bu, boyutlar büyük olduğunda israf yaratır, bu nedenle Julia, broadcast
sağlar; bu, dizi argümanlarındaki tekil boyutları diğer dizideki karşılık gelen boyutla eşleştirmek için genişletir ve ekstra bellek kullanmadan, verilen işlevi eleman bazında uygular:
julia> broadcast(+, a, A)
2×3 Array{Float64,2}:
1.20813 1.82068 1.25387
1.56851 1.86401 1.67846
julia> b = rand(1,2)
1×2 Array{Float64,2}:
0.867535 0.00457906
julia> broadcast(+, a, b)
2×2 Array{Float64,2}:
1.71056 0.847604
1.73659 0.873631
Dotted operators gibi .+
ve .*
broadcast
çağrılarıyla eşdeğerdir (fakat birleştirme yaparlar, çünkü described above). Ayrıca, belirli bir hedefi belirtmek için broadcast!
fonksiyonu da vardır (bu, .=
ataması ile birleştirilmiş bir şekilde de erişilebilir). Aslında, f.(args...)
broadcast(f, args...)
ile eşdeğerdir ve herhangi bir fonksiyonu yaymak için kullanışlı bir sözdizimi sağlar (dot syntax). İç içe "nokta çağrıları" f.(...)
(örneğin .+
gibi çağrılar dahil) automatically fuse tek bir broadcast
çağrısına dönüştürülür.
Ayrıca, broadcast
dizilerle sınırlı değildir (fonksiyon belgelerine bakın); aynı zamanda skalarlar, demetler ve diğer koleksiyonları da işler. Varsayılan olarak, yalnızca bazı argüman türleri skalar olarak kabul edilir, bunlar arasında (ancak bunlarla sınırlı olmamak üzere) Number
, String
, Symbol
, Type
, Function
ve missing
ile nothing
gibi bazı yaygın tekil nesneler bulunur. Diğer tüm argümanlar eleman bazında yineleme veya indeksleme ile işlenir.
julia> convert.(Float32, [1, 2])
2-element Vector{Float32}:
1.0
2.0
julia> ceil.(UInt8, [1.2 3.4; 5.6 6.7])
2×2 Matrix{UInt8}:
0x02 0x04
0x06 0x07
julia> string.(1:3, ". ", ["First", "Second", "Third"])
3-element Vector{String}:
"1. First"
"2. Second"
"3. Third"
Bazen, bir dizinin gibi bir konteynerin, genellikle yayılma işlemine katılmasını istemezsiniz ve bu nedenle tüm elemanları üzerinde yineleme yapma davranışından "korunmuş" olmasını istersiniz. Bunu, başka bir konteynerin içine yerleştirerek (örneğin, tek bir eleman Tuple
) yayılma işlemi onu tek bir değer olarak değerlendirecektir.
julia> ([1, 2, 3], [4, 5, 6]) .+ ([1, 2, 3],)
([2, 4, 6], [5, 7, 9])
julia> ([1, 2, 3], [4, 5, 6]) .+ tuple([1, 2, 3])
([2, 4, 6], [5, 7, 9])
Implementation
Julia'daki temel dizi türü, soyut tür AbstractArray{T,N}
'dır. Bu, boyut sayısı N
ve eleman türü T
ile parametreleştirilmiştir. AbstractVector
ve AbstractMatrix
1-d ve 2-d durumları için takma adlardır. AbstractArray
nesneleri üzerindeki işlemler, temel depolamadan bağımsız bir şekilde, daha yüksek seviyeli operatörler ve fonksiyonlar kullanılarak tanımlanmıştır. Bu işlemler, belirli bir dizi uygulaması için bir geri dönüş olarak genellikle doğru bir şekilde çalışır.
AbstractArray
türü, herhangi bir şekilde dizi benzeri olan her şeyi içerir ve bunun uygulamaları geleneksel dizilerden oldukça farklı olabilir. Örneğin, elemanlar depolanmak yerine talep üzerine hesaplanabilir. Ancak, herhangi bir somut AbstractArray{T,N}
türü genellikle en az size(A)
(bir Int
demetini döndürür), getindex(A, i)
ve getindex(A, i1, ..., iN)
uygulamalıdır; değiştirilebilir diziler ayrıca setindex!
uygulamalıdır. Bu işlemlerin neredeyse sabit zaman karmaşıklığına sahip olması önerilir, aksi takdirde bazı dizi işlevleri beklenmedik şekilde yavaş olabilir. Somut türler ayrıca genellikle similar(A, T=eltype(A), dims=size(A))
yöntemini sağlamalıdır; bu, copy
ve diğer yer dışı işlemler için benzer bir dizi tahsis etmek için kullanılır. Bir AbstractArray{T,N}
içsel olarak nasıl temsil edilirse edilsin, T
, tam sayı indeksleme ile döndürülen nesne türüdür (A[1, ..., 1]
, A
boş değilse) ve N
, size
tarafından döndürülen demetin uzunluğu olmalıdır. Özel AbstractArray
uygulamalarını tanımlama hakkında daha fazla bilgi için array interface guide in the interfaces chapter kısmına bakın.
DenseArray
, AbstractArray
'ın, elemanların sütun-anahtar sırasına göre sürekli olarak depolandığı tüm dizileri içermek üzere tasarlanmış soyut bir alt türüdür (bkz. additional notes in Performance Tips). Array
türü, DenseArray
'nın belirli bir örneğidir; Vector
ve Matrix
1-d ve 2-d durumları için takma adlardır. Array
için, tüm AbstractArray
'lar için gerekli olanlar dışında çok az işlem özel olarak uygulanmıştır; dizi kütüphanesinin çoğu, tüm özel dizilerin benzer şekilde davranmasına olanak tanıyan genel bir şekilde uygulanmıştır.
SubArray
, AbstractArray
'ın bellek paylaşımı ile dizinleme yapan bir özel versiyonudur; bu, dizinin kopyalanması yerine orijinal dizi ile bellek paylaşarak gerçekleştirilir. SubArray
, view
fonksiyonu ile oluşturulur; bu fonksiyon, bir dizi ve bir dizi indeks argümanı ile aynı şekilde çağrılır. 4d61726b646f776e2e436f64652822222c2022766965772229_40726566
'nın sonucu, getindex
'nın sonucu ile aynı görünür, tek farkla verilerin yerinde bırakılmasıdır. 4d61726b646f776e2e436f64652822222c2022766965772229_40726566
, giriş indeks vektörlerini bir SubArray
nesnesinde saklar; bu nesne daha sonra orijinal diziyi dolaylı olarak dizinlemek için kullanılabilir. Bir ifadenin veya kod bloğunun önüne @views
makrosunu koyarak, o ifadede bulunan herhangi bir array[...]
dilimi, bir SubArray
görünümü oluşturacak şekilde dönüştürülür.
BitArray
alanında, her boolean değeri için bir bit depolayan, alan açısından verimli "paketlenmiş" boolean dizileri bulunmaktadır. Bunlar, her boolean değeri için bir byte depolayan Array{Bool}
dizileri ile benzer şekilde kullanılabilir ve Array(bitarray)
ve BitArray(array)
aracılığıyla birbirine dönüştürülebilir.
Bir dizi "stride" olarak adlandırılırsa, bellekte elemanları arasında iyi tanımlanmış boşluklarla (stride'lar) saklanır. Desteklenen bir eleman türüne sahip bir stride dizisi, pointer
ve her boyut için stride'ı geçerek BLAS veya LAPACK gibi bir dış (Julia dışı) kütüphaneye aktarılabilir. stride(A, d)
ise d
boyutu boyunca elemanlar arasındaki mesafedir. Örneğin, rand(5,7,2)
ile döndürülen yerleşik Array
, elemanlarını sütun ana sırasına göre ardışık olarak düzenler. Bu, ilk boyutun stride'ının — aynı sütundaki elemanlar arasındaki boşluğun — 1
olduğu anlamına gelir:
julia> A = rand(5, 7, 2);
julia> stride(A, 1)
1
İkinci boyutun adımı, aynı satırdaki elemanlar arasındaki boşluktur ve bir sütundaki eleman sayısı kadar (5
) atlanır. Benzer şekilde, iki "sayfa" arasında (üçüncü boyutta) atlamak 5*7 == 35
eleman atlamayı gerektirir. Bu dizinin strides
değeri, bu üç sayının bir arada bulunduğu demettir:
julia> strides(A)
(1, 5, 35)
Bu özel durumda, bellekte atlanan eleman sayısı, atlanan doğrusal indeksler sayısıyla eşleşmektedir. Bu, yalnızca Array
(ve diğer DenseArray
alt türleri) gibi bitişik diziler için geçerlidir ve genel olarak doğru değildir. Aralık indekslerine sahip görünümler, bitişiksiz adımlı dizilerin iyi bir örneğidir; V = @view A[1:3:4, 2:2:6, 2:-1:1]
ifadesini düşünün. Bu V
görünümü, A
ile aynı belleği referans alır ancak bazı elemanlarını atlamakta ve yeniden düzenlemektedir. V
'nin birinci boyutunun adımı 3
'tür çünkü orijinal dizimizden yalnızca her üçüncü satırı seçiyoruz:
julia> V = @view A[1:3:4, 2:2:6, 2:-1:1];
julia> stride(V, 1)
3
Bu görünüm, orijinal A
'mızdan her diğer sütunu benzer şekilde seçiyor - bu nedenle, ikinci boyuttaki indeksler arasında hareket ederken iki beş elemanlı sütunu atlaması gerekiyor:
julia> stride(V, 2)
10
Üçüncü boyut ilginçtir çünkü sırası tersine dönmüştür! Bu nedenle birinci "sayfadan" ikinci "sayfaya" geçmek için bellekte geriye gitmesi gerekir ve bu nedenle bu boyuttaki adımı negatiftir!
julia> stride(V, 3)
-35
Bu, V
için pointer
'ın aslında A
'nın bellek bloğunun ortasına işaret ettiğini ve bellek içinde hem geriye hem de ileriye doğru elemanlara atıfta bulunduğunu gösterir. Kendi adım dizilerinizi tanımlamak için daha fazla ayrıntı için interface guide for strided arrays'e bakın. StridedVector
ve StridedMatrix
, adım dizileri olarak kabul edilen birçok yerleşik dizi türü için kullanışlı takma adlardır ve bunların, yalnızca işaretçi ve adımlar kullanarak yüksek derecede ayarlanmış ve optimize edilmiş BLAS ve LAPACK fonksiyonlarını çağıran özel uygulamalara yönlendirilmesine olanak tanır.
Belleklemek gerekir ki, adımlar bellek içindeki kaydırmalarla ilgilidir, indeksleme ile değil. Eğer lineer (tek indeks) indeksleme ile kartezyen (çoklu indeks) indeksleme arasında dönüşüm yapmak istiyorsanız, LinearIndices
ve CartesianIndices
'ya bakın.
- 1iid, independently and identically distributed.