\chapter{Memory Allocators}

\epigraph{Memory memory everywhere but not a allocation to be made}{A really fragmented heap}

\section{Introduction}

Memory allocation is very important!
Allocating and de-allocating heap memory is one of the most common operations in any application.
The heap at the system level is contiguous series of addresses that the program can expand or contract and use as its own accord \cite{mallocinternals}.
In POSIX, this is called the system break.
We use \keyword{sbrk} to move the system break.
Most programs don't interact directly with this call, they use a memory allocation system around it to handle chunking up and keeping track of which memory is allocated and which is freed.

We will mainly be looking into simple allocators.
Just know that there are other ways of dividing up memory like with \keyword{mmap} or other allocation schemes and methods like \keyword{jemalloc}.

\section{C Memory Allocation API}

\begin{itemize}

\item \keyword{malloc(size\_t bytes)} is a C library call and is used to reserve a contiguous block of memory that may be uninitialized \cite[P. 348]{jones2010wg14}.
Unlike stack memory, the memory remains allocated until \keyword{free} is called with the same pointer.
If \keyword{malloc} can either return a pointer to at least that much free space requested or \keyword{NULL}.
That means that malloc can return NULL even if there is some spaces.
Robust programs should check the return value.
If your code assumes \keyword{malloc} succeeds, and it does not, then your program will likely crash (segfault) when it tries to write to address 0.
Also, malloc may not zero out memory because of performance -- check your code to make sure that you are not using uninitialized values.

\item \keyword{realloc(void *space, size\_t bytes)} allows you to resize an existing memory allocation that was previously allocated on the heap (via malloc, calloc, or realloc) \cite[P. 349]{jones2010wg14}.
The most common use of realloc is to resize memory used to hold an array of values.
There are two gotchas with realloc.
One, a new pointer may be returned.
Two, it can fail.
A naive but readable version of realloc is suggested below with sample usage.

\begin{lstlisting}[language=C]
void * realloc(void * ptr, size_t newsize) {
  // Simple implementation always reserves more memory
  // and has no error checking
  void *result = malloc(newsize);
  size_t oldsize =  ... //(depends on allocator's internal data structure)
  if (ptr) memcpy(result, ptr, newsize < oldsize ? newsize : oldsize);
  free(ptr);
  return result;
}

int main() {
  // 1
  int *array = malloc(sizeof(int) * 2);
  array[0] = 10; array[1] = 20;
  // Oops need a bigger array - so use realloc..
  array = realloc(array, 3 * sizeof(int));
  array[2] = 30;

}
\end{lstlisting}

The above code is not robust.
If \keyword{realloc} fails then the array is a memory leak.
Robust code checks for the return value and only reassigns the original pointer if not null.

\begin{lstlisting}[language=C]
int main() {
  // 1
  int *array = malloc(sizeof(int) * 2);
  array[0] = 10; array[1] = 20;
  void *tmp = realloc(array, 3 * sizeof(int));
  if (tmp == NULL) {
    // Nothing I can do here
  } else if (tmp == array) {
    // realloc returned same space
    array[2] = 30;
  } else {
    // realloc returned different space
    array = tmp;
    array[2] = 30;
  }

}
\end{lstlisting}

