What's poppin class! Welcome to Julia (pt. 2). Today we are learnin' all about linear algebra and matricies. Julia (and machine learning, for those of you that are intrested) is built around linear algebra, so this is a pretty important one.

In [ ]:

```
# Euler 16 code goes here
```

Who did the homework? We want to see your solutions and hear about any road blocks y'all may have run into.

Problems to present:

- Euler 1
- Euler 2
- Euler 4
- Euler 6
- Euler 8
- Euler 9

To talk about Linear Algebra, we first need to talk about matrices. A matrix is a series of numbers, arranged in a grid of rows and columns, like so.

In [ ]:

```
# generating matrices with Julia
```

The following operations are defined for matrices: addition, subtraction, and multiplication.

In [ ]:

```
# matrix operations in Julia
# two types of multiplication
# multiplying elements w/broadcast
# multiplying properly, rows by columns
```

That's right, we can multiply matrices in two ways. Typical matrix multiplication (the kind from linear algebra) involves multiplying **rows** by **columns**, like so:
$$
\begin{bmatrix} \color{red}{1} & \color{red}{4} \\ 3 & 1 \end{bmatrix} \begin{bmatrix} \color{red}{3} \\ \color{red}{2} \end{bmatrix} = \begin{bmatrix} \color{red}{11} \\ 11 \end{bmatrix}
$$
We can do matrix multiplication as long as the number of **columns** of the first matrix matches the number of **rows** of the second matrix.

To access the values of a matrix, we access one dimension at a time. `:`

allows us to select the entire range, while `start`

refers to the first index and `end`

refers to the last index.

In [ ]:

```
m = [1 2 3
4 5 6
7 8 9]
# accessing a matrix
```

$n$-dimensional vectors in Linear Algebra are typically a matrix of $n$ rows by one column. This is called a **column vector**. An 1 by $n$ matrix is called a **row vector**. Julia represents all arrays as column vectors.

In [ ]:

```
# arrays as column vectors
```

Take the following series of linear equations: $$ \begin{align} 3x + y &= 8 \\ x - 2y &= -2 \end{align} $$

We can represent these equations as a *matrix-vector product* (a matrix multiplied by a column vector), using the method of multplication shown above:

To solve this equation, we can use Julia to find the "inverse" of this matrix and multiply it by (8, 2).

In [ ]:

```
# solve eqn with Julia inv
# solve eqn with Julia \ operator
```

Let matrix $A$ be the matrix below:

In [ ]:

```
A = [1 -1
2 4]
```

Notice that if we multiply $A$ by certain vectors (specifically (1, -1) and (1, -2)), we get scaled versions of these vectors back. **Eigenvalues** and **eigenvectors** have the property that: $$ A\vec{v} = \lambda\vec{v} $$
where $\lambda$ is an **eigenvalue** and $\vec{v}$ is its corresponding **eigenvector**.

Julia gives us eigenvalues and their eigenvectors for a given matrix with the function `eigen()`

in the `LinearAlgebra`

package.

In [ ]:

```
using LinearAlgebra # how to import a package in Julia
# Using eigen with A
```

In [ ]:

```
# Demonstrating eigenvectors with A
```

Julia supplies the `'`

as a *transpose* operator. Transposing a matrix switches its rows and columns.

In [ ]:

```
# Demonstrate transpose
```

The `LinearAlgebra`

package also provides dot and cross product operators for you to use at your convenience.

In [ ]:

```
# Using dot and cross
```

Remember we can initialize vectors and matricies with Julia using *array comprehension*. For a 2-D matrix, you just need two variables.

In [ ]:

```
# Vector created from array comprehension
# Matrix created from array comprehension
```

Definitely something to get the hang of, it comes in *very* handy.

What if I want to add `5`

to every element in the array `[1,2,3]`

?

In [ ]:

```
B = [n for n in 1:3] # Array comprehension ;)
# Try (notice the error)
```

In [ ]:

```
# Using broadcast(operator, thing to add, matrix)
```

Broadcast can conveniently be represented by a `.`

.

In [ ]:

```
# Using . as broadcast
```

The other similar function is `map`

. `map`

takes in three inputs like `broadcast`

but it converts everything to the dimension of the second input. For example

In [ ]:

```
# Try to use map like broadcast
```

In [ ]:

