Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lecture-and-consult-scraps/Consult_Fri_Aug_19.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Now instead of passing `abs` we create an annoymous function using `()->`"
"Now instead of passing `abs` we create an anonymous function using `()->`"
]
},
{
Expand Down Expand Up @@ -718,7 +718,7 @@
}
],
"source": [
"reverse(split(\"Yoni Nazarathy\",\" \"))[1] #This is one way to take the last word of a sentnance or name"
"reverse(split(\"Yoni Nazarathy\",\" \"))[1] #This is one way to take the last word of a sentence or name"
]
},
{
Expand Down Expand Up @@ -956,7 +956,7 @@
" n = length(a)\n",
" for i in 1:n-1\n",
" for j in 1:n-i\n",
" if by(a[j]) > by(a[j+1]) #THIS IS THE BUBBLE SORT UDPGRADE TO USE by\n",
" if by(a[j]) > by(a[j+1]) #THIS IS THE BUBBLE SORT UPGRADE TO USE by\n",
" a[j], a[j+1] = a[j+1], a[j]\n",
" end\n",
" end\n",
Expand Down
8 changes: 4 additions & 4 deletions lecture-and-consult-scraps/Consult_Friday_Aug_12.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"metadata": {},
"outputs": [],
"source": [
"#Initilization "
"#Initialization "
]
},
{
Expand All @@ -27,7 +27,7 @@
],
"source": [
"function do_timing()\n",
" times = Vector{Float64}(undef,0) #Initilization\n",
" times = Vector{Float64}(undef,0) #Initialization\n",
"# n_range = 500 : 500 : 10^4 \n",
"# for n in n_range\n",
"# data = rand(Int64, n)\n",
Expand Down Expand Up @@ -162,7 +162,7 @@
}
],
"source": [
"array = Vector{Float64}(undef,0) #Initilization\n",
"array = Vector{Float64}(undef,0) #Initialization\n",
"push!(array,3.14)"
]
},
Expand Down Expand Up @@ -301,7 +301,7 @@
],
"source": [
"function sieve_of_evens(n)\n",
"# return [2i for i in 1:(n ÷ 2)] #\\div integer divis \n",
"# return [2i for i in 1:(n ÷ 2)] #\\div integer division \n",
" array = []\n",
" for i in 1:n\n",
" if i ÷ 2 == i/2\n",
Expand Down
50 changes: 25 additions & 25 deletions lectures_jupyter/unit_5.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
"\n",
"##### Definition (Ring)\n",
"\n",
"A ring $\\RR$ is a set with addtion $(+)$ and multiplciation $(\\cdot)$ satisfying the following conditions called the *ring axioms*:\n",
"A ring $\\RR$ is a set with addition $(+)$ andmultiplicationn $(\\cdot)$ satisfying the following conditions called the *ring axioms*:\n",
"\n",
"- $(\\RR,+)$ is an abelian group, that is:\n",
" - $(+)$ is associative *and* commutative,\n",
Expand All @@ -157,7 +157,7 @@
"#### Example\n",
"1. The $\\RR = \\{ 0 \\}$ (the *zero ring*) is a trivial ring.\n",
"1. The naturals $\\NN$ do *not* form a ring as they lack additive idenity.\n",
"1. Arithemtic on the clock forms a ring.\n",
"1. Arithmetic on the clock forms a ring.\n",
"\n",
"##### Definition (Zero Divisor)\n",
"An element $a \\in \\RR$ is called a *zero divisor* if there is nonzero $b \\in \\RR$ such that $ab = 0$.\n",
Expand Down Expand Up @@ -237,7 +237,7 @@
"function remainder(a::T, b::T) where T <: Integer \n",
" #Note that later we'll extend this to integral domains\n",
" \n",
" #short circuit evalution gives cheeky if statements\n",
" #short circuit evaluation gives cheeky if statements\n",
" a < 0 && return remainder(-a, b) #later replace `0` with `zero(T)`\n",
" a < b && return a\n",
" return remainder(a-b, b)\n",
Expand Down Expand Up @@ -606,7 +606,7 @@
"\n",
"##### Def (GCD)\n",
"\n",
"Let $a,b \\in \\ZZ$ not both 0. We say $g \\in \\ZZ$ is the *greatest common divsor* of $a$ and $b$, denoted $\\gcd(a,b)$, when\n",
"Let $a,b \\in \\ZZ$ not both 0. We say $g \\in \\ZZ$ is the *greatest common divisor* of $a$ and $b$, denoted $\\gcd(a,b)$, when\n",
"1. $g | a$ and $g | b$ ($g$ is a common divisor), \n",
"1. $h | a \\;\\wedge\\; h | b \\implies h | g$ (greatest),\n",
"1. $g > 0$ (required for uniqueness) \n",
Expand Down Expand Up @@ -806,7 +806,7 @@
"### Chinese Remaindering\n",
"\n",
"##### Problem Statement\n",
"Two integers $a$ and $b$ are *relatively prime* when $\\gcd(a,b) = 1$. Given a finite sequence of relatively prime integers $m_1,\\ldots,m_k$ called the *moduli* and correspoing integers $u_1,\\ldots,u_k$ called the *images*, find $u \\in \\ZZ$ such that\n",
"Two integers $a$ and $b$ are *relatively prime* when $\\gcd(a,b) = 1$. Given a finite sequence of relatively prime integers $m_1,\\ldots,m_k$ called the *moduli* and corresponding integers $u_1,\\ldots,u_k$ called the *images*, find $u \\in \\ZZ$ such that\n",
"\\begin{align*}\n",
"u &\\cong u_1 \\mod m_1 \\\\\n",
"u &\\cong u_2 \\mod m_2 \\\\\n",
Expand Down Expand Up @@ -1250,11 +1250,11 @@
"$$\\# a := \\mbox{number of nonzero terms of }a.$$ \n",
"So, for instance $\\# 2x^2-5 = 2$.\n",
"\n",
"If we intend to use CRT to cacluate the product $c = a \\cdot b$ of $a,b \\in \\ZZ_p[x]$ we need $M = p_1,\\ldots,p_\\ell$ satisfying\n",
"If we intend to use CRT to calculate the product $c = a \\cdot b$ of $a,b \\in \\ZZ_p[x]$ we need $M = p_1,\\ldots,p_\\ell$ satisfying\n",
"$$\n",
"M = p_1 \\cdot \\cdots \\cdot p_\\ell > 2 \\cdot ||c||_\\infty.\n",
"$$\n",
"It is *twice* $||c||_\\infty$ to account for negative ceofficients. For instance, $3x^2 - 3x +1$ requires coefficients in $\\{ -3,-2,-1,0,1,2,3\\}$ which is $\\ZZ_7$ and not $\\ZZ_5$.\n",
"It is *twice* $||c||_\\infty$ to account for negative coefficients. For instance, $3x^2 - 3x +1$ requires coefficients in $\\{ -3,-2,-1,0,1,2,3\\}$ which is $\\ZZ_7$ and not $\\ZZ_5$.\n",
"\n",
"##### Proposition\n",
"Let $a,b \\in \\ZZ[x]$.\n",
Expand All @@ -1263,7 +1263,7 @@
"$$\n",
"\n",
"*Proof* (Sketch)\n",
"Do a worst case analysis where you mutiply $a = \\alpha x^n + \\alpha x^{n-1} + \\cdots + \\alpha$ by $b = \\beta x^n + \\beta x^{n-1} + \\cdots + \\beta$ and see what the largest coefficient will end up being."
"Do a worst case analysis where you multiply $a = \\alpha x^n + \\alpha x^{n-1} + \\cdots + \\alpha$ by $b = \\beta x^n + \\beta x^{n-1} + \\cdots + \\beta$ and see what the largest coefficient will end up being."
]
},
{
Expand Down Expand Up @@ -1396,7 +1396,7 @@
"source": [
"def MULTIPLICATION: \n",
" Input a = an x^n + ... a1 x + a0, b = bm x^m + ... b1 x + b0 in ZZ[x]\n",
" Ouput a * b in ZZ[x]\n",
" Output a * b in ZZ[x]\n",
" \n",
" height_a <- max(|an|, ..., |a1|, |a0|)\n",
" height_b <- max(|bm|, ..., |b1|, |b0|)\n",
Expand All @@ -1409,10 +1409,10 @@
" while M < B do\n",
" p <- NextPrime(p) # the first prime > p\n",
" c' <- a*b mod p # multiplication in ZZ_p[x]\n",
" c <- CRT([c, c'], [M, p]) # spatial optimaztion \n",
" c <- CRT([c, c'], [M, p]) # spatial optimization \n",
" M <- M*p\n",
" \n",
" return c smod M # restore negative coefficients with symemetric mod"
" return c smod M # restore negative coefficients with symmetric mod"
]
},
{
Expand All @@ -1430,7 +1430,7 @@
"$$\n",
"Even though $x^2$ and $2x$ are from $\\ZZ[x]$ that their division is in $\\QQ[x]$. This is because $\\ZZ$ is not a *field* but $\\QQ$ is. \n",
"\n",
"It turns out $\\FF[x]$ is a **Euclidean Domain** when $\\FF$ is a field. Re-consider the division, but this time let us do the calcuation in $\\ZZ_7[x]$\n",
"It turns out $\\FF[x]$ is a **Euclidean Domain** when $\\FF$ is a field. Re-consider the division, but this time let us do the calculation in $\\ZZ_7[x]$\n",
"$$\n",
"\\begin{align*}\n",
"\\frac{x^2}{2x} \n",
Expand Down Expand Up @@ -1475,7 +1475,7 @@
"source": [
"def DIVISION: \n",
" Input a, b in ZZ_p[x] such that b != 0\n",
" Ouput q, r such that a = b*q + r and deg r < deg b in ZZ_p[x]\n",
" Output q, r such that a = b*q + r and deg r < deg b in ZZ_p[x]\n",
" \n",
" r, q = a, 0\n",
" while r != 0 and deg r >= deg b do:\n",
Expand Down Expand Up @@ -1633,7 +1633,7 @@
"outputs": [],
"source": [
"#Taken from polynomial_gcd.jl\n",
"#Note that as part of your project you'll implelment this for PolynomialModP \n",
"#Note that as part of your project you'll implement this for PolynomialModP \n",
"#(without an input argument `prime`)\n",
"\n",
"function extended_euclid_alg(a::Polynomial, b::Polynomial, prime::Int)\n",
Expand Down Expand Up @@ -1729,7 +1729,7 @@
"$$\n",
"We have deduced $f = (3x^2 + 1) \\frac{9x^4-1}{3x^2+1} = (3x^2+1)(3x^2-1)$.\n",
"\n",
"We may get **luckier** by chosing different eval points that have **fewer** integer factors:\n",
"We may get **luckier** by choosing different eval points that have **fewer** integer factors:\n",
"$$\n",
"f(12) = 186\\,623 = 431 \\cdot 433 = [(3x^2-1)(3x^2+1)]_{x=12}\n",
"$$\n",
Expand Down Expand Up @@ -2006,7 +2006,7 @@
"##### Theorem \n",
"In $\\ZZ_p[x]$, \n",
"$$x^{p^k}-x$$ \n",
"is the product of all *monic* irreducible polynomials in $\\ZZ_p[x]$ of degreee $d | k$.\n",
"is the product of all *monic* irreducible polynomials in $\\ZZ_p[x]$ of degree $d | k$.\n",
"\n",
"This means that\n",
"$$\n",
Expand All @@ -2018,7 +2018,7 @@
"\\end{align*}\n",
"$$\n",
"\n",
"Notice we now have an algorithm for decomposing a polynomial into groups of products of irreducible polyomials of the same degree."
"Notice we now have an algorithm for decomposing a polynomial into groups of products of irreducible polynomials of the same degree."
]
},
{
Expand All @@ -2028,7 +2028,7 @@
"source": [
"def DISTINCT_DEGREE_FACTORIZATION:\n",
" Input a in ZZ_p[x] such that d = deg a > 0, a is monic, primitive, and a square-free.\n",
" Ouput g_1, g_2, ..., g_m such that a = g_1 * g_2 * ... * g_m and \n",
" Output g_1, g_2, ..., g_m such that a = g_1 * g_2 * ... * g_m and \n",
" g_i = Product of irreducible polynomials of degree i\n",
"\n",
" w <- x\n",
Expand Down Expand Up @@ -2119,7 +2119,7 @@
"for $\\sigma$ a permutation on $\\ZZ_p$ and $k = \\frac{p-1}2$. In particular, we have merely pushed\n",
"the roots around.\n",
"\n",
"Similarily,\n",
"Similarly,\n",
"$$\n",
"x^{p^k}-x = x(x^\\frac{p^k-1}2 - 1)(x^\\frac{p^k-1}2 + 1)\n",
"$$\n",
Expand All @@ -2146,7 +2146,7 @@
"def DISTINCT_DEGREE_SPLIT: \n",
" Input a in ZZ_p[x] monic and d in ZZ such that a = g_1 * g_2 * ... * g_m, \n",
" g_k in \\ZZ_p[x] irreducible, and deg g_k = d\n",
" Ouput [g_1, g_2, ..., g_m]\n",
" Output [g_1, g_2, ..., g_m]\n",
"\n",
" if degree(a) = d then\n",
" return [a]\n",
Expand Down Expand Up @@ -2216,7 +2216,7 @@
"\n",
"def FACTOR(): \n",
" Input a in ZZ_p[x]\n",
" Ouput [[g1, d1], [g2, d2], ..., [gm, dm]] such that gk, irreducible, and\n",
" Output [[g1, d1], [g2, d2], ..., [gm, dm]] such that gk, irreducible, and\n",
" a ≡ g1^d1 * g2^d2 * ... * gm^dm (mod p)\n",
" \n",
" f <- a\n",
Expand Down Expand Up @@ -2336,7 +2336,7 @@
"$$\n",
"103 = 64 + 32 + 4 + 2 + 1 = (1100111)\n",
"$$\n",
"where $(x)_2$ is the binary representaiton of $x$. Thereby\n",
"where $(x)_2$ is the binary representation of $x$. Thereby\n",
"$$\n",
"w^{103} \\mod p = (w^{64}) \\cdot (w^{32}) \\cdot (w^4) \\cdot (w^2) \\cdot w^1 \\mod m\n",
"$$\n",
Expand All @@ -2352,7 +2352,7 @@
"w^{64} \\mod a && s &\\gets s^2 \\mod a \n",
"\\end{align*}\n",
"$$\n",
"So, instead of doing $103$ multiplications we are doing less than $2 \\cdot 5 = 10$ mutiplications (5 to get the squares, then worst case multiply those 5 squares together).\n",
"So, instead of doing $103$ multiplications we are doing less than $2 \\cdot 5 = 10$ multiplications (5 to get the squares, then worst case multiply those 5 squares together).\n",
"\n",
"Returning to $8^{17^3}$ we have \n",
"$$17^3 = (1001100110001)_2 = 2^{12} + 2^9 + 2^8 + 2^5 + 2^4 + 2^0$$ \n",
Expand All @@ -2374,7 +2374,7 @@
"source": [
"def POWMOD:\n",
" Input x in ZZ, m in ZZ such that m >= 0, p a prime.\n",
" Ouput x^m mod p\n",
" Output x^m mod p\n",
" \n",
" let m = b0*2^0 + b1*2^1 + ... + bk*2^k with bi in {0, 1} # i.e. determine the binary representation of m\n",
" \n",
Expand All @@ -2399,7 +2399,7 @@
"You should *not* use indexing for sparse polynomials --- there is no relationship between term degree and its position in the terms vector. Rather, limit yourself to *two* operations on polynomials:\n",
"1. Adding a single term `p + t` which we can abstract as `push!(p::PolynomialSparse, t::Term)`.\n",
"1. Removing the leading term `p - leading(p)` which we can abstract as `pop!(p::PolynomialSparse)::Term`.\n",
"Note: The bang symbol `!` is userd to indicate the function mutates its input."
"Note: The bang symbol `!` is used to indicate the function mutates its input."
]
},
{
Expand Down
6 changes: 3 additions & 3 deletions markdown/lecture-unit-1.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ You are coming to this course after doing several mathematics and statistics cou
* You know that you can make computers do the same action again and again, by wrapping code in loops, often using conditional statements (`if`) to decide how the program should continue.
* You have even used and/or written a few functions (or routines) where you specify how some action should be done and describe that action in a function.
* You certainly know how to use files, directories, and the internet.
* Finally, you are also somewhat of a mathematician. You have done courses such as STAT1301 (first year stats), MATH1071 (Analysis + Linear Algebra) + MATH1072 (Mutivariable Calculus + some modelling) + several more math electives.
* Finally, you are also somewhat of a mathematician. You have done courses such as STAT1301 (first year stats), MATH1071 (Analysis + Linear Algebra) + MATH1072 (Multivariable Calculus + some modelling) + several more math electives.

[![Women coding image](../web_img/women_coders.jpg)](https://cacm.acm.org/news/234820-the-secret-history-of-women-in-coding/fulltext)

Expand Down Expand Up @@ -615,7 +615,7 @@ function fast_inv_sqrt(number::Float32)
i = reinterpret(UInt32, number)
#do WTF magic
i = 0x5F3759Df - (i >> 1)
#reinterpet back into a float32
#reinterpret back into a float32
y = reinterpret(Float32, i)
#do an iteration of newtons method from a good first guess
y = y * (Float32(1.5) - (x2 * y^2))
Expand Down Expand Up @@ -958,7 +958,7 @@ uppercase("ramzi")

How would you do that?

To close, here is an example adapted from the SWJ book. It takes the Shakespere corpus and counts frequencies of words.
To close, here is an example adapted from the SWJ book. It takes the Shakespeare corpus and counts frequencies of words.

```julia
using HTTP, JSON
Expand Down
14 changes: 7 additions & 7 deletions markdown/lecture-unit-2.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function bubble_sort!(a)
end

bubble_sort!(data)
println("Sorted data (with buble sort): ", data)
println("Sorted data (with bubble sort): ", data)
```

A key question when considering such an algorithm is **how fast does it run?** Other key questions include **how much memory does it use?**, as well as other questions. Such questions are often critical during the phase of algorithm design, and are later critical with algorithm or datastructure choice.
Expand Down Expand Up @@ -386,7 +386,7 @@ for j in 1:n, i in 1:m
end
```

Access of matrix elements is $O(1)$, however this doesn't mean that in practice (certainly in big numerical computations), different ways of accesing the matrix vary:
Access of matrix elements is $O(1)$, however this doesn't mean that in practice (certainly in big numerical computations), different ways of accessing the matrix vary:

```julia
function sum_rows(data, n, m)
Expand Down Expand Up @@ -551,15 +551,15 @@ Note: do not confuse the heap data structure with the other computer science usa

Before starting to see what a heap does (we'll continue in more depth in future units on how it works), we'll discuss what we expect it to do - namely implement an efficient **priority queue**.

Consider for example a hypothetical situation where thousands of individuals attend a mass vaccination centre. As they arrive, each individual is tagged by their name (a `String`), and recieves a priority for vaccination which is a number (say `Float32`). Assume (hypothetically) that the priority is a function of their age, their occupation (essential or not), and their medical condition. Hence there are many possible different priorities.
Consider for example a hypothetical situation where thousands of individuals attend a mass vaccination centre. As they arrive, each individual is tagged by their name (a `String`), and receives a priority for vaccination which is a number (say `Float32`). Assume (hypothetically) that the priority is a function of their age, their occupation (essential or not), and their medical condition. Hence there are many possible different priorities.

Continuing with this example, assume the individuals queue (e.g. wait in a big arena or showgrounds area) and are only called when their priority is the highest (clearly high priority individuals won't queue much while others wait for a long while). The management system will then keep track of the priorities of the individuals and do the following:

* Add individuals (this will happen at every arbitrary time in which someone arrives).
* Remove the individual with the highest priority (they then get vaccinated and leave).
* Modify an individual's priority if they complain about waiting too long or in case of other reasons.

There are different alternatives for implementing such a data structure and in all cases the associated "collection" will be called a **priority queue**. It turns out that the heap data structure is the most efficient way to implement a priority (certainly if the number of items is large). But for starters lets consider some naive implemintations.
There are different alternatives for implementing such a data structure and in all cases the associated "collection" will be called a **priority queue**. It turns out that the heap data structure is the most efficient way to implement a priority (certainly if the number of items is large). But for starters lets consider some naive implementations.

A small digression is to see the Julia type of **named tuples**; which present one way of keeping individuals:

Expand All @@ -575,16 +575,16 @@ person_B = (priority = 12.6, name = "Lenna")#if there wasn't "priority =" and "n
@show person_B.priority;
```

So the type of this objects is `NamedTuple{(:priority, :name), Tuple{Float64, String}}` and they are just convient to work with.
So the type of this objects is `NamedTuple{(:priority, :name), Tuple{Float64, String}}` and they are just convenient to work with.

Now back to our naive priority queue. We will just keep an array of the named tuples (the naiveness is not because of the named tuples but because of the fact we are using an array).

```julia
#Create an empty priorty queue as an array of named tuples
#Create an empty priority queue as an array of named tuples
naive_priority_queue = NamedTuple{(:priority, :name), Tuple{Float64, String}}[];
```

Now in the most naive implemintation, every time we add an individual we'll just `push!` their named tuple to the array. For example,
Now in the most naive implementation, every time we add an individual we'll just `push!` their named tuple to the array. For example,

```julia
new_person = (priority = 123.2, name = "Yarden")
Expand Down
Loading