{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Kotlin-numpy library demo\n",
    "\n",
    "Follow the project repository: https://github.com/Kotlin/kotlin-numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%use numpy(0.1.4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "val a = array(arrayOf(1L, 2L, 3L))\n",
    "val b = array<Double>(listOf(listOf(1.5f, 2f, 3f), listOf(4f, 5f, 6f)))\n",
    "val c = array<Double>(\n",
    "    listOf(\n",
    "        listOf(listOf(1.5f, 2f, 3f), listOf(4f, 5f, 6f)),\n",
    "        listOf(listOf(3f, 2f, 1f), listOf(4f, 5f, 6f))\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initial Placeholders"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1.4012985e-45 0.0000000e+00]\n",
       " [2.0743408e+01 4.5909340e-41]\n",
       " [2.0743408e+01 4.5909340e-41]]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeros<Int>(3, 4) // Create an array of zeros\n",
    "ones<Short>(2, 3, 4) // Create an array of ones\n",
    "val d = arange<Long>(10, 25, 5) // Create an array of evenly spaced values (step value)\n",
    "\n",
    "linspace<Float>(0, 2, 9) // Create an array of evenly spaced values (number of samples)\n",
    "\n",
    "val e = full(intArrayOf(2, 2), 7L) // Create a constant array\n",
    "val f = eye<Double>(2) // Create a 2x2 identity matrix\n",
    "Random.random(2, 2) // Create an array with random values\n",
    "empty<Float>(3, 2) // Create an empty array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## I/0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "// a.toFile(\"my_array\")\n",
    "// fromfile<Long>(\"my_array\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Inspecting Your Array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1 2 3]\n",
       " [4 5 6]]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.shape // Array domensions\n",
    "b.ndim // Number of array dimensions\n",
    "e.size // Number of array elements\n",
    "b.dtype // Dara type of array elements\n",
    "b.dtype.name // Name of data type\n",
    "b.asType<Double, Int>() // Convert an array to a different type"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Array Mathematics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Arithmetic Operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Subtraction:\n",
      "[[-0.5  0.   0. ]\n",
      " [-3.  -3.  -3. ]]\n",
      "Addition:\n",
      "[[2.5 4.  6. ]\n",
      " [5.  7.  9. ]]\n",
      "Division:\n",
      "[[0.66666667 1.         1.        ]\n",
      " [0.25       0.4        0.5       ]]\n",
      "Multiplication:\n",
      "[[ 1.5  4.   9. ]\n",
      " [ 4.  10.  18. ]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[[7. 7.]\n",
       " [7. 7.]]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val g = a - b\n",
    "println(\"Subtraction:\")\n",
    "println(a - b) // Subraction\n",
    "\n",
    "println(\"Addition:\")\n",
    "println(b + a) // Addition\n",
    "\n",
    "println(\"Division:\")\n",
    "println(a / b) // Division\n",
    "\n",
    "println(\"Multiplication:\")\n",
    "println(a * b) // Multiplication\n",
    "\n",
    "exp(b) // Exponentiation\n",
    "sqrt(b) // Square root\n",
    "sin(a) // Sin\n",
    "cos(b) // Cos\n",
    "log(a) // natural logarithm\n",
    "e.dot(f) // Dot product"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comparison"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Element-wise comparison\n",
      "[[[ True  True  True]\n",
      "  [ True  True  True]]\n",
      "\n",
      " [[False  True False]\n",
      "  [ True  True  True]]]\n",
      "Element-wise comparison\n",
      "[ True False False]\n",
      "Array comparison\n",
      "false\n"
     ]
    }
   ],
   "source": [
    "println(\"Element-wise comparison\")\n",
    "println(c eq b)\n",
    "\n",
    "println(\"Element-wise comparison\")\n",
    "println(a lt 2)\n",
    "\n",
    "println(\"Array comparison\")\n",
    "println(a == b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aggregate Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.08248290463863"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.sum() // Array sum\n",
    "a.min() // Array minimum value\n",
    "b.max(0) // Maximum value of an array row\n",
    "b.cumSum(1) // Cumulative sum of the lements\n",
    "a.mean() // Mean\n",
    "median(b) // Median\n",
    "corrcoef<Long, Long>(a) // Correlation coefficient\n",
    "std(d) // Standard deviation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Copying arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "var h = a.view<Long, Long>()\n",
    "copy(a)\n",
    "h = copy(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sorting Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.sort()\n",
    "c.sort(axis = 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Subsetting, Slicing, Indexing, Iterating"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Subsetting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\r\n",
      "6.0\r\n"
     ]
    }
   ],
   "source": [
    "println(a[2]) // Select the element at the 2nd index\n",
    "println(b[1, 2]) // Select the element at row 1 column 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Slicing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2]\r\n",
      "[2. 5.]\r\n",
      "[[1.5 2.  3. ]]\r\n",
      "[[3. 2. 3.]\n",
      " [4. 5. 6.]]\r\n",
      "[3 2 1]\r\n"
     ]
    }
   ],
   "source": [
    "println(a[0..2]) // Select items at index 0 and 1\n",
    "println(b[0..2, 1]) // Select items at rows 0 and 1 in column 1\n",
    "\n",
    "println(b[None..1]) // Select all items at row 0\n",
    "\n",
    "println(c[1, None..None, None..None]) // Same as [1, ...] or [1, :, :] in Python\n",
    "println(a[None..None..-1]) // Reversed array a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Boolean Indexing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[a lt 2] // Select elements from a less than 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fancy indexing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4.  2.  6.  1.5]\r\n",
      "[[4.  5.  6.  4. ]\n",
      " [1.5 2.  3.  1.5]\n",
      " [4.  5.  6.  4. ]\n",
      " [1.5 2.  3.  1.5]]\r\n"
     ]
    }
   ],
   "source": [
    "println(b[arrayOf(1, 0, 1, 0), arrayOf(0, 1, 2, 0)]) // Select elements (1,0), (0,1), (1,2) and (0, 0)\n",
    "\n",
    "println(b[arrayOf(1, 0, 1, 0)][None..None, arrayOf(0, 1, 2, 0)]) // Select a subset of the matrix's rows and columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Iterating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 \r\n",
      "[1.5 2.  3. ]\r\n",
      "[4. 5. 6.]\r\n"
     ]
    }
   ],
   "source": [
    "// Flat array iteration\n",
    "for (element in a.flatIter()) {\n",
    "    print(\"$element \")\n",
    "}\n",
    "println()\n",
    "\n",
    "// Iteration along the axes of the array\n",
    "for (ax in b) {\n",
    "    println(ax)\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Array Manipulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Transposing Array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1.5 2.  3. ]\n",
       " [4.  5.  6. ]]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val i = transpose(b) // Permute array dimensions\n",
    "i.t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Changing Array Shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[-0.5  0. ]\n",
       " [ 0.  -3. ]\n",
       " [-3.  -3. ]]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.ravel() // Flatten the array\n",
    "g.reshape(3, -2) // Reshape, but don't chenge data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding/Removing Elements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1 3]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h.resize(2, 6) // Change to new array with shape (2,6)\n",
    "append(h.view(), g) // Append items to an array\n",
    "insert(a, 1, array(arrayOf(5L))) // Insert items in an array\n",
    "delete(a, 1) // Delete items from an array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Combining Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3 10 15 20]\n",
      "[[1.  2.  3. ]\n",
      " [1.5 2.  3. ]\n",
      " [4.  5.  6. ]]\n",
      "[[7. 7. 1. 0.]\n",
      " [7. 7. 0. 1.]]\n",
      "[[ 1 10]\n",
      " [ 2 15]\n",
      " [ 3 20]]\n"
     ]
    }
   ],
   "source": [
    "println(concatenate(a, d, axis = 0)) // Concatenate arrays\n",
    "\n",
    "println(vstack(a.view(), b)) // Stack arrays vertically\n",
    "\n",
    "println(hstack(e.view(), f)) // Stack arrays horizontally\n",
    "\n",
    "println(columnStack(a, d)) // Create stacked column-wise arrays"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Splitting Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1], [2], [3]]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hsplit(a, 3) // Split the array horizontally at the 3rd index"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "codemirror_mode": "text/x-kotlin",
   "file_extension": ".kt",
   "mimetype": "text/x-kotlin",
   "name": "kotlin",
   "pygments_lexer": "kotlin",
   "version": "1.4.20-dev-1121"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}