```
C = [2 for n in 4:6]
# Lets add the elements of B to C using map
```

These functions also work on matrices

In [ ]:

```
# Broadcast in 2 dimensions
5 .+ [1 2 3 ; 4 5 6]
```

In [ ]:

```
# Map in 2 dimensions
map(+, [5 5 5 ; 5 5 5], [1 2 3 ; 4 5 6])
```

`push!`

, `pop!`

, and `pushfirst!`

¶We (Cameron) went over some of these last time, but it is worth a recap. Remember that `!`

means the function alters its input vector.

`push!(vector, element)`

pushes an element to the back of a vector`pop!(vector)`

removes the first element from a vector`pushfirst!(vector, element)`

pushes an element to the front of a vector

In [ ]:

```
pushPop = [n for n in 2:7]
# push 8 to pushPop
```

In [ ]:

```
# pop pushPop
```

In [ ]:

```
# put 1 at the front of pushPop
```

Remember, if you think an matrix function *should* exist in Julia, it probably does. These next three functions are three of my most used and favorites (cough cough they will be useful on the homework).

`digits(int)`

converts an integer to a vector made up of its digits`circshift(vector, times to shift)`

rotates a vector, rotating the back elements to the front`diag(matrix)`

returns the diagonal of the matrix

In [ ]:

```
n = 987654321
# Demonstrate digits() on num, notice how the least signifigant digit is at the [1] position
digits(n)
```

In [ ]:

```
# Demonstrate circshift on the digits() vector
```

In [ ]:

```
A = [1 2 3 ; 4 5 6 ; 7 8 9] # Array to demonstrate diag on
```

In [ ]:

```
using LinearAlgebra # diag is a LinearAlgebra thing
# Demonstrate diag(A) and diag(A, 1) and diag(A, -1)
```

What if I want to access the opposite diagonal (the one running from the top right to the bottom left)?

Well, we can do this. The part before the comma is how we want to read the rows. Writing `end:-1:1`

reverses the order the rows appear (the last one will appear on top, etc). The part after the comma is how we want to read the columns, and we want those to stay the same so `:`

will work. A single colon just means `1:end`

.

Not going to lie, this is a little complicated and it is ok if you cannot wrap your head around it, I am only presenting it to you because it us important when you will need to read an array's backwards diagonal in the homework.

In [ ]:

```
diag(A[end:-1:1,:]) # grabs the reverse diagonal from A
```

`vcat`

and `hcat`

¶Ok one last set of functions before we go. `vcat`

stands for vertical concatenate and `hcat`

is horizontal concatenate. They can take in vectors or matrices and concatenate them, given the dimensions match (number of rows must be the same for `hcat`

and number of columns must be the same for `vcat`

).

In [ ]:

```
peanutButter = [1 2 ; 3 4]
jelly = [5 6 ; 7 8]
# hcat peanutButter and jelly
```

In [ ]:

```
# vcat peanutButter and jelly
```

Enough Lecture!

https://projecteuler.net/problem=35

The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.

There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.

How many circular primes are there below one million?

In [ ]:

```
using Primes
prime = primes(1000000) # prime is now a vector of all the primes below 1,000,000... we will teach you how to use the Primes package later :)
# Euler 35 code goes here
```

https://projecteuler.net/problem=30

Surprisingly there are only three numbers that can be written as the sum of fourth powers of their digits:

$$1634 = 1^4 + 6^4 + 3^4 + 4^4$$$$8208 = 8^4 + 2^4 + 0^4 + 8^4$$$$9474 = 9^4 + 4^4 + 7^4 + 4^4$$As $1 = 1^{4}$ is not a sum it is not included.

The sum of these numbers is $1634 + 8208 + 9474 = 19316$.

Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.

In [ ]:

```
# Euler 30 code goes here
```

https://projecteuler.net/problem=11

In the 20×20 grid below, four numbers along a diagonal line have been marked in red.

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48The product of these numbers is 26 × 63 × 78 × 14 = 1788696.

What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?

We will be spending a good portion of next week's class on this problem, so we strongly suggest you at least attempt it. Feel free to email us with any and all questions. Go get that sweet, sweet checkmark!

Requirement: Y'all's solution should look through every possible product and then return the largest one.

Hint: the "Other Very Useful Operations" section should be *very useful* for this problem

In [ ]:

```
# Euler 11 code goes here
```