Arrays are a good example to get some idea of the Julian way of defining interfaces.

Arrays can be defined by explicitly providing their content:

In [ ]:

```
i = [1, 2, 3 , 4] # An integer array
```

In [ ]:

```
f = [1.2, 3.4, 2.3, π] # A float array
```

In [ ]:

```
s = ["abc", "def", "ghi"] # A string array
```

Notice, that the type of arrays is `Array{T, N}`

, where `T`

is a type and `N`

is the number of dimensions. This type is an example of a **parametric type**, i.e. a type, which itself is parametrised by other values or types.

Arrays do not need to be of one type only, for example:

In [ ]:

```
m = [1, 3.4, "abc"] # A mixed array
```

In some cases, Julia tries to be smart, however, and converts the types of the elements. For example:

In [ ]:

```
m = [1, 3.4, 4] # As soon as there is one float element, it's a float array
```

One can influence this by explictly denoting the type:

In [ ]:

```
m = Number[1, 3.4, 4]
```

In [ ]:

```
# or
m = Float32[1, 3.4, 4]
```

Even though all above arrays present as `Array`

, their data layout in memory differs. Arrays with pointer-free element types such as `Array{Float64, 1}`

or `Array{Int64, 1}`

are stored contiguously in memory, but `Array`

s with mutable types (such as `Array{String, 1}`

and arrays containing abstract types are stored *boxed*, which means that only a pointer to a different memory location is stored inside the array.

On the interface level Julia does not distinguish between both kind of arrays. Since operations on boxed elements are a lot slower, arrays with abstract types should be avoided in critical parts of a program.

Multidimensional arrays can be defined similarly:

In [ ]:

```
A = [[1 2 3]; # Define row-wise
[5 6 7]]
```

In [ ]:

```
A = [[1, 5] [2, 6] [3, 7]] # Define column-wise
```

Notice the subtle difference to an Array of Arrays

In [ ]:

```
A = [[1, 5], [2, 6], [3, 7]]
```

Yet another option is to explicitly filled arrays:

In [ ]:

```
A = zeros(3, 4, 2)
```

In [ ]:

```
@show randn(1, 2) # Float64
A = randn(Float32, 3, 4, 2)
```

Array addition (`+`

, `-`

) and scalar multiplication are directly available on arrays (of any dimension):

In [ ]:

```
x = [1,2,3]
y = [4,5,6]
```

In [ ]:

```
x + 2.0y
```

For element-wise operations the vectorisation syntax is used:

In [ ]:

```
x .* y # elementwise mulitplication
```

In [ ]:

```
x .^ y # Elementwise exponentiation
```

Note, that the `.`

-syntax continues to functions of the standard library ...

In [ ]:

```
sqrt.(cos.(2π * x) .+ sin.(2π * x))
```

In [ ]:

```
@. sqrt(cos(2π * x) + sin(2π * x))
```

... custom functions ...

In [ ]:

```
myrand(x) = rand() * x
myrand.(y)
```

... and may be easily chained

In [ ]:

```
@. exp(cos(x^2))
```

Create the following arrays using Julia code: $$\left(\begin{array}{ccccc} 2&2&2&2&2 \\ 2&2&2&2&2 \\ 2&2&2&2&2 \\ \end{array}\right) \qquad \left(\begin{array}{cccc} 0.1&0.5&0.9&1.3\\ 0.2&0.6&1.0&1.4\\ 0.3&0.7&1.1&1.5\\ 0.4&0.8&1.2&1.6\\ \end{array}\right) $$

Array elements can be indexed individually ...

In [ ]:

```
A[1, 2, 1] = 15
@show A[1, 2, 1]
@show A[2, 2, 2];
```

... or using ranges

In [ ]:

```
A[2:end, 1, :] = ones(2, 2) # : is full range, 2:end means ignore 1st
@show A[2:end, 1, :]
@show A[1, 1, :];
```

It should be noted that Arrays in Julia are stored in column-major order (like in MATLAB, FORTRAN and R) and that indices start with *1*:

In [ ]:

```
vec = collect(1:6) # Collect all numbers 1 to 6 in a Vector
@show vec
A = reshape(vec, 2, 3) # Reshape the result
```

In [ ]:

```
for i in 1:length(A)
# Iterate through the storage in memory order
println(i, " ", A[i])
end
```

In [ ]:

```
A = randn(Float32, 4, 5)
```

In [ ]:

```
ndims(A) # Get the number of dimensions
```

In [ ]:

```
eltype(A) # Get the type of the array elements
```

In [ ]:

```
length(A) # Return the number of elements
```

In [ ]:

```
size(A) # Get the size of the array
```

In [ ]:

```
size(A, 1) # Get the size along an axis
```

In [ ]:

```
reshape(A, 2, 5, 2) # Return an array with the shape changed
```

We want improve our capabilities to perform simulations to two dimensions using the 2D harmonic potential $$ V\left( \begin{array}{c} x_1 \\ x_2 \end{array}\right) = x_1^2 + x_2^2 $$ and the acceleration map $$ \vec{A}_V = - \nabla V. $$ The adapted forward-Euler scheme is $$\left\{\begin{array}{l} \vec{v}^{(n+1)} = \vec{v}^{(n)} + \vec{A}_V(\vec{x}^{(n)}) \Delta t\\ \vec{x}^{(n+1)} = \vec{x}^{(n)} + \vec{v}^{(n)} \Delta t\\ \end{array}\right. .$$

Change the `euler`

function we introduced in 02_Functions_Types_Dispatch.ipynb
accordingly (Hint: Suprisingly few changes are needed) and run the dynamics for five steps using
$$x_n = \left( \begin{array}{c} 0 \\ 0 \end{array}\right) \qquad v_n = \left( \begin{array}{c} 1 \\ 0 \end{array}\right) .$$
Check against your previous implementation.

In [ ]:

```
# You're code here
```

Julia provides the `push!`

and `append!`

functions to add additional elements to an existing array.
For example:

In [ ]:

```
A = Vector{Float64}() # Create an empty Float64 array
```

In [ ]:

```
push!(A, 4.)
```

In [ ]:

```
append!(A, [5, 6, 7])
```

Notice, that the `!`

is part of the name of the function. In Julia the `!`

is a convention to indicate that the respective function *mutates* the content of at least one of the passed arrays.

Very helpful functions for type-generic code in Julia are:

`zero`

, which allocates an array of zeros of the same element type

In [ ]:

```
A = randn(Float32, 3, 4)
zero(A)
```

`similar`

, which returns an uninitialised array, which is similar to the passed array. This means that by default array type, element type and size are all kept.

In [ ]:

```
similar(A)
```

- One may also change these parameters easily:

In [ ]:

```
similar(A, (3, 2)) # Keep element type and array type
```

In [ ]:

```
similar(A, Float64) # Change element type
```

In [ ]:

```
similar(A, Float64, (1, 2)) # Change element type and shape
```

A syntax Julia borrowed from Python are comprehensions. For example:

In [ ]:

```
arr = randn(5)
```

In [ ]:

```
[e for e in arr if e > 0]
```