|
| 1 | +# About |
| 2 | + |
| 3 | +A central aim of Julia is to be able to perform calculations on numerical data, quickly and efficiently. |
| 4 | +_Lots_ of numerical data. |
| 5 | + |
| 6 | +Typically, the data will be stored in arrays (or some related type), so it is reasonable to say that arrays are at the heart of the Julia language. |
| 7 | + |
| 8 | +Arrays can be of arbitrary size (subject only to memory constraints in your hardware), and can have arbitrarily many dimensions. |
| 9 | + |
| 10 | +Some types of arrays have special names (copied from Linear Algebra). |
| 11 | +A 1-Dimensional array is called a `Vector` and a 2-dimensional array is called a `Matrix`. |
| 12 | +Both are subtypes of `Array` in Julia. |
| 13 | + |
| 14 | +This introductory Concept concentrates on the basics of Vectors. |
| 15 | +Higher-dimensional arrays will be covered later in the syllabus. |
| 16 | + |
| 17 | +## Creating Vectors |
| 18 | + |
| 19 | +In Julia, a [Vector][arrays] is an ordered sequence of values that can be accessed by index number. |
| 20 | + |
| 21 | +The simplest way to create a Vector is to list the values in square brackets: |
| 22 | + |
| 23 | +```julia-repl |
| 24 | +julia> num_vec = [1, 4, 9] |
| 25 | +3-element Vector{Int64}: |
| 26 | + 1 |
| 27 | + 4 |
| 28 | + 9 |
| 29 | +
|
| 30 | +julia> str_vec = ["arrays", "are", "important"] |
| 31 | +3-element Vector{String}: |
| 32 | + "arrays" |
| 33 | + "are" |
| 34 | + "important" |
| 35 | +``` |
| 36 | + |
| 37 | +The Vector type matches the type of each element. |
| 38 | + |
| 39 | +Technically, it is a _column_ vector, but please ignore that for now if you are unfamiliar with Linear Algebra. |
| 40 | +It should make more sense after the Multidimensional Arrays concept. |
| 41 | + |
| 42 | +_So Vectors need to be homogeneous (all elements the same type)?_ |
| 43 | + |
| 44 | +At some level, yes — and it is recommended to aim for this if you want the best performance. |
| 45 | +However, Julia can work round this limitation (when necessary) by using the `Any` type: |
| 46 | + |
| 47 | +```julia-repl |
| 48 | +julia> mixed_vector = [1, "str", 'c'] |
| 49 | +3-element Vector{Any}: |
| 50 | + 1 |
| 51 | + "str" |
| 52 | + 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase) |
| 53 | +``` |
| 54 | + |
| 55 | +### Pre-filled Vectors |
| 56 | + |
| 57 | +It is very common to start from vectors of all-0 or all-1 values. For these, there are functions called (unsurprisingly) `zeros()` and `ones()`, which take the vector size as a parameter. |
| 58 | +The default type is Float64, but other numeric types can optionally be specified. |
| 59 | + |
| 60 | +By extension, the `fill()` function takes both a value to repeat, and the desired vector size. |
| 61 | + |
| 62 | +```julia-repl |
| 63 | +julia> zeros(3) |
| 64 | +3-element Vector{Float64}: |
| 65 | + 0.0 |
| 66 | + 0.0 |
| 67 | + 0.0 |
| 68 | +
|
| 69 | +julia> ones(3) |
| 70 | +3-element Vector{Float64}: |
| 71 | + 1.0 |
| 72 | + 1.0 |
| 73 | + 1.0 |
| 74 | +
|
| 75 | +julia> ones(Int64, 3) |
| 76 | +3-element Vector{Int64}: |
| 77 | + 1 |
| 78 | + 1 |
| 79 | + 1 |
| 80 | +
|
| 81 | +julia> fill(42, 3) |
| 82 | +3-element Vector{Int64}: |
| 83 | + 42 |
| 84 | + 42 |
| 85 | + 42 |
| 86 | +``` |
| 87 | + |
| 88 | +There are many other options: see [the manual][prefilled]. |
| 89 | + |
| 90 | +# Indexing |
| 91 | + |
| 92 | +Please read and remember this rule: |
| 93 | + |
| 94 | +- ***By default, indexing in Julia starts at 1, not 0***. |
| 95 | + |
| 96 | +This is familiar to anyone who has used other data science languages (R, Matlab, Fortran...), but may seem shocking to computer scientists with a background in C-like languages. |
| 97 | + |
| 98 | +Otherwise, indexes work as you might guess: just put them in square brackets: |
| 99 | + |
| 100 | +```julia |
| 101 | +squares = [0, 1, 4, 9, 16] |
| 102 | +squares[1] # 0 |
| 103 | +squares[3] # 4 |
| 104 | +squares[begin] # 0 ("begin" is synonym for 1) |
| 105 | +squares[end] # 16 ("end" is synonym for length(squares)) |
| 106 | +``` |
| 107 | + |
| 108 | +Note the convenience of indexing with `end` (which is very useful) and `begin` (which is probably not). |
| 109 | + |
| 110 | +Python programmers may be wondering about negative indices. |
| 111 | +Don't: these are not part of Julia, and will raise a `BoundsError`, as will any index smaller than 1 or bigger than `length(squares)`. |
| 112 | + |
| 113 | +## Vector operations |
| 114 | + |
| 115 | +Vectors in Julia are _mutable_: we can change the contents of individual cells. |
| 116 | + |
| 117 | +```julia-repl |
| 118 | +julia> vals = [1, 3, 5, 7] |
| 119 | +4-element Vector{Int64}: |
| 120 | + 1 |
| 121 | + 3 |
| 122 | + 5 |
| 123 | + 7 |
| 124 | +
|
| 125 | +julia> vals[2] = 4 # reassign the value of this element |
| 126 | +4 |
| 127 | +
|
| 128 | +# Only the value at position 2 changes: |
| 129 | +julia> vals |
| 130 | +4-element Vector{Int64}: |
| 131 | + 1 |
| 132 | + 4 |
| 133 | + 5 |
| 134 | + 7 |
| 135 | +``` |
| 136 | + |
| 137 | +There are many [functions available][dequeue] for manipulating vectors, though the Julia documentation generalizes them to "collections" rather than vectors. |
| 138 | + |
| 139 | +Note that, by convention, functions that mutate their input have `!` in the name. |
| 140 | +The compiler will not enforce this, but it is a very _strong_ convention in the Julia world. |
| 141 | + |
| 142 | +These are a few of the useful functions: |
| 143 | + |
| 144 | +- To add values to the end of the vector, use [`push!()`][push]. |
| 145 | +- To remove the last value, use [`pop!()`][pop]. |
| 146 | +- To operate on the start of the vector, the corresponding functions are [`pushfirst!()`][pushfirst] and [`popfirst!()`][popfirst]. |
| 147 | +- To insert or remove an element at any position, there is [`insert!()`][insert] and [`deleteat!()`][deleteat]. |
| 148 | + |
| 149 | +```julia-repl |
| 150 | +julia> vals = [1, 3] |
| 151 | +2-element Vector{Int64}: |
| 152 | + 1 |
| 153 | + 3 |
| 154 | +
|
| 155 | +julia> push!(vals, 5, 6) # can add multiple values |
| 156 | +4-element Vector{Int64}: |
| 157 | + 1 |
| 158 | + 3 |
| 159 | + 5 |
| 160 | + 6 |
| 161 | +
|
| 162 | +julia> pop!(vals) # mutates vals, return popped value |
| 163 | +6 |
| 164 | +
|
| 165 | +julia> vals |
| 166 | +3-element Vector{Int64}: |
| 167 | + 1 |
| 168 | + 3 |
| 169 | + 5 |
| 170 | +``` |
| 171 | + |
| 172 | +## Concatenation |
| 173 | + |
| 174 | +Concatenation is fairly simple for vectors, though a glance at the manual gives warning of complexities in store when we consider multidimensional arrays. |
| 175 | + |
| 176 | +The [`append!()][append] function can take a mixture of several vectors and single elements as input. |
| 177 | + |
| 178 | +```julia-repl |
| 179 | +julia> append!([1, 2], [3, 4], [-1, -2], 15) |
| 180 | +7-element Vector{Int64}: |
| 181 | + 1 |
| 182 | + 2 |
| 183 | + 3 |
| 184 | + 4 |
| 185 | + -1 |
| 186 | + -2 |
| 187 | + 15 |
| 188 | +``` |
| 189 | + |
| 190 | + |
| 191 | +[arrays]: https://docs.julialang.org/en/v1/manual/arrays/ |
| 192 | +[prefilled]: https://docs.julialang.org/en/v1/manual/arrays/#Construction-and-Initialization |
| 193 | +[dequeue]: https://docs.julialang.org/en/v1/base/collections/#Dequeues |
| 194 | +[push]: https://docs.julialang.org/en/v1/base/collections/#Base.push! |
| 195 | +[pop]: https://docs.julialang.org/en/v1/base/collections/#Base.pop! |
| 196 | +[pushfirst]: https://docs.julialang.org/en/v1/base/collections/#Base.pushfirst! |
| 197 | +[popfirst]: https://docs.julialang.org/en/v1/base/collections/#Base.popfirst! |
| 198 | +[insert]: https://docs.julialang.org/en/v1/base/collections/#Base.insert! |
| 199 | +[deleteat]: https://docs.julialang.org/en/v1/base/collections/#Base.deleteat! |
| 200 | +[append]: https://docs.julialang.org/en/v1/base/collections/#Base.append! |
0 commit comments