\item \keyword{calloc(size\_t nmemb, size\_t size)} initializes memory contents to zero and also takes two arguments: the number of items and the size in bytes of each item.
An advanced discussion of these limitations is \href{http://locklessinc.com/articles/calloc/}{in this article}.
Programmers often use \keyword{calloc} rather than explicitly calling \keyword{memset} after \keyword{malloc}, to set the memory contents to zero because certain performance considerations are taken into account.
Note \keyword{calloc(x,y)} is identical to \keyword{calloc(y,x)}, but you should follow the conventions of the manual.
A naive implementation of calloc is below.

\begin{lstlisting}[language=C]
void *calloc(size_t n, size_t size) {
  size_t total = n * size; // Does not check for overflow!
  void *result = malloc(total);

  if (!result) return NULL;

  // If we're using new memory pages
  // just allocated from the system by calling sbrk
  // then they will be zero so zero-ing out is unnecessary,
  // We will be non-robust and memset either way.
  return memset(result, 0, total);
}
\end{lstlisting}

\item \keyword{free} takes a pointer to the start of a piece of memory and makes it available for use in the subsequent calls to the other allocation functions.
This is important because we don't want every process in our address space to take an enormous amount of memory.
Once we are done using memory, we stop using it with free.
A simple usage is below.

\begin{lstlisting}[language=C]
int *ptr = malloc(sizeof(*ptr));
do_something(ptr);
free(ptr);
\end{lstlisting}

If you use a piece of memory after it is freed - that is undefined behavior.

\end{itemize}

\subsection{Heaps and sbrk}

The heap is part of the process memory, and it does not have a fixed size.
Heap memory allocation is performed by the C library when you call \keyword{malloc} (\keyword{calloc}, \keyword{realloc}) and \keyword{free}.
By calling \keyword{sbrk} the C library can increase the size of the heap as your program demands more heap memory.
As the heap and stack need to grow, we put them at opposite ends of the address space.
Stacks don't grow like a heap, new parts of the stack are allocated for new threads.
So for typical architectures the heap will grow upwards and the stack grows downwards.

Nowadays, Modern operating system memory allocators no longer need \keyword{sbrk} - instead they can request independent regions of virtual memory and maintain multiple memory regions.
For example, gibibyte requests may be placed in a different memory region than small allocation requests.
However this detail is an unwanted complexity.

Programs don't need to call \keyword{brk} or \keyword{sbrk} typically, though calling \keyword{sbrk(0)} can be interesting because it tells you where your heap currently ends.
Instead programs use \keyword{malloc},\keyword{calloc},\keyword{realloc} and \keyword{free} which are part of the C library.
The internal implementation of these functions may call \keyword{sbrk} when additional heap memory is required.

\begin{lstlisting}[language=C]
void *top_of_heap = sbrk(0);
malloc(16384);
void *top_of_heap2 = sbrk(0);
printf("The top of heap went from %p to %p \n", top_of_heap, top_of_heap2);
// Example output: The top of heap went from 0x4000 to 0xa000
\end{lstlisting}

An important fact we just glossed over earlier is memory that was newly obtained by the operating system must be zeroed out.
If the operating system did not zero out contents of physical RAM, it might be possible for one process to learn about the memory of another process that had previously used the memory.
This would be a security leak.
Unfortunately this means that for \keyword{malloc} requests before any memory has been freed is \emph{often} zero.
This is unfortunate because, many programmers mistaken write C programs that assume malloc'd memory will \emph{always} be zero.

\begin{lstlisting}[language=C]
char* ptr = malloc(300);
// contents is probably zero because we get brand new memory
// so beginner programs appear to work!
// strcpy(ptr, "Some data"); // work with the data
free(ptr);
// later
char *ptr2 = malloc(300); // Contents might now contain existing data and is probably not zero
\end{lstlisting}

\section{Intro to Allocating}

Let's try to write Malloc.
Here is a first attempt at it -- the naive version.

\begin{lstlisting}[language=C]
void* malloc(size_t size)
{
    // Ask the system for more bytes by extending the heap space.
    // sbrk returns -1 on failure
    void *p = sbrk(size);
    if(p == (void *) -1) return NULL; // No space left
    return p;
}
  void free() {/* Do nothing */}
\end{lstlisting}

Above is the simplest implementation of malloc, there are a few drawbacks though.

\begin{itemize}
\item System calls are slow compared to library calls.
  We should reserve a large amount of memory and only occasionally ask for more from the system.
\item No reuse of freed memory.
  Our program never re-uses heap memory - it just keeps asking for a bigger heap.
\end{itemize}

If this allocator was used in a typical program, the process would quickly exhaust all available memory.
Instead we need an allocator that can efficiently use heap space and only ask for more memory when necessary.
There are programs that may use this type of allocator.
Consider a video game allocating objects to load the next scene.
It is considerably faster to do the above and just throw the entire block of memory away than it is to do the following placement strategies.

\subsection{Placement Strategies}

During program execution, memory is allocated and de-allocated, so there will be gap in the heap memory that can be re-used for future memory requests.
The memory allocator needs to keep track of which parts of the heap are currently allocated and which are parts are available.
Suppose our current heap size is 64K, though not all of it is in use because some earlier malloc'd memory has already been freed by the program.
Let's say that our heap looks like the following table.

\begin{figure}[H]
\centering
\includegraphics[width=.9\textwidth]{malloc/drawings/heap_empty.png}
\caption{Empty heap blocks}
\end{figure}

If a new malloc request for 2KiB is executed (\keyword{malloc(2048)}), where should \keyword{malloc} reserve the memory?
It could use the last 2KiB hole, which happens to be the perfect size!
Or it could split one of the other two free holes.
These choices represent different placement strategies.
Whichever hole is chosen, the allocator will need to split the hole into two.
The newly allocated space, which will be returned to the program and a smaller hole if there is spare space left over.
A perfect-fit strategy finds the smallest hole that is of sufficient size (at least 2KiB):

\begin{figure}[H]
\centering
\includegraphics[width=.9\textwidth]{malloc/drawings/heap_best_fit.png}
\caption{Best fit finds an exact match}
\end{figure}

A worst-fit strategy finds the largest hole that is of sufficient size so break the 30KiB hole into two:

\begin{figure}[H]
\centering
\includegraphics[width=.9\textwidth]{malloc/drawings/heap_worst_fit.png}
\caption{Worst fit finds the worst match}
\end{figure}

A first-fit strategy finds the first available hole that is of sufficient size so break the 16KiB hole into two.
We don't even have to look through the entire heap!

\begin{figure}[H]
\centering
\includegraphics[width=.5\textwidth]{malloc/drawings/heap_first_fit.png}
\caption{First fit finds the first match}
\end{figure}

One thing to keep in mind is that placement strategies don't need to replace the block.
For example, our first fit allocator could've just returned the original block unbroken.
Notice that this would lead to about 14KiB of space to be unused by the user and the allocator.
We call this internal fragmentation.

To introduce another concept, external fragmentation is that even though we have enough memory in the heap, it may be divided up in a way that we are not able to give the full amount.
In our previous example, of the 64KiB of heap memory, 17KiB is allocated, and 47KiB is free.
However, the largest available block is only 30KiB because our available unallocated heap memory is fragmented into smaller pieces.

\subsection{Placement Strategy Pros and Cons}

The challenges of writing a heap allocator are
\begin{itemize}
\item Need to minimize fragmentation (i.e.~maximize memory utilization)
\item Need high performance
\item Fiddly implementation -- lots of pointer manipulation using linked lists and pointer arithmetic.
\item Both fragmentation and performance depend on the application allocation profile, which can be evaluated but not predicted and in practice, under-specific usage conditions, a special-purpose allocator can often out-perform a general purpose implementation.
\item The allocator doesn't know the program's memory allocation requests in advance. Even if we did, this is the \href{http://en.wikipedia.org/wiki/Knapsack_problem}{Knapsack problem} which is known to be NP hard!
\end{itemize}

Different strategies affect the fragmentation of heap memory in non-obvious ways, which only are discovered by mathematical analysis or careful simulations under real-world conditions (for example simulating the memory allocation requests of a database or web server).

First we will have a more mathematical, one-shot approach to each of these algorithms \cite{Garey:1972:WAM:800152.804907}. The paper describes a scenario where you have a certain number of bins, and a certain number of allocations, and you are trying to fit the allocations in as few bins as possible, hence using as little memory as possible.
The paper discusses theoretical implications and puts a nice limit on the ratios in the long run between the ideal memory usage and the actual memory usage.
For those who are interested, the paper concludes that actual memory usage over ideal memory usage as the number of bins increases -- the bins can have any distribution -- is about 1.7 for first fit and lower bounded by 1.7 for best fit.
The problem with this analysis is that very few real world applications need this type of one-shot allocation.
Video game object allocations will typically designate a different subheap for each level and fill up that subheap if they need a quick memory allocation scheme that they can throw away.

In practice, we'll be using the result from a more rigorous survey conducted in 2005 \cite{10.1007/3-540-60368-9_19}.
The survey makes sure to note that memory allocation is a moving target.
A good allocation scheme to one program may not be a good allocation scheme to another program.
Programs don't uniformly follow the distribution of allocations, so very.
The survey talks about all the allocation schemes that we have introduced as well as a few extra ones.
Here are some summarized takeaways

\begin{enumerate}
\item Best fit may have problems when a block is chosen that is almost the right size, and the remaining space is split so small that a program probably won't use it.
  A way to get around this could be to set a threshold for splitting.
  This small splitting isn't observed as frequently under regular work load.
  In addition, the worst case behavior of best fit is bad, but doesn't usually happen p. 43.
\item The survey also talks about an important distinction of first fit.
  There are multiple notions of first.
  First could be ordered in terms of time of free, or it could be ordered through the addresses of the start of the block, or it could be ordered by the time of last free -- first being least recently used.
  The survey didn't go too in depth into the performance of each, but did make a note that address ordered and least recently used lists ended up with better performance than the most recently used first.
\item The survey concludes by first saying that under simulated random (assuming uniform at random) work loads, best fit and first fit do as well. Even in practice, both best and address ordered first fit do about as equally as well with a splitting threshold and coalescing. The reasons why aren't entirely known.
\end{enumerate}

Some additional notes we make

\begin{enumerate}
\item Best fit may not require a full scan of the heap. When a block of perfect size or of perfect size within a threshold is found, that can be returned, depending on what edge-case policy you have.
\item Worst fit may not need to scan the entire heap as well. Your heap could be represented with the max-heap data structure and each allocation call could simply pop the top off, reheapify, and possibly insert a split memory block.
  Using Fibonacci heaps, however, could be extremely inefficient.
\item First fit needs to have some sort of ordering. Most of the time people will default to linked lists which is a fine choice. There aren't too many improvements you can make with a least recently used and most recently used linked list policy, but with address ordered linked lists you can speed up insertion from O(n) to O(log(n)) by using a randomized skip-list in conjunction with your singly linked list.
  Basically an insert would use the skip list as shortcuts to find the right place to insert the block and a removal would go through the list as normal.
\item There are many placement strategies that we haven't talked about, one is next-fit which is first fit on the next fit block. This adds a sort-of deterministic randomness. You won't be expected to know this algorithm, just know as you are implementing a memory allocator as part of a machine problem, there are more than these.
  \end{enumerate}

\section{Memory Allocator Tutorial}

A memory allocator needs to keep track of which bytes are currently allocated and which are available for use.
This section introduces the implementation and conceptual details of building an allocator, or the actual code that implements \keyword{malloc} and \keyword{free}.

Conceptually, we are thinking about creating linked lists and lists of blocks!
Please enjoy the following ASCII art.
bt is short for boundary tag.

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{malloc/drawings/malloc_patching.png}
\caption{3 Adjacent Memory blocks}
\end{figure}

We will have implicit pointers in our next block, meaning that we can get from one block to another using addition.
This is in contrast to an explicit \keyword{metadata *next} field in our meta block.

\begin{figure}[H]
\centering
\includegraphics[width=.5\textwidth]{malloc/drawings/malloc_addition.png}
\caption{Malloc addition}
\end{figure}

One can grab the next block by finding the end of the current one.
That is what we mean by ``implicit list''.

The actual spacing may be different.
The metadata can contain different things.
A minimal metadata would simply have the size of the block.

Since we write integers and pointers into memory that we already control, we can later consistently hop from one address to the next.
This internal information represents some overhead.
Meaning even if we had requested 1024 KiB of contiguous memory from the system, we will not be able to provide all of it to the running program.

Our heap memory is a list of blocks where each block is either allocated or unallocated.
Thus there is conceptually a list of free blocks, but it is implicit in the form of block size information that we store as part of each block.
Let's think of it in terms of a simple implementation.
\begin{lstlisting}[language=C]
typedef struct {
  size_t block_size;
  char data[0];
} block;
block *p = sbrk(100);
p->size = 100 - sizeof(*p) - sizeof(BTag);
// Other block allocations
\end{lstlisting}

We could navigate from one block to the next block just by adding the block's size.

\begin{lstlisting}[language=C]
p + sizeof(metadata) + p->block_size + sizeof(BTag)
\end{lstlisting}

Make sure to get your casting right!
Otherwise you will move an extreme amount of bytes over.

The calling program never sees these values.
They are internal to the implementation of the memory allocator.
As an example, suppose your allocator is asked to reserve 80 bytes (\keyword{malloc(80)}) and requires 8 bytes of internal header data.
The allocator would need to find an unallocated space of at least 88 bytes.
After updating the heap data it would return a pointer to the block.
However, the returned pointer does not point to the start of the block because that's where the internal size data is stored!
Instead we would return the start of the block + 8 bytes.
In the implementation, remember that pointer arithmetic depends on type. For example, \keyword{p\ +=\ 8} adds \keyword{8\ *\ sizeof(p)}, not necessarily 8 bytes!

\subsection{Implementing malloc}

The simplest implementation uses first fit.
Start at the first block, assuming it exists, and iterate until a block that represents unallocated space of sufficient size is found, or we've checked all the blocks.
If no suitable block is found, it's time to call \keyword{sbrk()} again to sufficiently extend the size of the heap.
For the purposes of this class, we will try to serve every memory request until the operating system tells us we are going to run out of heap space.
Other applications may limit themselves to a certain heap size and cause requests to intermittently fail.
In addition, a fast implementation might extend it a significant amount so that we will not need to request more heap memory in the near future.

When a free block is found, it may be larger than the space we need.
If so, we will create two entries in our implicit list.
The first entry is the allocated block, the second entry is the remaining space.
There are ways to do this if you want to keep the overhead small.
We recommend first for going with readability.

\begin{lstlisting}[language=C]
typedef struct {
  size_t block_size;
  int is_free;
  char data[0];
} block;
block *p = sbrk(100);
p->size = 100 - sizeof(*p) - sizeof(boundary_tag);
// Other block allocations
\end{lstlisting}

If you want certain bits to hold different pieces of information, use bit fields!

\begin{lstlisting}[language=C]
typedef struct {
  unsigned int block_size : 7;
  unsigned int is_free : 1;
} size_free;

typedef struct {
  size_free info;
  char data[0];
} block;
\end{lstlisting}

The compiler will handle it for you.
After setting up your fields then it becomes simply looping through each of the blocks and checking the appropriate fields

Here is a visual representation of what happens.
As for some more ascii art, if we assume that we have a block that looks like this, we want to spit if the allocation is let's say 16 bytes
The split we'll have to do is the following.

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{malloc/drawings/malloc_split.png}
\caption{Malloc split}
\end{figure}

This is before alignment concerns as well.

\subsection{Alignment and rounding up considerations}

Many architectures expect multi-byte primitives to be aligned to some multiple of 2 (4, 16, etc).
For example, it's common to require 4-byte types to be aligned to 4-byte boundaries and 8-byte types on 8-byte boundaries.
If multi-byte primitives are not stored on a reasonable boundary for example starting at an odd address then the performance can be significantly impacted because it may require two memory read requests instead of one.
On some architectures the penalty is even greater - the program will crash with a \href{http://en.wikipedia.org/wiki/Bus_error\#Unaligned_access}{bus error}.
Most of you experienced this in your architecture classes if there was no memory protection.

As \keyword{malloc} does not know how the user will use the allocated memory, the pointer returned to the program needs to be aligned for the worst case, which is architecture dependent.

From glibc documentation, the glibc \keyword{malloc} uses the following heuristic \cite{vma_paging}

\begin{quote}
The block that malloc gives you is guaranteed to be aligned so that it can hold any type of data. On GNU systems, the address is always a multiple of eight on most systems, and a multiple of 16 on 64-bit systems." For example, if you need to calculate how many 16 byte units are required, don't forget to round up.
\end{quote}

This is what the math would look like in C.

\begin{lstlisting}[language=C]
int s = (requested_bytes + tag_overhead_bytes + 15) / 16
\end{lstlisting}

The additional constant ensures incomplete units are rounded up. Note, real code is more likely to symbol sizes e.g. \keyword{sizeof(x)\ -\ 1}, rather than coding numerical constant 15.
\href{http://www.ibm.com/developerworks/library/pa-dalign/}{Here's a great article on memory alignment, if you are further interested}

Another added effect is could be internal fragmentation happens when the block you give them is larger than their allocation size.
Let's say that we have a free block of size 16B (not including metadata).
If they allocate 7 bytes, you may want to round up to 16B and just return the entire block.
This gets very sinister when you implementing coalescing and splitting.
If you don't implement either, then you may end up returning a block of size 64B for a 7B allocation!
There is a \emph{lot} of overhead for that allocation which is what we are trying to avoid.

\subsection{Implementing free}

When \keyword{free} is called we need to re-apply the offset to get back to the `real' start of the block -- to where we stored the size information.
A naive implementation would simply mark the block as unused.
If we are storing the block allocation status in a bit field, then we just need to clear the bit:

\begin{lstlisting}[language=C]
p->info.is_free = 0;
\end{lstlisting}

However, we have a bit more work to do.
If the current block and the next block (if it exists) are both free we need to coalesce these blocks into a single block.
Similarly, we also need to check the previous block, too.
If that exists and represents an unallocated memory, then we need to coalesce the blocks into a single large block.

To be able to coalesce a free block with a previous free block we will also need to find the previous block, so we store the block's size at the end of the block, too.
These are called ``boundary tags'' \cite{knuth1973art}.
These are Knuth's solution to the coalescing problem both ways.
As the blocks are contiguous, the end of one blocks sits right next to the start of the next block.
So the current block (apart from the first one) can look a few bytes further back to lookup the size of the previous block.
With this information you can now jump backwards!

Take for example a double coalesce.
If we wanted to free the middle block we need to turn the surrounding blocks into one big blocks

\begin{figure}[H]
\centering
\includegraphics[width=.9\textwidth]{malloc/drawings/malloc_double_coalesce.png}
\caption{Free double coalesce}
\end{figure}

\subsection{Performance}

With the above description it's possible to build a memory allocator.
It's main advantage is simplicity - at least simple compared to other allocators!
Allocating memory is a worst-case linear time operation -- search linked lists for a sufficiently large free block.
De-allocation is constant time.
No more than 3 blocks will need to be coalesced into a single block, and using a most recently used block scheme only one linked list entry.

Using this allocator it is possible to experiment with different placement strategies.
For example, you could start searching from where you last free'd a block, or where you last allocated from.
If you do store pointers to blocks, you need to be very careful that they always remain valid
Particularly when you malloc, free, calloc, realloc, coalesce, split, etc.

\subsection{Explicit Free Lists Allocators}

Better performance can be achieved by implementing an explicit doubly-linked list of free nodes.
In that case, we can immediately traverse to the next free block and the previous free block.
This can reduce the search time, because the linked list only includes unallocated blocks.
A second advantage is that we now have some control over the ordering of the linked list.
For example, when a block is free'd, we could choose to insert it into the beginning of the linked list rather than always between its neighbors.
We may update our struct to look like this

\begin{lstlisting}[language=C]
typedef struct {
  size_t info;
  struct block *next;
  char data[0];
} block;
\end{lstlisting}

Here is what that would look like along with our implicit linked list

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{malloc/drawings/free_list.png}
\caption{Free list}
\end{figure}

Where do we store the pointers of our linked list?
A simple trick is to realize that the block itself is not being used and store the next and previous pointers as part of the block, though now you have to ensure that the free blocks are always sufficiently large to hold two pointers.
We still need to implement Boundary Tags, so we can correctly free blocks and coalesce them with their two neighbors.
Consequently, explicit free lists require more code and complexity.
With explicit linked lists a fast and simple `Find-First' algorithm is used to find the first sufficiently large link.
However, since the link order can be modified, this corresponds to different placement strategies.
For example if the links are maintained from largest to smallest, then this produces a `Worst-Fit' placement strategy.

There are edge cases though, consider how you'd maintain your free list if you also have to perform a double coalesce.
We've included a figure with a common mistake.

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{malloc/drawings/free_list_ptrs.png}
\caption{Free list good and bad coalesce}
\end{figure}

We recommend when trying to implement malloc that you draw out all the cases conceptually and then write the code.

\subsubsection{Explicit linked list insertion policy}

The newly free'd block can be inserted easily into two possible positions: at the beginning or in address order.
Inserting at the beginning creates a LIFO (last-in, first-out) policy.
The most recently free'd spaces will be reused. Studies suggest fragmentation is worse than using address order \cite{10.1007/3-540-60368-9_19}.

Inserting in address order (``Address ordered policy'') inserts free'd blocks so that the blocks are visited in increasing address order.
This policy required more time to free a block because the boundary tags (size data) must be used to find the next and previous unallocated blocks.
However, there is less fragmentation.

\section{Case study: Buddy Allocator, an example of a segregated list}

A segregated allocator is one that divides the heap into different areas that are handled by different sub-allocators dependent on the size of the allocation request.
Sizes are grouped into powers of two and each size is handled by a different sub-allocator and each size maintains its own free list.

A well known allocator of this type is the buddy allocator \cite[P. 85]{rangan1999foundations}.
We'll discuss the binary buddy allocator which splits allocation into blocks of size $2^n; n = 1, 2, 3, ...$ times some base unit number of bytes, but others also exist like Fibonacci split where the allocation is rounded up to the next Fibonacci number.
The basic concept is simple: If there are no free blocks of size $2^n$, go to the next level and steal that block and split it into two.
If two neighboring blocks of the same size become unallocated, they can be coalesced back together into a single large block of twice the size.

Buddy allocators are fast because the neighboring blocks to coalesce with can be calculated from the free'd block's address, rather than traversing the size tags.
Ultimate performance often requires a small amount of assembler code to use a specialized CPU instruction to find the lowest non-zero bit.

The main disadvantage of the Buddy allocator is that they suffer from \emph{internal fragmentation}, because allocations are rounded up to the nearest block size.
For example, a 68-byte allocation will require a 128-byte block.

\section{Further Reading}

There are many other allocation schemes.
One of three allocators used internally by the Linux Kernel.
See \href{http://man7.org/linux/man-pages/man3/malloc.3.html}{the man page} or the appendix of the book \ref{man_malloc}!

\begin{itemize}
\item
  \href{http://en.wikipedia.org/wiki/SLUB_\%28software\%29}{SLUB} (wikipedia)
\item
  \href{http://en.wikipedia.org/wiki/Buddy_memory_allocation}{Wikipedia's buddy memory allocation page}
\end{itemize}

\section{Topics}

\begin{itemize}
\item
  Best Fit
\item
  Worst Fit
\item
  First Fit
\item
  Buddy Allocator
\item
  Internal Fragmentation
\item
  External Fragmentation
\item
  sbrk
\item
  Natural Alignment
\item
  Boundary Tag
\item
  Coalescing
\item
  Splitting
\item
  Slab Allocation/Memory Pool
\end{itemize}

\section{Questions/Exercises}

\begin{itemize}
\tightlist
\item
  What is Internal Fragmentation? When does it become an issue?
\item
  What is External Fragmentation? When does it become an issue?
\item
  What is a Best Fit placement strategy? How is it with External Fragmentation? Time Complexity?
\item
  What is a Worst Fit placement strategy? Is it any better with External Fragmentation? Time Complexity?
\item
  What is the First Fit Placement strategy? It's a little bit better with Fragmentation, right? Expected Time Complexity?
\item
  Let's say that we are using a buddy allocator with a new slab of 64kb. How does it go about allocating 1.5kb?
\item
  When does the 5 line \keyword{sbrk} implementation of malloc have a use?
\item
  What is natural alignment?
\item
  What is Coalescing/Splitting? How do they increase/decrease fragmentation? When can you coalesce or split?
\item
  How do boundary tags work? How can they be used to coalesce or split?
\end{itemize}

\bibliographystyle{plainnat}
\bibliography{malloc/malloc}


\documentclass{article}
\usepackage[dvipsnames]{xcolor}
\usepackage[utf8]{inputenc}
\usepackage{amsmath, amsfonts}
\usepackage{braket}
\usepackage{graphicx}
\usepackage{mathtools}
% \usepackage{thmbox}
\usepackage{amsthm}
\usepackage{qcircuit}
\usepackage{dsfont}
\usepackage{tikz}
\usepackage{mathtools}
\usepackage{enumerate}

\usepackage{caption}
\usepackage[colorlinks,allcolors=blue]{hyperref} % optional
\usepackage[noabbrev,capitalize,nameinlink]{cleveref}
\usepackage[ruled,vlined]{algorithm2e}
\usepackage[style=numeric, sorting=none]{biblatex}
\addbibresource{references.bib}

\usepackage{geometry}
\geometry{margin=1in}

\title{ECON Brainstorming}
\author{Christopher Kang \\
\href{https://www.overleaf.com/read/xbkhntchwshn}{Click for Latest Version}}
\date{\today}

\newcommand{\kron}{\otimes}
\newcommand{\norm}[1]{\left\lVert#1\right\rVert}
\newcommand{\identity}{\mathds{1}}
\newcommand{\how}[1]{\colorbox{BurntOrange}{\textbf{#1}}}
\DeclareMathOperator{\Tr}{Tr}

\DeclarePairedDelimiter\ceil{\lceil}{\rceil}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

\newtheorem{theorem}{Theorem}[section]
\newtheorem{claim}{Claim}[section]
\newtheorem{lemma}{Lemma}[section]
\newtheorem{fact}{Fact}
\newtheorem{corr}{Corollary}[section]
\newtheorem{define}{Definition}
\newtheorem{problem}{Problem}[section]
\newtheorem{practice}{Practice}[section]
\newtheorem{question}{Question}

\newcommand{\indep}{\perp \!\!\! \perp}

\renewcommand{\thesubsection}{\thesection.\alph{subsection}}

\begin{document}

\maketitle

We will begin by restating some useful theorems:
\how{fill me in}

%%1
\section{}
\subsection{}
Yes, $A$ and $B$ can be mutually exclusive. Recall that:
\begin{align}
    \mathbb{P}[A \cup B] = \mathbb{P}[A] + \mathbb{P}[B] - \mathbb{P}[A \cap B] \implies \mathbb{P}[A \cap B] = \mathbb{P}[A] + \mathbb{P}[B] - \mathbb{P}[A \cup B]
\end{align}

We also know that: \how{need to resolve this still}
\begin{align}
    \max(\mathbb{P}[A], \mathbb{P}[B]) \leq \mathbb{P}[A \cup B] \leq
\end{align}

\how{I need to explain this lol}

\subsection{}

\subsection{}

\subsection{}

\subsection{}
No. Suppose, by contradiction, that $A, B$ mutually exclusive and $A \indep B$. If this were the case, then:
\begin{align}
    \mathbb{P}[A \cap B] = 0 = \mathbb{P}[A] \mathbb{P}[B]
\end{align}

However, we know that $\mathbb{P}[A] \mathbb{P}[B] = 0.12$, a contradiction. Thus, $A, B$ cannot be both.

\subsection{}
Recall our equation from (e):
\begin{align}
    \mathbb{P}[A \cap B] = 0 = \mathbb{P}[A] \mathbb{P}[B]
\end{align}

This is true if and only if one of the probabilities take on the value $0$. Thus, because all probabilities are nonnegative,
\begin{align}
    \min \{ \mathbb{P}[C], \mathbb{P}[D] \} = 0
\end{align}

\newpage %% 2
\section{}
Call the event $W \leq 0$ to be $\mathcal{E}_{\leq}$ and $W \geq 0$ to be $\mathcal{E}_\geq$. Then, note that $\mathcal{E}_\leq \cap \mathcal{E}_\geq$ is precisely the event where $W = 0$. Thus, by provided theorems, we know that:
\begin{align}
    \mathbb{P}[\mathcal{E}_\leq \cup \mathcal{E}_\geq] &= \mathbb{P}[\mathcal{E}_\leq] + \mathbb{P}[\mathcal{E}_\geq] - \mathbb{P}[\mathcal{E}_\leq \cap \mathcal{E}_\geq]  \\
    1 &= c + d - \mathbb{P}[W = 0] \\
    \mathbb{P}[W = 0] &= c + d - 1
\end{align}

% \begin{align}
%     \mathbb{P}[\mathcal{E}_\leq \cap \mathcal{E}_\geq] \leq \min \left(\mathbb{P}[\mathcal{E}_\leq], \mathbb{P}[\mathcal{E}_\geq]\right) = \min(c, d)
% \end{align}

% Furthermore, we can produce a lower bound on the event by recognizing $\mathcal{E}_\leq \cup \mathcal{E}_\geq = \mathcal{S}$ where $S$ is the sample space, so that:

% \how{i need to lower bound lmao}

\newpage %% 3
\section{}
\subsection{}
No - because $\mathbb{P}[A \cap B] \neq 0$, $A, B$ are not mutually exclusive.

\subsection{}
From prior theorems, note that:
\begin{align}
    \mathbb{P}[A \cap B] \leq \mathbb{P}[B] \leq \mathbb{P}[A \cup B] \implies \mathbb{P}[B] \in [1/8, 1/2]
\end{align}

\subsection{}
We will employ a proof by contradiction. Suppose that $A \indep B$, so that:
\begin{align}
    \frac{1}{8} = \mathbb{P}[A] \mathbb{P}[B]
\end{align}

Consider that:
\begin{align}
    \mathbb{P}[A \cup B] = \mathbb{P}[A] + \mathbb{P}[B] - \mathbb{P}[A \cap B] \implies \frac{5}{8} - \mathbb{P}[B]= \mathbb{P}[A]
\end{align}

This requires:
\begin{align}
    \frac{1}{8} = \left( \frac{5}{8} - \mathbb{P}[B] \right) \mathbb{P}[B] \implies \mathbb{P}[B]^2 - \frac{5}{8}\mathbb{P}[B] + \frac{1}{8} = 0
\end{align}

We can solve this via the quadratic equation, but it's unnecessary; a simple test of $b^2 - 4ac$ demonstrates that there are no real solutions for $\mathbb{P}[B]$:
\begin{align}
    \frac{25}{64} - \frac{1}{2} < 0
\end{align}

Thus, our assumption was false and we cannot have that $A \indep B$.

\newpage %% 4
\section{}
\subsection{}
Recall that $\mathbb{P}[A \cup B] \geq \max(\mathbb{P}[A], \mathbb{P}[B])$, so $r \geq \max(\mathbb{P}[A], \mathbb{P}[B]), s \geq \max(\mathbb{P}[A], \mathbb{P}[C])$. Thus, it's conceivable that, when $\mathbb{P}[B] = r, \mathbb{P}[C] = s$, that we can allow $\mathbb{P}[A] = 0$.

On the other hand, let's consider the maximal value $\mathbb{P}[A]$ could be. Note that $\mathbb{P}[A] \leq \mathbb{P}[A \cup B], \mathbb{P}[A] \leq \mathbb{P}[A \cup C]$ by the above statements. Thus, $\mathbb{P}[A] \leq \min(\mathbb{P}[A \cup B], \mathbb{P}[A \cup C]) = \min(r, s)$. So, we conclude:
\begin{align}
    0 \leq \mathbb{P}[A] \leq \min(r, s)
\end{align}

\subsection{}
\how{um who knows lmao}

\newpage %% 5
\section{}
\subsection{}

\subsection{}

\subsection{}

\subsection{}

\subsection{}

\subsection{}

\subsection{}

\newpage %% 6
\section{}
\subsection{}

\subsection{}

\subsection{}

\subsection{}

\newpage %% 7
\section{}
\subsection{}
\begin{proof}
We seek to show that $A^C \indep B^C$ by demonstrating that $\mathbb{P}[A^C \cap B^C] = \mathbb{P}[A^C] \mathbb{P}[B^C]$. Recall that, if we partition the sample space, it's probability must sum to 1. Thus,
\begin{align}
    \mathbb{P}[A \cup B] + \mathbb{P}[\widetilde{A \cup B}] &= 1 \\
    \mathbb{P}[A] + \mathbb{P}[B] - \mathbb{P}[A \cap B] + \mathbb{P}[A^C \cap B^C] &= 1 \\
    \mathbb{P}[A^C \cap B^C] &= 1 - \mathbb{P}[A] - \mathbb{P}[B] + \mathbb{P}[A] \mathbb{P}[B] \\
    &= 1 - \mathbb{P}[A] - \mathbb{P}[B](1 - \mathbb{P}[A]) \\
    &= (1 - \mathbb{P}[B])(1- \mathbb{P}[A]) \\
    \mathbb{P}[A^C \cap B^C] &= \mathbb{P}[A^C] \mathbb{P}[B^C]
\end{align}

As desired.
\end{proof}

\subsection{}

\subsection{}
$A \indep B$:
\begin{proof}
We seek to show $\mathbb{P}[A \cap B] = \mathbb{P}[A] \mathbb{P}[B]$. Note that $\mathbb{P}[A]$ is $\frac{1}{6}$, as is $\mathbb{P}[B]$. We also know that $\mathbb{P}[A \cap B] = \frac{1}{36}$, because there is only one possibility where both die are 6 $(6, 6)$, while there are 36, equally likely possibilities for both die roles. Thus,
\begin{align}
    \mathbb{P}[A \cap B] = \frac{1}{36} = \frac{1}{6} \cdot \frac{1}{6} = \mathbb{P}[A] \mathbb{P}[B]
\end{align}
\end{proof}

$A \not \indep B | D$ \how{?}
\begin{proof}

\end{proof}

\printbibliography
\end{document}

% This is actually the Taylor series for $e^x$; so, substituting, we see:

% \begin{align}
%     &= 2 \Big[ \sum_{k = 0}^{\infty} \frac{1}{k!} \Big(\frac{2\lambda t}{N}\Big)^k - 1 - \Big(\frac{2\lambda t}{N}\Big) \Big]
% \end{align}


\section{Matrix: Matrices}
The matrix computations are implemented naively.  Consider
Krey88 to be the source, though any number of texts would
serve.  Notably, Gems90 takes the naive approach for vectors
and matrixrices of 3 and 4 dimensions.

Further testing may show that large matrixes need more
careful treatment of truncation.


%%%%%%%%%%%%%%%%
% switch from arc to beamer
%%%%%%%%%%%%%%%%
\PassOptionsToClass{a4paper,10pt}{article} % for article mode
\PassOptionsToClass{aspectratio=1610,10pt}{beamer} % for beamer, handout, trans modes
\newcommand*{\BeamerswitchSpawn}[1]{
\ShellEscape{... -jobname=\jobname#1 \jobname} %
}
\documentclass{beamerswitch}
\mode<article>{
    \usepackage[top=3cm, bottom=3cm, left=3cm, right=3cm]{geometry}
}
\mode<presentation>{
    \usefonttheme[onlymath]{serif}
}

\usepackage{amsmath, amsthm, amsfonts}
\usepackage{subfiles, bm, hyperref, graphicx, listings}
\usepackage{authblk}
\usepackage{subcaption}
\usepackage{xcolor}
% my cmd
%%%%%%%%%%%%%%%%
% start my commands
%%%%%%%%%%%%%%%%
\newcommand{\lm}{\lambda_\textrm{max}}
\newcommand{\trace}{\mathbf{trace}}
\newcommand{\diag}{\mathbf{diag}}
\newcommand{\model}[1]{(\textbf{#1})}
\newcommand{\mx}{\mathbf{\max}\;}
\newcommand{\mn}{\mathbf{\min}\;}
\newcommand{\st}{\mathrm{s.t.\;}}
\newcommand{\ex}{\mathbb E}
\newcommand{\dx}{\;\bm dx}
\newcommand{\pr}{\mathbb P}
\newcommand{\id}{\mathbb I}
\newcommand{\bp}{\mathbb P}
\newcommand{\be}{\mathbb E}
\newcommand{\bi}{\mathbb I}
\newcommand{\bxi}{\bm \xi}
\newcommand{\bo}{\bm \omega}
\newcommand{\va}{\mathbf{Var}}
\newcommand{\dif}{\mathbf{d}}
\newcommand{\minp}[2]{\min\{#1, #2\}}
\newcommand{\intp}{\mathbf{int}}
\newcommand{\apex}{\mathbf{apex}}
\newcommand{\conv}{\mathbf{conv}}
%%%%%%%%%%%%%%%%
% finish my commands
%%%%%%%%%%%%%%%%

% theorem environments
\newtheorem{thm}{Theorem}[section]
\newtheorem{defn}[thm]{Definition}
\newtheorem{cor}[thm]{Corollary}
\newtheorem{lem}[thm]{Lemma}
\newtheorem{remark}[thm]{Remark}
% my code style
%%%%%%%%%%%%%%%%
% start my commands
%%%%%%%%%%%%%%%%
\lstdefinestyle{codestyle}{
    basicstyle=\ttfamily\footnotesize,
    tabsize=2
    \scriptsize
}
\title{Notes on Stochastic Programming}

\begin{document}

\author[1]{\small Chuwen Zhang}
\author[1]{\small Jingyuan Yang}
\affil[1]{\footnotesize Stochastic Programming Reading Group}

\maketitle
\section{Mathematical Background}

This week we introduce the basics for convex functions, differentiation, and so on.

\emph{\textcolor{red}{See the hand written notes.}}

\begin{thm}[\cite{rockafellar_variational_2009} Theorem 6.12, basic first-order conditions for optimality] Consider a problem of minimizing a differentiable function \(f_{0}\) over a set \(C \subset R ^{n} . A\) necessary condition for \(\bar{x}\) to be locally optimal is
    \begin{align*}
        \left\langle\nabla f_{0}(\bar{x}), w\right\rangle \geq 0 \text { for all } w \in T_{C}(\bar{x}), \quad 6(10)
    \end{align*}
    which is the same as \(-\nabla f_{0}(\bar{x}) \in \widehat{N}_{C}(\bar{x})\) and implies
    \begin{align*}
        -\nabla f_{0}(\bar{x}) \in N_{C}(\bar{x}), \quad \text { or } \nabla f_{0}(\bar{x})+N_{C}(\bar{x}) \ni 0 . \quad 6(11)
    \end{align*}
    When \(C\) is convex, these tangent and normal cone conditions are equivalent and can be written also in the form
    \begin{align*}
        \left\langle\nabla f_{0}(\bar{x}), x-\bar{x}\right\rangle \geq 0 \text { for all } x \in C,
    \end{align*}
    which means that the linearized function \(l(x):=f_{0}(\bar{x})+\left\langle\nabla f_{0}(\bar{x}), x-\bar{x}\right\rangle\) achieves its minimum over \(C\) at \(\bar{x}\). When \(f_{0}\) too is convex, the equivalent conditions are sufficient for \(\bar{x}\) to be globally optimal.
\end{thm}

\section{Two-stage Problems}

When talk about the two-stage problems, we basically follow an analytic routine:

\begin{enumerate}
    \item The value function \(Q(x, \xi)\): differentiation calculus, completeness.
    \item The completeness of recourse contributes to existence of the \emph{cost-to-go function}, i.e., the expectation of \(Q: \phi(\cdot) = \ex(Q(\cdot, \xi))\)
    \item The existence of \(\phi\) is essentially about an integral being finite
    \item In the discrete case, we need for any \(\xi\) the recourse problem is feasible: the dual is bounded.
    \item In the continuous case, more technical conditions are needed. In accordance with the case of discrete distribution, the recourse problem should be feasible a.e.
    \item With that being said, we could finally discuss the differentiation (first-order condition) of \(\phi\) which is essential to optimality conditions.
\end{enumerate}

\subsection{Polyhedral Two-Stage Problems}
\begin{defn} A Two-Stage Problems is called polyhedral if it can be written as follows,
    \begin{align*}
        f_{1}(x)= \begin{cases}\max _{1 \leq j \leq J_{1}} \alpha_{j}+c_{j}^{\top} x & \text { if } a_{k}^{\top} x \leq b_{k}, \quad k=1, \ldots, K_{1} \\ +\infty & \text { otherwise }\end{cases}
    \end{align*}
    where \(f_1\) is the first stage problem. Second stage problem \(f_2\) can written as
    \begin{align*}
        f_{2}(y, \omega)= \begin{cases}\max _{1 \leq j \leq J_{2}} \gamma_{j}(\omega)+q_{j}(\omega)^{\top} y & \text { if } d_{k}(\omega)^{\top} y \leq r_{k}(\omega), \quad k=1, \ldots, K_{2} \\ +\infty & \text { otherwise }\end{cases}
    \end{align*}
    almost everywhere.
\end{defn}

We mark the preliminary facts: if the problem is polyhedral, it can be rewritten to a linear problem.

\begin{thm}[Differentiation of value function]
    The differentiation conclusions for \(Q\) holds just like the linear case. That is,
    \begin{equation}
        \partial Q(\cdot, \omega) = - T^T \mathfrak D(x, w)
    \end{equation}
    where \(\mathfrak D\) is the optimal dual solutions.
\end{thm}

\begin{thm}[Differentiation of cost-to-go function]
    Similar results to those of linear models.

    For discrete distributions:
    \begin{equation}
        \partial \phi\left(x_{0}\right)=\sum_{k=1}^{K} p_{k} \partial Q\left(x_{0}, \omega_{k}\right)
    \end{equation}

    For continuous distributions:
    \begin{equation}\label{eq.cont.diff}
        \partial \phi\left(x_{0}\right)=- \ex \left[T^{\top} \mathfrak D \left(x_{0}, \omega\right)\right]+ \mathcal N_{\text {dom} \phi}\left(x_{0}\right)
    \end{equation}
\end{thm}

For continuous case we should be more careful, \eqref{eq.cont.diff} is true for free. We omit the technical details here.

We now consider the optimal condition for two-stage problems. Since the problem is convex, the first-order conditions suffice:

\begin{equation}
    0 \in \partial f_1(\cdot) + \partial \phi(\cdot)
\end{equation}

The above equation directly reduces to the discrete and continuous case analyzed above.

\subsection{General Problems \and Convex Problems}
The results can be \emph{conjectured} like polyhedral problems. We will revisit them later.

\section{Nonanticipativity}

It can be shown the two-stage problem without \emph{here-and-now} decision can be written as,
\begin{equation}
    \underset{x_{1}, \ldots, x_{K}}{\min} \sum_{k=1}^{K} p_{k} F\left(x_{k}, \omega_{k}\right) \text { subject to } x_{k} \in X, k=1, \ldots, K \text {. }
\end{equation}

with \(x_k = x, k = 1, ..., K\) we have the \textcolor{red}{equivalent} problem. This allows a natural decomposition of scenarios \(w_1, ..., w_k\).

The anticipativity constraint can be described in two alternatives,

\begin{align*}
     & I \cdot x = x_0                    \\
     & P \cdot x = x, P = [p^T, ..., p^T]
\end{align*}

using the second equation and let \(\lambda\) be the Lagrangian multipliers.

\begin{align*}
    L = p^T F + \lambda^T(I-P)x
\end{align*}

We can define the dual function, \(D(\lambda) = \min_x L\), if we have strong duality, then we optimize over \(\lambda\).

\begin{frame}[allowframebreaks]
    \bibliography{robust}
    \bibliographystyle{apalike}
\end{frame}
\end{document}


\chapter{Analysis and prediction of seiyuu popularity}

Popularity is an abstract criterion that must be defined as a numerical metric in order to be used for analysis and prediction. Since we are using MAL database and it has a social component, seems logic to use member\_favorites as a representation of popularity. We can also get popularity and score of anime from opinions of the same set of users.\\

In terms of distribution \textit{popularity} is highly unequal \---as we can observe in Fig.~\ref{fig:popularityDistribution}\--- having a lot of seiyuu which are no member favorites and only a few who are favorite of more than 10000 members. It's good to keep in mind that users can favorite multiple seiyuu.

\begin{figure}[!h]
	\begin{center}
	\includegraphics[width=\columnwidth]{graphics/popularityDistribution.png}
	\caption{Amount of seiyuu with that popularity, divided into groups for better visualization.}
	\label{fig:popularityDistribution}
	\end{center}
\end{figure}

\newpage

Some metrics about popularity:
\begin{itemize}
	\item Mean:    289.55
	\item Median:    2.0
	\item Max:    55018
	\item Min:    0
	\item 1037 values equal to zero
	\item Only 120 values bigger than 1000
\end{itemize}

\begin{table}[!h]
	\begin{center}
	\caption{Top 10 popular seiyuu}
	\label{tab:top10Popularity}
	\begin{tabular}{|l|c|l|}
		\hline
		Name & Popularity & Some popular roles of them\\
		\hline
		Kana Hanazawa & 56637 & \textit{Angel Beats!}: Tachibana, Kanade \\
		 & & \textit{Steins;Gate}: Shiina, Mayuri \\
		 & & \textit{Psycho-Pass}: Tsunemori, Akane \\
		\hline
		Hiroshi Kamiya & 49685 & \textit{Shingeki no Kyojin}: Levi, \\
		 & & \textit{Noragami}: Yato \\
		 & & \textit{Durarara!!}: Orihara, Izaya \\
		\hline
		Mamoru Miyano & 43942 & \textit{Death Note}: Yagami, Light \\
		 & & \textit{Steins;Gate}: Okabe, Rintarou \\
		 & & \textit{Soul Eater}: Death the Kid \\
		\hline
		Rie Kugimiya & 31668 & \textit{Toradora!}: Aisaka, Taiga \\
		 & & \textit{Fairy Tail}: Happy \\
		 & & \textit{Fullmetal Alchemist}: Elric, Alphonse \\
		\hline
		Jun Fukuyama & 26811 & \textit{Code Geass: Hangyaku no Lelouch}: Lamperouge, Lelouch, \\
		 & & \textit{Ao no Exorcist}: Okumura, Yukio \\
		 & & \textit{Noragami}: Kazuma \\
		\hline
		Miyuki Sawashiro & 26501 & \textit{Sword Art Online II}: Asada, Shino \\
		 & & \textit{Durarara!!}: Sturluson, Celty \\
		 & & \textit{Highschool of the Dead}: Busujima, Saeko \\
		\hline
		Tomokazu Sugita & 24449 & \textit{Suzumiya Haruhi no Yuuutsu}: Kyon \\
		 & & \textit{JoJo no Kimyou na Bouken (TV)}: Joestar, Joseph \\
		 & & \textit{Gintama}: Sakata, Gintoki \\
		\hline
		Daisuke Ono & 24080 & \textit{Durarara!!}: Heiwajima, Shizuo \\
		 & & \textit{Kuroshitsuji}: Michaelis, Sebastian \\
		 & & \textit{Suzumiya Haruhi no Yuuutsu}: Koizumi, Itsuki \\
		\hline
		Saori Hayami & 18322 & \textit{Koe no Katachi}: Nishimiya, Shouko \\
		 & & \textit{Owari no Seraph}: Hiiragi, Shinoa \\
		 & & \textit{Mahouka Koukou no Rettousei}: Shiba, Miyuki \\
		\hline
		Aya Hirano & 18094 & \textit{Fairy Tail}: Heartfilia, Lucy \\
		 & & \textit{Kiseijuu: Sei no Kakuritsu}: Migi \\
		 & & \textit{Suzumiya Haruhi no Yuuutsu}: Suzumiya, Haruhi \\
		\hline
	\end{tabular}
	\end{center}
\end{table}

\newpage
\section{Correlation with only one feature}
Our first approach to explaining popularity was using Pearson correlation.

\begin{figure}[!h]
	\begin{flushleft}
	\makebox[\textwidth][c]{\includegraphics[width=1.7\columnwidth]{graphics/10Works_correlation_Pearson_allWorks.png}}%
	\caption{Pearson correlation between popularity and attribute of nodes (using all works).}
	\label{fig:pearsonCorrAllWorks}
	\end{flushleft}
\end{figure}

As shown on Fig.~\ref{fig:pearsonCorrAllWorks} a fairly big correlation can be seen between popularity and amount of works. This attribute doesn't have the biggest correlation with popularity but "number of main roles" was added to the end of this investigation since we didn't had the data for doing so before. Number of main roles and amount of works have a strong correlation with each other (0.9) but they have different influence over popularity, this means they provide distinct information.

We are showing only average of values for work's attributes (ex. favorites) mostly for better visualization but for predictions we use sum, mean, median and maximum.

Since our dataset is biased in favor of more modern anime we thought of correlate with recent works only. But, how recent? Last 5, 10 or 20 years? Thus correlation between popularity and works from different data frames was analyzed, Fig.~\ref{fig:correlationPopRecentWorks}.

\begin{figure}[!h]
	\begin{center}
	\includegraphics[width=\columnwidth]{graphics/correlationPopRecentWorks.png}
	\caption{Last \textit{X} years means works from 2018-\textit{X} to present.}
	\label{fig:correlationPopRecentWorks}
	\end{center}
\end{figure}

The best result was given by recent works from last 9 years. Therefore, this definition of recent works was used from there on.

Fig.~\ref{fig:pearsonCorrRecentWorks} shows the result of running Pearson again but using information from last 9 years of works only. It's important to clarify that we didn't build the network using only last 9 years, so betweenness centrality and degree are exactly the same as before. We left "amount of works" attribute for easy comparision against "amount of recent works".

\begin{figure}[!h]
	\begin{flushleft}
	\makebox[\textwidth][c]{\includegraphics[width=1.7\columnwidth]{graphics/10Works_correlation_Pearson_recentWorks.png}}%
	\caption{Pearson correlation between popularity and attribute of nodes (using recent works only).}
	\label{fig:pearsonCorrRecentWorks}
	\end{flushleft}
\end{figure}

\FloatBarrier
\subsection{Why last 9 years of works has more correlation?}
Graphics of some characteristics of works divided by years were made, trying to shed some light over why works from last 9 years were more "important".

\begin{sidewaysfigure}
	\centering
	\begin{subfigure}{.55\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/avgFavorites.png}
		\caption{Average amount of favorites per year.}
		\label{fig:avgFavorites}
	\end{subfigure}%
	\begin{subfigure}{.55\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/avgScores.png}
		\caption{Average score per year.}
		\label{fig:avgScores}
	\end{subfigure}
	\begin{subfigure}{.55\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/avgPopularities.png}
		\caption{Average popularity per year.}
		\label{fig:avgPopularities}
	\end{subfigure}%
	\begin{subfigure}{.55\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/avgMembers.png}
		\caption{Average amount of members per year.}
		\label{fig:avgMembers}
	\end{subfigure}
	\caption{Averages of some atributes of anime divide by year.}
	\label{fig:averages}
\end{sidewaysfigure}

Fig.~\ref{fig:avgFavorites} and ~\ref{fig:avgScores} shows an improvement in average of scores and favorites.
Biggest peak of favorites is on 2005, this may have to do with the start of MAL (2006), see Fig.~\ref{fig:avgFavorites}. We suppose as users started to use MAL they favorite anime they liked from that year and only some of the old ones; from then on they used the website often and favorite new works as they began airing.

Year 2018 was left out of Fig.~\ref{fig:avgScores} because, since 2018 is not finished yet, the average of scores was unusually small.

As Fig.~\ref{fig:avgPopularities} shows, popularity goes down in last years. But we need to consider that this metrics are from MAL and it could mean, for example, the parameter is in disuse; instead of representing how people feel about new anime.\\

We suppose the attribute "members" of an anime is taken from how many users have it on any of their lists. If that is correct Fig.~\ref{fig:avgMembers} tells us feature of adding anime in watched / watching / plan to watch lists is really used. As for our experience on the web and social media we can confirm this is the most used feature of MAL. So this makes it one of the best metrics to measure "public" as another sense of popularity of anime.\\

As we can see on Fig.~\ref{fig:amountOfWorksPerYear} anime industry is growing bigger each year, of course this is biased by the fact MAL will sure have every adaptation of last year but maybe not for anime from 1980.

\begin{figure}[!h]
	\begin{center}
	\includegraphics[width=\columnwidth]{graphics/worksPerYear_1960-2018.png}
	\caption{Amount of works divided by years which were aired for the first time.}
	\label{fig:amountOfWorksPerYear}
	\end{center}
\end{figure}

The majority of works are from 1990 to 2018 and half of them are distributed over the last 14 years (2014 to 2018) but as far as we can tell there isn’t anything particular over the last 9 years nor on year 2009. Judging by amount of favorites per year it appears that users have been more active in recent years so this could be one of the reasons.

\section{Correlation with multiple features}
For this section Scikit-learn, a free software machine learning Python library, was used. The node attributes were divided into categories, leaving four distinct types:

\begin{itemize}
	\item Personal data:
	\begin{itemize}
		\item Debut
		\item Gender
		\item Activity years (2018-debut)
	\end{itemize}
	\item Works data:
	\begin{itemize}
		\item Amount
		\item Top 5 genre
		\item Favorites
		\item Score
		\item Popularity
		\item Members
		\item Number of main roles
	\end{itemize}
	\item Recent works data:
	\begin{itemize}
		\item Same as works but for only last 9 years
	\end{itemize}
	\item Graph data:
	\begin{itemize}
		\item Degree
		\item Betweenness centrality
		\item Closeness
	\end{itemize}
\end{itemize}

Fitting and prediction experiments were run for each category, each combination of 2, 3 and all of them together; using 80\% of seiyuu as train data and the rest as test. This was done for all following models:
\begin{itemize}
	\item DecisionTreeRegressor
	\item DecisionTreeClassifier
	\item LinearRegression
	\item KNeighborsClassifier
	\item LinearDiscriminantAnalysis
	\item GaussianNB
	\item SVM
\end{itemize}

We used r2\_score\footnote{\url{http://scikit-learn.org/stable/modules/model_evaluation.html#r2-score-the-coefficient-of-determination}} for accuracy comparation. Problem is, since popularity variance is really high, we observed some good results in terms of r2\_score values but particular predictions were aloof.

If we predict without error a seiyuu whose popularity is \textgreater50000 but we make "small" mistakes predicting seiyuu with \textless100 popularity then, is it a good prediction? and having into account more than $\frac{3}{4}$ of them have \textless100 popularity?

This was happening to our predictions. Since they were on spot for higher popularity values their prediction performance's metrics were good; but in fact they failed on small values, which is the big majority of them.

Fig.~\ref{fig:scatterPlot_DTC_WR} and Fig.~\ref{fig:scatterPlot_LR_WR} shows some examples.\\

\begin{figure}
	\centering
	\begin{subfigure}{.5\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/Work_RecentWorks_DecisionTreeClassifier.png}
		\caption{All values.}
	\end{subfigure}%
	\begin{subfigure}{.5\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/Work_RecentWorks_DecisionTreeClassifierZOOM.png}
		\caption{If we zoom in we can tell it's actually bad predictions.}
	\end{subfigure}
	\caption{Scatter plot showing predicted / measured for Decision Tree Classifier using model Work + RecentWorks.}
	\label{fig:scatterPlot_DTC_WR}
\end{figure}

\begin{figure}
	\centering
	\begin{subfigure}{.5\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/Work_RecentWorks_LinearRegression.png}
		\caption{All values.}
		\label{fig:avgFavorites}
	\end{subfigure}%
	\begin{subfigure}{.5\columnwidth}
		\centering
		\includegraphics[width=\columnwidth]{graphics/Work_RecentWorks_LinearRegressionZOOM.png}
		\caption{Zoomed in.}
		\label{fig:avgScores}
	\end{subfigure}
	\caption{Scatter plot showing predicted / measured for Linear Regression using model Work + RecentWorks.}
	\label{fig:scatterPlot_LR_WR}
\end{figure}

On the next subchapters we present r2\_score values for each algorithm and each combination of categories. Along with information about which feature is more important, from the Decision Tree Classifier's point of view (for only some of the models).

%-------------------------------------------------------------------------------
\FloatBarrier
\subsection{Only one category}
\begin{table}[!hbt]
	\begin{center}
	\caption{Only one category R2 score results}
	\label{tab:oneCategory}
	\include{tables/oneCategory_r2score}
	\end{center}
\end{table}

Table.~\ref{tab:oneCategory} reveals that Recent Works is the most performant if we are only using one category.

\begin{figure}[!hbt]
	\centering
	\includegraphics[width=\columnwidth]{graphics/Personal_DTC_featureImportances.png}
	\caption{Feature information contribution for Personal data.}
	\label{fig:DTC_P}
\end{figure}

Fig.~\ref{fig:DTC_P} shows that Decision Tree Classifier firstly uses activity years and debut to distinguish between most clases.

\begin{figure}[!hbt]
	\centering
	\includegraphics[width=\columnwidth]{graphics/RecentWorks_DTC_featureImportances.png}
	\caption{Feature information contribution for Recent works.}
	\label{fig:DTC_R}
\end{figure}

Decision Tree Classifier has bad performance when using only Recent works data but there's something very interesting about Fig.~\ref{fig:DTC_R}, when using Work and Recent works "number of \textit{recent} main roles" is not used to classify but here it is used; we suppose is because it doesn't provide new information against "number of mail roles" (see Fig.~\ref{fig:DTC_WR}).

%-------------------------------------------------------------------------------
\FloatBarrier
\subsection{Groups of two categories}
\begin{table}[!hbt]
	\begin{center}
	\caption{Two categories R2 score results (R: recent works, P: personal, G: graph, W: work)}
	\label{tab:twoCategories}
	\include{tables/twoCategories_r2score}
	\end{center}
\end{table}

Table.~\ref{tab:twoCategories} shows ones of the best r2\_scores of all predictions. Decision Tree Classifier, Linear Discriminant Analysis and Linear Regression all did well when using Work + Recent Works model.

\begin{figure}[!hbt]
	\centering
	\includegraphics[width=\columnwidth]{graphics/Work_RecentWorks_DTC_featureImportances.png}
	\caption{Feature information contribution for Work + Recent works model.}
	\label{fig:DTC_WR}
\end{figure}

As Fig.~\ref{fig:DTC_WR} reveals number of main roles is a very important feature to classify seiyuu by popularity. We saw earlier that it has a strong correlation.

%-------------------------------------------------------------------------------
\FloatBarrier
\subsection{Groups of three categories}
\begin{table}[!hbt]
	\begin{center}
	\caption{Three categories R2 score results (R: recent works, P: personal, G: graph, W: work)}
	\label{tab:threeCategories}
	\include{tables/threeCategories_r2score}
	\end{center}
\end{table}

According to Table.~\ref{tab:threeCategories} three categories models have bad performance for most algorithm but it also has the highest (best) value of all. Is achieved by K Neighbors Classifier when using Personal + Graph + Recent works data.

\begin{figure}[!hbt]
	\centering
	\includegraphics[width=\columnwidth]{graphics/Personal_Work_RecentWorks_DTC_featureImportances.png}
	\caption{Feature information contribution for Personal + Work + Recent works model.}
	\label{fig:DTC_PWR}
\end{figure}

Fig.~\ref{fig:DTC_PWR} tells us, as we already saw before, that number of main roles is a very important feature. Also, notice that number of \textit{recent} main roles does not appear.

%-------------------------------------------------------------------------------
\FloatBarrier
\subsection{All categories}
\begin{table}[!hbt]
	\begin{center}
	\caption{All categories R2 score results}
	\label{tab:allCategories}
	\include{tables/allCategories_r2score}
	\end{center}
\end{table}

Table.~\ref{tab:allCategories} Decision Tree Classifier has bad performance when using all categories, this can be because it overfits train data. Linear Discriminant Analysis and Linear Regression doesn't seem to do that bad, Decision Tree Regressor also. Of course, once we saw the scatter plots particular predictions were wrong most of the times for small values, showing a very different reality from value of metrics.

\begin{figure}[!hbt]
	\centering
	\includegraphics[width=\columnwidth]{graphics/AllFeatures_DTC_featureImportances.png}
	\caption{Feature information contribution for model using all categories.}
	\label{fig:DTC_All}
\end{figure}

As Fig.~\ref{fig:DTC_All} shows, even when using all features "number of main roles" is still the one that separates more values, having almost double importance than the second one (sum of score of works).


\documentclass[a4paper]{article}
\usepackage[inline]{enumitem}
\input{head}
\begin{document}

%-------------------------------
%	TITLE SECTION
%-------------------------------

\fancyhead[C]{}
\hrule \medskip % Upper rule
\begin{minipage}{0.295\textwidth}
\raggedright
\footnotesize
Winston Peng \hfill\\
50364686 \hfill\\
wpeng2@buffalo.edu
\end{minipage}
\begin{minipage}{0.4\textwidth}
\centering
\large
Homework 3 - Sets\\
\normalsize
Intro To Discrete Structures, 2021\\
\end{minipage}
\begin{minipage}{0.295\textwidth}
\raggedleft
\today\hfill\\
\end{minipage}
\medskip\hrule
\bigskip

\section{Translate English To Math - Sets}
\large Sets: \smallskip \\
\normalsize
A: The set of students who are taking cs majors \\
B: The set of students taking CSE 191

\begin{enumerate}
    \item \textbf{The set of cs majors taking CSE 191} $A \cap B$
    \item \textbf{The set of cs majors not taking CSE 191} $A \cap \neg B$
    \item \textbf{The set of either cs majors or CSE 191 students} $A \cup B$
    \item \textbf{The set of students either not cs majors or not taking CSE 191} $\neg A \cup \neg B$
\end{enumerate}

\bigskip %-------------------------

\section{Generalized Set Operators}
Let $A_i = \{-i, ...,-2, -1, 0, 1, 2, ..., i\}$
\begin{enumerate}
    \item \boldmath $\bigcup\limits_{i=1}^n A_i$ \unboldmath $= A_1 \cup A_2 \cup ... \cup A_n = \{-1, 0, 1\} \cup \{-2, -1, 0, 1, 2\} \cup ... \cup \{-n, ..., -1, 0, 1, ..., n\}$ \\
    \boldmath $A$\unboldmath $_n$ \boldmath $ = \{$ \unboldmath
    $-n, ..., -1, 0, 1, ..., n$
    \boldmath $\}$
    \item $\bigcap\limits_{i=1}^n A_i$ \unboldmath $= A_1 \cap A_2 \cap ... \cap A_n = \{-1, 0, 1\} \cap \{-2, -1, 0, 1, 2\} \cap ... \cap \{-n, ..., -1, 0, 1, ..., n\}$ \\
    \boldmath $A$\unboldmath $_1$ \boldmath $= \{$ \unboldmath $-1, 0, 1$ \boldmath $\}$
\end{enumerate}

\section{Set Operations}
Describe resulting set using roster notation \\
% \setlength\parindent{24pt}
\hspace*{10mm} A = $(\{0\} \cup \{x \, | \, x \in \mathbb{Z}^+$ and $x < 4\})$ \\
\hspace*{10mm} B = $\{0, 1, 3, 5, 7\}, and$ \\
\hspace*{10mm} C = $(\{0\} \cup \{x \, | \, x \in \mathbb{Z}^+$ and $x$ is even and $x < 8\})$

\begin{enumerate}
    \item \boldmath $A \oplus B$ \unboldmath \\
    $\{2, 5, 7\}$
    \item \boldmath $(A \cup B \cup C) - (A \cap B \cap C)$ \unboldmath \\
    $\{1, 2, 3, 4, 5, 6, 7\}$
    \item \boldmath $B \oplus (A \cap C)\\
    $ \unboldmath $\{2\}$
    \item \boldmath $B \oplus B$ \unboldmath \\
    $\{\}$
    \item \boldmath $C \oplus \varphi$ \unboldmath \\
    $\{0, 2, 4, 6\}$
\end{enumerate}

\bigskip %-----------------------------

\section{Set Operations}
Describe (a-e) using roster notation \\
\hspace*{10mm} A = $\{0, 1\}$, \\
\hspace*{10mm} B = $\{x\}$, and \\
\hspace*{10mm} C = $\{red, green, blue\}$. \\

\begin{enumerate}
    \item \textbf{(A $\times$ B) $\times$ C} \\
    \{(0, x), (1, x), ((0, x), red), ((1, x), red), ((0, x), green), ((1, x), green), ((0, x), blue), ((1, x), blue)\}
    \item \textbf{$\mathcal{P}$(A $\times$ B)} \\
    $\mathcal{P}$\{(0, x), (1, x)\} \\
    \{$\O$, (0, x), (1, x), \{(0, x), (1, x)\}\}
    \item \textbf{$\mathcal{P}$(A) $\times \mathcal{P}$(B)} \\
    \{$\O$, \{0\}, \{1\}, \{1, 2\}\} $\times$ \{$\O$, \{x\}\} \\
    \{($\O$, $\O$), ($\O$, \{x\}), (\{0\}, $\O$), (\{0\}, \{x\}), (\{1\}, $\O$), (\{1\}, \{x\}), (\{1, 2\}, $\O$), (\{1, 2\}, \{x\})\}
    \item \textbf{A$^0 \cup $ A$^2 \cup$ A$^3$} \\
    \{()\} $\cup$ \{0, 1\} $\times$ \{0, 1\} $\cup$ \{0, 1\} $\times$ \{0, 1\} $\times$ \{0, 1\} \\
    \{()\} $\cup$ \{(0, 0), (1, 0), (0, 1), (1, 1)\} $\cup$ \{(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)\} \\
    \{(), (0, 0), (1, 0), (0, 1), (1, 1), (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)\}
    \item \textbf{B$^2 \cap$ B$^4$} \\
    \{x\} $\times$ \{x\} $\cap$ \{x\} $\times$ \{x\} $\times$ \{x\} $\times$ \{x\} \\
    \{(x, x)\} $\cap$ \{(x, x, x ,x)\} \\
    \{$\O$\}
    \item \textbf{$|$C$^5|$} \\
    $2^5$\\
    $32$
\end{enumerate}

\section{Extra Credit - Evaluate Equivalence}
\begin{enumerate}
    \item \textbf{If (A $\cup$ C) = (B $\cup$ C), then A = B.}\\
    This statement is false. If A is \{1, 2, 3\} and C is \{3, 4, 5\}, then B could either be \{1, 2\} or \{1, 2, 3\}. Since duplicates don't matter in sets, both values of B would be equivalent, meaning that A doesn't always equal B.
    \item \textbf{If (A $\cap$ C) = (B $\cap$ C), then A = B.}\\
    This statement is false. If A is \{1, 2, 3\} and C is \{3, 4, 5\}, then B could be \{2, 3\}, \{3\}, or \{1, 2, 3\}. As long as set B in the example has 3, and not 4 or 5, the statement would ring true. This means that A wouldn't always equal B.
\end{enumerate}

\end{document}


\documentclass{article}

\usepackage{booktabs}
\usepackage{multirow}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{overpic}
\usepackage{amssymb}
\usepackage{url}

\usepackage[accepted]{dlai2021}

\dlaititlerunning{Stock Prediction using Neural Networks}

\begin{document}

\twocolumn[

\dlaititle{Stock Prediction using Deep Learning}

\begin{center}\today\end{center}

\begin{dlaiauthorlist}
\dlaiauthor{Nefeli Tavoulari}{}
\end{dlaiauthorlist}
\dlaicorrespondingauthor{}{tavoulari.1977701@studenti.uniroma1.it}
\vskip 0.3in
]

\printAffiliationsAndNotice{}

\section{Introduction}

\paragraph*{Topic.}
Forecasting stock prices can yield high profit to investors. There are many techniques to accomplish that, including Fundamental Analysis, Technical Analysis and Machine Learning. This paper analyzes the procedure of predicting TESLA stock prices, experimenting with different neural networks. These types of neural networks are not necessarily suitable for our goal, but they were chosen simply so that I can familiarize with all these different concepts and organize them in my brain.
\paragraph*{Challenges.}
Predicting stock prices is a challenging task, due to the many factors that cause them to go up or down (e.g. national economic and social situation). Moreover, time-series forecasting is challenging because of the data not being stationary.

\section{Methodology}
In this section I would like to say a few words about each type of neural network used in this experiment, but also about some relative concepts.
\paragraph*{Artificial Neural Networks.}
ANNs are composed of multiple nodes, which imitate biological neurons of human brain. The neurons are connected by links and they interact with each other. The nodes can take input data and perform simple operations on the data. The result of these operations is passed to other neurons. The output at each node is called its activation or node value.Each link is associated with weight. ANNs are capable of learning, which takes place by altering weight values.

\paragraph*{Multi-Layer Perceptron.}An MLP is a class of feedforward artificial neural network (ANN).It consists of at least three layers of nodes: an input layer, a hidden layer and an output layer. Except for the input nodes, each node is a neuron that uses a nonlinear activation function. MLP utilizes a supervised learning technique called backpropagation for training.Its multiple layers and non-linear activation distinguish MLP from a linear perceptron.

\paragraph*{Convolutional Neural Network.}
CNN are distinguished from other neural networks by their superior performance with image, speech, or audio signal inputs. They have three main types of layers, which are:

Convolutional layer \\
Pooling layer \\
Fully-connected (FC) layer \\ \\
The convolutional layer is the first layer of a convolutional network. While convolutional layers can be followed by additional convolutional layers or pooling layers, the fully-connected layer is the final layer. With each layer, the CNN increases in its complexity, identifying greater portions of the image. Earlier layers focus on simple features, such as colors and edges. As the image data progresses through the layers of the CNN, it starts to recognize larger elements or shapes of the object until it finally identifies the intended object

Key properties of CNNs :

Trasnslation Equivariance - Compositionality - Locality - Self-Similarity

\paragraph*{Recurrent Neural Network.}
An RNN is a class of artificial neural networks where connections between nodes form a directed graph along a temporal sequence. This allows it to exhibit temporal dynamic behavior. Derived from feedforward neural networks, RNNs can use their internal state (memory) to process variable length sequences of inputs. This makes them applicable to tasks such as unsegmented, connected handwriting recognition or speech recognition.

\paragraph*{Long Short-Term Memory.}
LSTM is an artificial recurrent neural network (RNN) architecture used in the field of deep learning. Unlike standard feedforward neural networks, LSTM has feedback connections.A common LSTM unit is composed of a cell, an input gate, an output gate and a forget gate. The cell remembers values over arbitrary time intervals and the three gates regulate the flow of information into and out of the cell.

LSTM networks are well-suited to classifying, processing and making predictions based on time series data, since there can be lags of unknown duration between important events in a time series. LSTMs were developed to deal with the vanishing gradient problem that can be encountered when training traditional RNNs. Relative insensitivity to gap length is an advantage of LSTM over RNNs, hidden Markov models and other sequence learning methods in numerous applications.

\paragraph*{Gated Recurrent Unit.}
GRUs are a gating mechanism in recurrent neural networksThe GRU is like a long short-term memory (LSTM) with a forget gate, but has fewer parameters than LSTM, as it lacks an output gate.GRU's performance on certain tasks of polyphonic music modeling, speech signal modeling and natural language processing was found to be similar to that of LSTM.GRUs have been shown to exhibit better performance on certain smaller and less frequent datasets.

\paragraph*{Rectifier Linear Unit.}
In the context of artificial neural networks, the rectifier or ReLU activation function is an activation function defined as the positive part of its argument:

{\displaystyle f(x)=x^{+}=\max(0,x)}

\paragraph*{Backpropagation.}
Calculating gradients.

\paragraph*{Optimization.}
Optimizers are algorithms or methods used to change the attributes of the neural network such as weights and learning rate to reduce the losses. Examples of optimizers :

GD
- SGD
- MB-SGD
- SGD with momentum
- AdaGrad
- AdaDelta
- Adam

All in all, Adam is considered the best algorithm

\paragraph*{Regularization.}
Regularization refers to a set of different techniques that lower the complexity of a neural network model during training, and thus prevent the overfitting. Examples of regularization :

- L1 regularization forces the weight parameters to become zero

- L2 regularization forces the weight parameters towards zero (but never exactly zero)

- During dropout, some neurons get deactivated with a random probability P → Neural network becomes less complex → less overfitting

\paragraph*{Early Stopping.}
Stop training as soon as performance on validation set decreases. This is where the network starts to overfit the training set.

\section{Tools}
PyTorch
- Pandas
- NumPy
- Plotly
- DVC

\section{Results}\label{sec:latex}

\begin{table}[h!]
\caption{Performance comparison.}
\label{tab:results}
\begin{center}
\begin{small}
\begin{tabular}{p{0.16\linewidth} | ccccc}

& \multirow{1}{0.1\linewidth}{MLP}& \multirow{1}{0.1\linewidth}{CNN}& \multirow{1}{0.1\linewidth}{LSTM}& \multirow{1}{0.1\linewidth}{GRU}\\
\toprule
Train RMSE & 6.938163  & 5.579548 &  6.192757 &  2.195456\\
\midrule
Test RMSE      & 51.058610 & 42.077173 & 59.642715 & 13.554291\\
\midrule
Train Time & 1.605949 &  1.977534 & 63.438091 &  47.674628 \\
\bottomrule
\end{tabular}
\end{small}
\end{center}
\vspace{-0.5cm}
\end{table}

\section{References}

\textit{\url{https://www.tutorialspoint.com/artificial_intelligence/artificial_intelligence_neural_networks.html}}

\textit{\url{https://en.wikipedia.org/wiki/Recurrent_neural_network}}

\textit{\url{https://en.wikipedia.org/wiki/Long_short-term_memory}}

\textit{\url{https://en.wikipedia.org/wiki/Gated_recurrent_unit}}

\textit{\url{https://www.ibm.com/cloud/learn/convolutional-neural-networks}}

\textit{\url{https://en.wikipedia.org/wiki/Rectifier_(neural_networks)}}

\textit{\url{https://medium.com/swlh/stock-price-prediction-with-pytorch-37f52ae84632}}

\textit{\url{https://colah.github.io/posts/2015-08-Understanding-LSTMs/}}

\textit{\url{https://www.kaggle.com/faressayah/stock-market-analysis-prediction-using-lstm}}

\textit{\url{https://towardsdatascience.com/7-tips-to-choose-the-best-optimizer-47bb9c1219e}}

\textit{\url{https://towardsdatascience.com/overview-of-various-optimizers-in-neural-networks-17c1be2df6d5}}

\textit{\url{https://towardsdatascience.com/regularization-in-deep-learning-l1-l2-and-dropout-377e75acc036}}
\end{document}