362 lines
7.7 KiB
Plaintext
Executable File
362 lines
7.7 KiB
Plaintext
Executable File
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Explicit for-loop vs. built-ins"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def index_sum_for(arr, idx):\n",
|
|
" sum_ = 0\n",
|
|
" for a, i in zip(arr, idx):\n",
|
|
" if i:\n",
|
|
" sum_ += a\n",
|
|
" return sum_\n",
|
|
"\n",
|
|
"\n",
|
|
"def index_sum_np(arr, idx):\n",
|
|
" return arr[idx].sum()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"num_points = int(5e5)\n",
|
|
"array = np.random.randn((num_points))\n",
|
|
"indices = np.random.choice([False, True], size=num_points)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"44.7 ms ± 192 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit sum_for = index_sum_for(array, indices)\n",
|
|
"sum_for = index_sum_for(array, indices)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2.17 ms ± 2.25 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit sum_np = index_sum_np(array, indices)\n",
|
|
"sum_np = index_sum_np(array, indices)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert np.allclose(sum_for, sum_np)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Pure allocation vs. allocation + initialization"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"num_points = int(1e4)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"6.5 µs ± 33.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit out = np.empty((num_points, num_points))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"72.1 ms ± 626 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit out = np.full((num_points, num_points), 1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Explicit for-loop vs. \"batched\" operations"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"rng = np.random.default_rng()\n",
|
|
"A = rng.standard_normal((3, 4))\n",
|
|
"batched_x = rng.standard_normal((1_000_000, 4))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def apply_matrix_for(A, xs):\n",
|
|
" b = np.empty((xs.shape[0], A.shape[0]))\n",
|
|
" for i, x in enumerate(xs):\n",
|
|
" b[i] = A @ x\n",
|
|
" return b"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def apply_matrix_batched(A, xs):\n",
|
|
" return xs @ A.T"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1.37 s ± 20.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit b_for = apply_matrix_for(A, batched_x)\n",
|
|
"b_for = apply_matrix_for(A, batched_x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2.15 ms ± 270 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit b_batched = apply_matrix_batched(A, batched_x)\n",
|
|
"b_batched = apply_matrix_batched(A, batched_x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"assert np.allclose(b_for, b_batched)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Hints for Assignment 0"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([[ 6., 2., 3., 4.],\n",
|
|
" [ 5., 11., 7., 8.],\n",
|
|
" [ 9., 10., 16., 12.],\n",
|
|
" [13., 14., 15., 21.]])"
|
|
]
|
|
},
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"np.set_printoptions(precision=1)\n",
|
|
"X = np.arange(1, 17, dtype=float).reshape(4, 4) + np.eye(4) * 5\n",
|
|
"kernel = np.array([\n",
|
|
" [1, 2, 1],\n",
|
|
" [2, 4, 2],\n",
|
|
" [1, 2, 1],\n",
|
|
"]) / 16\n",
|
|
"X"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 49,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def variance_naive(X):\n",
|
|
" M, N = X.shape\n",
|
|
" var_im = np.zeros_like(X)\n",
|
|
" for i in range(1, M - 1):\n",
|
|
" for j in range(1, N - 1):\n",
|
|
" x = X[i - 1:i + 2, j - 1:j + 2]\n",
|
|
" mu_x = (x * kernel).sum()\n",
|
|
" var_im[i, j] = (kernel * (x - mu_x) ** 2).sum()\n",
|
|
"\n",
|
|
" return var_im"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 50,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([[0. , 0. , 0. , 0. ],\n",
|
|
" [0. , 8.7, 9.4, 0. ],\n",
|
|
" [0. , 7.9, 8.7, 0. ],\n",
|
|
" [0. , 0. , 0. , 0. ]])"
|
|
]
|
|
},
|
|
"execution_count": 50,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"naive = variance_naive(X)\n",
|
|
"naive"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 54,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import scipy.signal as ss\n",
|
|
"def variance(X):\n",
|
|
" # in your code this corresponds to gaussian_filter calls\n",
|
|
" mu_x = ss.convolve2d(X, kernel, mode='valid')\n",
|
|
" mu_xx = ss.convolve2d(X * X, kernel, mode='valid')\n",
|
|
" return np.pad(mu_xx - mu_x ** 2, 1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 55,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"smart = variance(X)\n",
|
|
"assert np.allclose(smart, naive)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.8"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|