Commit 7dc3780b authored by Swicech's avatar Swicech
Browse files

upload assignment 10

parent 9b3bd08f
%% Cell type:markdown id: tags:
# Adaptive Simpson's Rule
**Learning goals**
- Recursion
- Adaptive Simpson's rule
Simpson's method is an algorithm for computing approximate integrals of functions, defined as
$$ \int_{a}^{b} f(x) dx \approx S(a,b) = \frac{h}{3}(f(a) + 4f(c) + f(b)), $$
where
$$ h = \frac{b-a}{2}, \qquad c = \frac{a+b}{2}. $$
Note: It is worth specifying that this is not the composite Simpson's rule.
%% Cell type:markdown id: tags:
### a)
Make a function `simpsons_method(f, a, b)` that takes as input a function `f`, a starting point `a`, and a stopping point `b` and returns the Simpson's method approximation to the integral of $f$ from $a$ to $b$.
***Example run***
```python
import math
def f(x):
return math.log(x)
print(simpsons_method(f,1,2))
#output:
0.3858346021654338
```
**Write your code in the block below**
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
## b)
To compute the integral more accurately we can either use the composite Simpson's rule, or the more economical adaptive Simpson's rule which is able to compute integrals with a guaranteed error of less than or equal to epsilon. This algorithm is formulated recursively through the following steps:
1. Given f and an interval `[a,b]`, compute the regular Simpson's approximation `whole = simpsons_method(f,a,b)` on the whole interval
2. Find the midpoint `c = (a+b)/2` and compute the Simpson's approximations on the left and right halves of the interval: `left = simpsons_method(f,a,c)`, `right = simpsons_method(f,c,b)`.
3. If `|left + right - whole| > 15*epsilon`, use recursive Simpson's method on the intervals `[a,c]` and `[c,b]` with halved tolerance `epsilon/2`, then return the two approximation added together.
* Otherwise, the approximation is accurate enough, so return the improved value `(16*(left + right) - whole)/15`
Make a function `recursive_simpson(f,a,b,tol)` that uses the adaptive Simpson's rule *recursively* to compute the integral of $f$ from $a$ to $b$. The inputs `f`, `a` and `b` are as defined in *a)* and `tol` is the error tolerance. The function should return an estimate of the integral.
**example run**
```python
import math
def f(x):
return math.log(x)
print(recursive(f, 1 , 2, 0.00001))
#output:
0.386294208843096
```
The exact value is 0.3862943611198906.
**Write your code in the block below**
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
# Book analysis with plotting
%% Cell type:markdown id: tags:
In this task are you going to analyze the book *Alice in Wonderland* and see how many times different words appear in each chapter. You are going to plot this into a graph by using `matplotlib`.
The file you are supposed to use is [alice_in_wonderland.txt](alice_in_wonderland.txt).
%% Cell type:markdown id: tags:
## a) Partition into chapters
%% Cell type:markdown id: tags:
In this first task are you going to create the function `get_chapters(filename, chapter_delimiter)` that takes in a filename, `filename`, and a delimiter, `chapter_delimiter`, and returns a list of strings where each string is the tekst of a chapter. The chapter delimiter is a string that appears before each chapter and *not anywhere else in the book*.
The preface should not be included, so the first string in the list you are going to return should be the text to chapter 1.
***Write your code in the codeblock below:***
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
In [alice_in_wonderland.txt](alice_in_wonderland.txt) is the string `'CHAPTER'` (in big letters) between each chapter, therefore can we use `'CHAPTER'` as our `chapter_delimiter` for this book.
If you have done everything correct should output, from the code below, be `12` since Alice in Wonderland consists of 12 chapters. *remember to run your function first!*
%% Cell type:code id: tags:
``` python
chapters = get_chapters("alice_in_wonderland.txt", "CHAPTER")
print(len(chapters))
```
%% Cell type:markdown id: tags:
#### Hint
%% Cell type:markdown id: tags:
- The built-in function `split` is smart to use.
- If your output is `13`, could it be that you have included the preface (the text before chapter 1).
%% Cell type:markdown id: tags:
## b) Counting words
%% Cell type:markdown id: tags:
Create the function `count_words(string_list, word)` that takes in a list of strings, `string_list` and a `word` and returns a new list with the number of times `word` is in each string in `string_list`. Look at the example further down if this was unclear.
The function should be case-insensitive (HelLo and hello is interpreted as the same word).
***Write your code in the codeblock below:***
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
*Example of usage:*
Yu can test if your function works as it should by running the code below (but remember to run the codeblock with your function first!):
%% Cell type:code id: tags:
``` python
string_list = ["Orange, yellow, blue, red", "Yellow lemons are very good if they are extra yellow."]
count_words(string_list, "Yellow")
```
%% Cell type:markdown id: tags:
If you have done everything correct should the function print the list `[1,2]`, because `"Orange, yellow, blue, red"` contains one `"Yellow"`, while `"Yellow lemons are very good if they are extra yellow."` contains two `"Yellow"`.
%% Cell type:markdown id: tags:
#### Hint
%% Cell type:markdown id: tags:
You can use the built-in function `string.count(word)` that count each tine a word is in a string. This should do the task significantly easier. Test it with the code below:
%% Cell type:code id: tags:
``` python
weird_sentence = "If i had one yesterday would i probably had had one today as well"
print(rar_setning.count("had"))
```
%% Cell type:markdown id: tags:
**Obs:** The function `count` is case-sensitive (Orange and orange is not considered the same word), so you have to fix this yourself in your code.
%% Cell type:markdown id: tags:
## c) Numbered list
%% Cell type:markdown id: tags:
In the next task are you going to create the function `create_numbers_to(number)` that takes in a number, `number`, and returns a list containing `number` amount of elements on the form `[1,2,3,4..., number-1, number]`. the biggest (and last) number in the list should be `number`.
For example `create_numbers_to(7)` should return the list `[1, 2, 3, 4, 5, 6, 7]`.
***Write your code in the codeblock below and test that it works:***
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
## d) Analyze book
%% Cell type:markdown id: tags:
Now are you going to create the function `analyze_book(filename, chapter_delimiter, word)` that uses your previously defined functions (from the tasks before). `analyze_book` takes in the word, `word` and plots a graph where the x-axis is the chapternumber and the y-axis is the amount of times `word` appears in this chapter. `filename` and `chapter_delimiter` is the same as in task a) (and is almost only needed to be sent into this function, hint hint...). The graph should look like this:
- The title of the graph should be: Amount of times "<word\>" appears in each chapter in "<filename\>"
- The title of the x-axis should be: Chapter
- The title of the y-axis should be: Number of "<word\>"
- The x-axis should go from 1 to the number of chapters in the book.
- The y-axis should go from 0 to the maximum amount of times `word` appear in a chapter +3 (so the graph doesn't crash in the roof).
<word\> should be replaced with the word sent in to the function, and <filename\> should be replaced with the filename sent into the function.
***Write your code in the marked place in the codeblock below:***
%% Cell type:code id: tags: