if unique: # remove duplicates, otherwise the `remove` method below might not be enough
if unique: # remove duplicates,
# otherwise the `remove` method below might not be enough
remove_duplicates(flat_values_B)
equal_values = []
...
...
@@ -417,7 +420,7 @@ img = [
[ 0, 0, 0, 0, 100, 100, 0, 0, 0, 0],
]
print(img)
print(pretty_print_as_rows(img))
from matplotlib import pyplot as plt
...
...
@@ -432,7 +435,7 @@ plt.show()
#### Linear search
Requires iterating over the array, asymptotic runtime is $O(n)$.
Requires iterating over the array, until the item with the correct value is found.
```{python}
import numpy as np
...
...
@@ -452,7 +455,7 @@ print("Linear search run time:")
##### Computational complexity side-quest
Even though the 'asymptotic' time of linear search is $O(n)$, the 'actual' time depends on the 'properties' of the array - where the item is located in the array.
The asymptotic time of the linear search is $O(n)$, the 'actual' time depends on the 'properties' of the array - where the item is located in the array.
```{python}
N = 100
...
...
@@ -472,7 +475,7 @@ print("Searching for an item at the end of the array:")
#### Binary search
Requires pre-sorted array but asymptotic runtime is $O(\log n)$ - we only look which "half" of the array might contain the item.
Requires pre-sorted array but asymptotic runtime is $O(\log n)$ - we only look which "half" of the array might contain the item, then discard the other half.
# otherwise, we look at the left half of the array
return binary_search_recursion(a[:mid_idx], x)
# recursion is slower in this case, as we are copying the whole array, instead of just using the index.
# recursion is slower in this case, as we are copying the whole array,
# instead of just using the index.
sa = np.sort(a)
print("Binary search run time:")
%timeit binary_search_loop(sa, 5)
...
...
@@ -518,22 +522,25 @@ print("'Fair' binary search run time (includes sorting):")
The advantage of binary search is relatively constant search time. As you can see from the following, the search time is shorter than "average" search time for linear search: $O(\log n) < O(n)$. This includes even sorting the array.
```{python}
print("Searching for an item in the middle of the array, using binary search:")
print("Searching for an item in the middle of the array, "
Even more restrictive requirements than binary search - the array needs to be 'uniformly' (equal distribution of values) sorted. It uses similar approach as binary search but uses "an educated guess" of where the item might be (this is where the uniformity comes into play). The is $O(\log n)$
Even more restrictive requirements than binary search - the array needs to be 'uniformly' (equal distribution of values) sorted. It uses similar approach as binary search but uses "an educated guess" of where the item might be (this is where the uniformity comes into play). The asymptotic run time is $O(\log(log n))$.
```{python}
def interpolation_search(a, x):
...
...
@@ -615,7 +622,8 @@ N = 100
a = np.random.choice(N**3, size=N, replace=True)
searched_item = a[N // 2]
occurrences = find_all(a, searched_item)
print("The value", searched_item, "occurs", len(occurrences), "times in the array at indices", occurrences)
Let's break it down: We want to compute the sum of the gray area - area of interest (AOI) in @fig-integral_image_full. To do that, we need to take the "total sum" (delimited by red rectangle in @fig-integral_image_full) of the area from $[0, 0]$ to $[c, d]$. That is, the sum from the origin of the image to the bottom_right corner of the AOI. This sum has the value at $ii[c][d]$. Then, we subtract the two areas from origin to the top-right corner of the AOI (delimited by blue rectangle in @fig-integral_image_full) and the area from the origin to the bottom-left corner of the AOI (delimited by green rectangle in @fig-integral_image_full). The sums of these areas are located at $ii[a-1][d]$ and $ii[c][b-1]$. This way, we subtracted twice the sum of the area from the origin to just above the top-left corner of the AOI. We need to add it once back-in. Therefore, the last step is to add the sum of this area (delimited by orange rectangle in @fig-integral_image_full) that is located at $ii[a-1][b-1]$. To recap, the full equation is: