{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2846e3a6-064a-46b1-84cb-24f0985f3f5a",
   "metadata": {},
   "source": [
    "# What is vectorization?\n",
    "\n",
    "Do operations without explicitly iterating over each element in the structure (vector), one by one, but manipulate it using vector operations.\n",
    "\n",
    "> ChatGPT: Vectorized operations are faster because they use optimized libraries, avoid unnecessary looping, take advantage of parallel processing, and have efficient memory access."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fe33c7c8-09db-4a7b-be6d-fbba882f2259",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import time;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1979bf0-7886-4a3a-8dcc-3414dcbbe66a",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## One dimensional array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6dca6430-6012-40cf-8d89-0deed090f232",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array = np.array([1,2,3,4])\n",
    "array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "d6b70b20-1f52-446e-9137-0faa8af564ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vectorized version: 0.5021095275878906ms\n"
     ]
    }
   ],
   "source": [
    "a = np.random.rand(1000000)\n",
    "b = np.random.rand(1000000)\n",
    "\n",
    "tic = time.time()\n",
    "c_vec = np.dot(a,b)\n",
    "toc = time.time()\n",
    "\n",
    "print(\"Vectorized version: \" + str(1000*(toc-tic)) + \"ms\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "c98c9278-4d88-4881-8139-90aeb7bceda1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Non vectorized version: 312.34097480773926ms\n"
     ]
    }
   ],
   "source": [
    "# c_non_vec = 0\n",
    "tic_non_vectorized = time.time()\n",
    "\n",
    "# for i in range(1000000):\n",
    "#     c_non_vec += a[i]*b[i]\n",
    "\n",
    "c_non_vec = sum([a[i]*b[i] for i in range(1000000)])\n",
    "\n",
    "toc_non_vectorized = time.time()\n",
    "\n",
    "print(\"Non vectorized version: \" + str(1000*(toc_non_vectorized-tic_non_vectorized)) + \"ms\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "3f4b9084-eb2f-4a51-9158-d834cf8f2469",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vectorized result: 249655.99738514755\n",
      "Non vectorized result: 249655.9973851444\n"
     ]
    }
   ],
   "source": [
    "print(f\"Vectorized result: {c_vec}\")\n",
    "print(f\"Non vectorized result: {c_non_vec}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3ba2077-47e6-43d8-8e16-98e6719a4dc5",
   "metadata": {},
   "source": [
    "## Exponential operations\n",
    "If you need to apply a exponential operation into each element of a matrix/vector\n",
    "\n",
    "$v = [v_1, v_2, ..., v_n]$, $u = [e^{v_1}, e^{v_2}, ..., e^{v_n}]$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "869298bb-404d-43b6-a792-2f229a6510db",
   "metadata": {},
   "source": [
    "Code example **non vectorized**:\n",
    "\n",
    "```python\n",
    "u = np.zeros((n,1))\n",
    "for i in range(n):\n",
    "    u[i] = math.exp(v[i])\n",
    "```\n",
    "\n",
    "Code example **vectorized**:\n",
    "\n",
    "```python\n",
    "u = np.exp(v)\n",
    "```\n",
    "\n",
    "Other vectorized expressions\n",
    "\n",
    "```python\n",
    "np.log(v)\n",
    "np.abs(v)\n",
    "np.maximum(v, 0)\n",
    "```\n"
   ]
  }
 ],
 "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.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}