День 2
Основы работы с векторами, матрицами и массивами
- Понятия и различия массива, вектора и матрицы
- создание векторов и матриц
- индексация векторов и матриц
- итерирование по матрицам и векторам
Понятия и различия массива, вектора и матрицы
Матрица
Для начала познакомимся с понятием матрицы, которое в целом является интуитивным:
M = [1 2 3;
4 5 6;
7 8 9;]
size(M)
length(M)
Под размерностью (dimensions
) в julia понимается не размерность матрицы, а её мерность:
2-мерная матрица размерности
ndims(M)
Вектор
В julia вектором называется вектор-столбец:
V = [1
2
3]
вектор-строка же в julia является матрицей размера 1×n
Row = [4 5 6]
[1, 2, 3] # вектор
Сразу покажем как умножить вектор-строку на вектор-столбец:
Заметьте, что результатом является вектор, а не число.
Row*V # 1×3 * 3×1 = 1×1
# 4*1 + 5*2 + 6*3 = 32
V*Row #3×1 * 1×3 = 3×3
Массив
До этого пункта мы рассматривали ситуации, где элементы матрицы/вектора имели один тип.
Проверить какой именно это тип можно с помощью eltype
eltype([1 2 3])
Однако в julia можно создавать матрицы/вектора из элементов разных типов.
В таком случае всё равно у матрицы/вектора будет общий тип элементов: Any
(пер. - любой)
@show 1.2 isa Any
@show "Строка" isa Any;
M_different_types = [1, "Два", '3', abs]
eltype(M_different_types)
Иногда происходит продвижение типов: процесс приведения типов к одному общему, путём преобразование типов из "меньшего" типа в "больший". Подробнее об этом мы поговорим в следующей главе.
V_numb = [1, 2//3, 4+5im]
# 1 - Int64
# 2//3 - Rational{Int64}
# 4+5im - Complex{Int64}
На самом деле и вектор и матрица представляют собой частный случай массива.
Вектор - массив, у которого размерность равна 1 (
ndims≡1
).
Матрица - массив, у которого размерность равна 2 (
ndims≡2
).
Если создать массив размерностью 3 и больше, то будет явно указываться,
что это именно массив, а не матрица
zeros(2,2,2) # массив нулей размера 2×2×2 (своего рода "кубик")
ndims(zeros(2,2,2))
Создание векторов и матриц
нулевые, константные, единичные, случайно заполненные матрицы
import Pkg.add;
Pkg.add("LinearAlgebra")
using LinearAlgebra
Единичная матрица размера
I(3)
Матрица, заполненная единицами
ones(3,3)
Заполнить матрицу размера значениями "abc"
abc_strings = fill("abc",3,2)
Создать "пустую" (непроинициализированную) матрицу типа Float64
на основе другой матрицы.
(Т.е. такого же размера.)
similar(abc_strings,Float64)
similar(abc_strings,Float64) .= 4.
12 элементов от 10 до 76 с постоянным шагом (т.е. 6)
12 = 3*4
12 = 2*6
reshape(range(10,76,12),3,4)
reshape(range(10,76,12),2,6)
Создание векторов/матриц по условию
[x^2 for x ∈ [1,3,6]]
[[x for x in 1:y] for y in 1:3]
[x for x in 1:10 if isodd(x)]
Обращение к элементам массива по индексу
A = reshape(10:10:90,3,3)
A[1] == A[begin] == 10
A[9] == A[end] == 90
A[4]
A[2,3]
A[6:9]
Итерирование по массивам
A = [1:3 10:10:30 100:100:300]
Итерирование по индексу
A_c = copy(A)
for i in eachindex(A_c)
isodd(i) ? A_c[i] = 0 : nothing
end
A_c
Итерирование по элементам
for a in A
print("$a ")
end
Итеррирование по строкам
for row in eachrow(A)
print(row)
println(" row sum: $(sum(row))")
end
Итеррирование по стоблцам
for column in eachcol(A)
println(reverse(column))
end
Статические массивы
Pkg.add("BenchmarkTools","StaticArrays")
using BenchmarkTools
using StaticArrays
v = @SVector [i^2 for i in 1:100]
function sqrt_sum()
v = [i^2 for i in 1:100]
sqrt(sum(v))
end
@btime sqrt_sum()
function sqrt_sum()
s_v = @SVector [i^2 for i in 1:100]
sqrt(sum(s_v))
end
@btime sqrt_sum()
Копирование векторов
Когда мы пропишем s = r, то s это не копия вектора, а ссылка на тот же вектор.
r = [1,2,3]
s = r
s[1] = 100
r
r = [1,2,3]
s = copy(r)
s[1] = 100
s
r
r = [[1],[2],[3]]
s = copy(r)
s[1][1] = 100
s
r
r = [[1],[2],[3]]
s = deepcopy(r)
s[1][1] = 100
s
r