{"id":13801698,"url":"https://github.com/botkop/numsca","last_synced_at":"2025-05-05T04:35:13.558Z","repository":{"id":50439939,"uuid":"113301428","full_name":"botkop/numsca","owner":"botkop","description":"numsca is numpy for scala","archived":false,"fork":false,"pushed_at":"2024-07-14T14:20:53.000Z","size":753,"stargazers_count":185,"open_issues_count":4,"forks_count":18,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-11-16T01:41:58.483Z","etag":null,"topics":["deep-learning","nd4j","numpy","scala"],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/botkop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-06T10:18:37.000Z","updated_at":"2024-10-30T19:21:44.000Z","dependencies_parsed_at":"2024-11-16T01:41:10.509Z","dependency_job_id":"98973b1d-5077-4bd9-8c96-e3bec9c01dd8","html_url":"https://github.com/botkop/numsca","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botkop%2Fnumsca","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botkop%2Fnumsca/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botkop%2Fnumsca/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/botkop%2Fnumsca/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/botkop","download_url":"https://codeload.github.com/botkop/numsca/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252441803,"owners_count":21748446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","nd4j","numpy","scala"],"created_at":"2024-08-04T00:01:26.038Z","updated_at":"2025-05-05T04:35:13.538Z","avatar_url":"https://github.com/botkop.png","language":"Jupyter Notebook","readme":"\"What I cannot create, I do not understand.\" - Richard Feynman.\n\nNumsca: Numpy for Scala\n=========================\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/be.botkop/numsca_2.13/badge.svg)](https://maven-badges.herokuapp.com/maven-central/be.botkop/numsca_2.13)\n[![Build Status](https://travis-ci.org/botkop/numsca.svg?branch=master)](https://travis-ci.org/botkop/numsca)\n\nNumsca is Numpy for Scala.\n\nI invite you to have a look at [this notebook](https://nbviewer.jupyter.org/github/botkop/numsca/blob/master/notebooks/dl-from-scratch.ipynb), \nwhich explains in simple terms how you can implement a neural net framework with Numsca.\n\n(If nbviewer barfs, then you can try [this notebook](notebooks/dl-from-scratch.ipynb))\n\nHere's the famous [neural network in 11 lines of Python](http://iamtrask.github.io/2015/07/12/basic-python-network/), translated to Numsca:\n\n```scala\nimport botkop.{numsca =\u003e ns}\nval x = ns.array(0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1).reshape(4, 3)\nval y = ns.array(0, 1, 1, 0).T\nval w0 = 2 * ns.rand(3, 4) - 1\nval w1 = 2 * ns.rand(4, 1) - 1\nfor (j \u003c- 0 until 60000) {\n  val l1 = 1 / (1 + ns.exp(-ns.dot(x, w0)))\n  val l2 = 1 / (1 + ns.exp(-ns.dot(l1, w1)))\n  val l2Delta = (y - l2) * (l2 * (1 - l2))\n  val l1Delta = l2Delta.dot(w1.T) * (l1 * (1 - l1))\n  w1 += l1.T.dot(l2Delta)\n  w0 += x.T.dot(l1Delta)\n}\n``` \n\nAnother example: a Scala translation of Andrej Karpathy's \n['Minimal character-level language model with a Vanilla Recurrent Neural Network'](src/main/scala/botkop/numsca/samples/MinCharRnn.scala).\n(Compare with Andrej Karpathy's original [post](https://gist.github.com/karpathy/d4dee566867f8291f086).)\n\nAlso have a look at [Scorch](https://github.com/botkop/scorch), a neural net framework in the spirit of [PyTorch](http://pytorch.org/), which uses Numsca.\n\n\n## Why?\nI love Scala. I teach myself deep learning. Everything in deep learning is written in Python. \nThis library helps me to quickly translate Python and Numpy code to my favorite language. \n\nI hope you find it useful. \n\nPull requests welcome.\n\n## Disclaimer\nThis is far from an exhaustive copy of Numpy's functionality. I'm adding functionality as I go. \nThat being said, I think many of the most interesting aspects of Numpy like slicing, broadcasting and indexing \nhave been successfully implemented.\n\n## Under the hood\nNumsca piggybacks on [Nd4j](https://nd4j.org/). Thanks, people!\n\n## Dependency\nAdd this to build.sbt:\n\nFor Scala 2.13:\n```scala\nlibraryDependencies += \"be.botkop\" %% \"numsca\" % \"0.1.7\"\n```\n\nFor Scala 2.11 and 2.12:\n```scala\nlibraryDependencies += \"be.botkop\" %% \"numsca\" % \"0.1.5\"\n```\n\n\n## Importing Numsca\n```scala\nimport botkop.{numsca =\u003e ns}\nimport ns.Tensor\n```\n\n## Creating a Tensor\n\n```scala\nscala\u003e Tensor(3, 2, 1, 0)\n[3.00,  2.00,  1.00,  0.00]\n\nscala\u003e ns.zeros(3, 3)\n[[0.00,  0.00,  0.00],\n [0.00,  0.00,  0.00],\n [0.00,  0.00,  0.00]]\n\nscala\u003e ns.ones(3, 2)\n[[1.00,  1.00],\n [1.00,  1.00],\n [1.00,  1.00]]\n \nscala\u003e val ta: Tensor = ns.arange(10)\n[0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e val tb: Tensor = ns.reshape(ns.arange(9), 3, 3)\n[[0.00,  1.00,  2.00],\n [3.00,  4.00,  5.00],\n [6.00,  7.00,  8.00]]\n \n scala\u003e val tc: Tensor = ns.reshape(ns.arange(2 * 3 * 4), 2, 3, 4)\n [[[0.00,  1.00,  2.00,  3.00],\n   [4.00,  5.00,  6.00,  7.00],\n   [8.00,  9.00,  10.00,  11.00]],\n \n  [[12.00,  13.00,  14.00,  15.00],\n   [16.00,  17.00,  18.00,  19.00],\n   [20.00,  21.00,  22.00,  23.00]]]\n```\n\n## Access\nSingle element\n```scala\nscala\u003e ta(0)\nres10: botkop.numsca.Tensor = 0.00\n\nscala\u003e tc(0, 1, 2)\nres14: botkop.numsca.Tensor = 6.00\n```\nGet the value of a single element Tensor:\n```scala\nscala\u003e ta(0).squeeze()\nres11: Double = 0.0\n```\nSlice\n```scala\nscala\u003e tc(0)\nres7: botkop.numsca.Tensor =\n[[0.00,  1.00,  2.00,  3.00],\n [4.00,  5.00,  6.00,  7.00],\n [8.00,  9.00,  10.00,  11.00]]\n \nscala\u003e tc(0, 1)\nres8: botkop.numsca.Tensor = [4.00,  5.00,  6.00,  7.00]\n```\n\n## Update\nIn place\n```scala\nscala\u003e val t = ta.copy()\nt: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e t(3) := -5\nscala\u003e t\nres16: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  -5.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e t(0) += 7\nscala\u003e t\nres18: botkop.numsca.Tensor = [7.00,  1.00,  2.00,  -5.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n```\n\nArray wise\n```scala\nscala\u003e val a2 = 2 * ta\nval a2 = 2 * ta\na2: botkop.numsca.Tensor = [0.00,  2.00,  4.00,  6.00,  8.00,  10.00,  12.00,  14.00,  16.00,  18.00]\n```\n\n## Slicing\nNote: \n- negative indexing is supported\n- Python notation ```t[:3]``` must be written as ```t(0 :\u003e 3)``` or ```t(:\u003e(3))``` \n\nNot supported (yet):\n- step size\n- ellipsis\n\n### Single dimension\n#### Slice over a single dimension\n\n```scala\nscala\u003e val a0 = ta.copy().reshape(10, 1)\na0: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e val a1 = a0(1 :\u003e)\na1: botkop.numsca.Tensor = [1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e val a2 = a0(0 :\u003e -1)\na2: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00]\n\nscala\u003e val a3 = a1 - a2\na3: botkop.numsca.Tensor = [1.00,  1.00,  1.00,  1.00,  1.00,  1.00,  1.00,  1.00,  1.00]\n\nscala\u003e ta(:\u003e, 5 :\u003e)\nres19: botkop.numsca.Tensor = [5.00,  6.00,  7.00,  8.00,  9.00]\n\nscala\u003e ta(:\u003e, -3 :\u003e)\nres4: botkop.numsca.Tensor = [7.00,  8.00,  9.00]\n```\n\n#### Update single dimension slice\n\n```scala\nscala\u003e val t = ta.copy()\nt: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n```\nAssign another tensor\n```scala\nscala\u003e t(2 :\u003e 5) := -ns.ones(3)\nscala\u003e t\nres6: botkop.numsca.Tensor = [0.00,  1.00,  -1.00,  -1.00,  -1.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n```\nAssign a value\n```scala\nscala\u003e t(2 :\u003e 5) := 33\nscala\u003e t\nres8: botkop.numsca.Tensor = [0.00,  1.00,  33.00,  33.00,  33.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n```\nUpdate in place\n```scala\nscala\u003e t(2 :\u003e 5) -= 1\nscala\u003e t\nres10: botkop.numsca.Tensor = [0.00,  1.00,  32.00,  32.00,  32.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n\n```\n\n### Multidimensional slices\n```scala\nscala\u003e tb\nres11: botkop.numsca.Tensor =\n[[0.00,  1.00,  2.00],\n [3.00,  4.00,  5.00],\n [6.00,  7.00,  8.00]]\n \nscala\u003e tb(2:\u003e, :\u003e)\nres15: botkop.numsca.Tensor = [6.00,  7.00,  8.00]\n```\nMixed range/integer indexing. Note that integers are implicitly translated to ranges, \nand this differs from Python. \n```scala\nscala\u003e tb(1, 0 :\u003e -1)\nres1: botkop.numsca.Tensor = [3.00,  4.00]\n```\n\n## Fancy indexing\n### Boolean indexing\n```scala\nscala\u003e val c = ta \u003c 5 \u0026\u0026 ta \u003e 1\nc: botkop.numsca.Tensor = [0.00,  0.00,  1.00,  1.00,  1.00,  0.00,  0.00,  0.00,  0.00,  0.00]\n```\nThis returns a TensorSelection:\n```scala\nscala\u003e val d = ta(c)\nd: botkop.numsca.TensorSelection = TensorSelection([0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00,  7.00,  8.00,  9.00],[[I@153ea1aa,None)\n```\nWhich is implicitly converted to a Tensor when needed:\n```scala\nscala\u003e val d: Tensor = ta(c)\nd: botkop.numsca.Tensor = [2.00,  3.00,  4.00]\n```\nOr you can force it to become a Tensor:\n```scala\nscala\u003e ta(c).asTensor\nres10: botkop.numsca.Tensor = [2.00,  3.00,  4.00]\n```\nUpdating:\n```scala\nscala\u003e val t = ta.copy()\nscala\u003e t(ta \u003c 5 \u0026\u0026 ta \u003e 1) := -7\nres6: botkop.numsca.Tensor = [0.00,  1.00,  -7.00,  -7.00,  -7.00,  5.00,  6.00,  7.00,  8.00,  9.00]\n```\nSelection over multiple dimensions:\n```scala\nscala\u003e val c: Tensor = tc(tc % 5 == 0)\nc: botkop.numsca.Tensor = [0.00,  5.00,  10.00,  15.00,  20.00]\n```\nUpdating over multiple dimensions:\n```scala\nscala\u003e val t1 = tc.copy()\nt1: botkop.numsca.Tensor =\n[[[0.00,  1.00,  2.00,  3.00],\n  [4.00,  5.00,  6.00,  7.00],\n  [8.00,  9.00,  10.00,  11.00]],\n\n [[12.00,  13.00,  14.00,  15.00],\n  [16.00,  17.00,  18.00,  19.00],\n  [20.00,  21.00,  22.00,  23.00]]]\n  \nscala\u003e t1(t1 \u003e 5 \u0026\u0026 t1 \u003c 15) *= 2\nres21: botkop.numsca.Tensor =\n[[[0.00,  1.00,  2.00,  3.00],\n  [4.00,  5.00,  12.00,  14.00],\n  [16.00,  18.00,  20.00,  22.00]],\n\n [[24.00,  26.00,  28.00,  15.00],\n  [16.00,  17.00,  18.00,  19.00],\n  [20.00,  21.00,  22.00,  23.00]]]\n```\n### List of location indexing\n```scala\nscala\u003e val primes = Tensor(2, 3, 5, 7, 11, 13, 17, 19, 23)\n\nscala\u003e val idx = Tensor(3, 4, 1, 2, 2)\n\nscala\u003e primes(idx).asTensor\nres23: botkop.numsca.Tensor = [7.00,  11.00,  3.00,  5.00,  5.00]\n\n```\nReshape according to index:\n```scala\nscala\u003e tb\nres25: botkop.numsca.Tensor =\n[[0.00,  1.00,  2.00],\n [3.00,  4.00,  5.00],\n [6.00,  7.00,  8.00]]\n\nscala\u003e primes(tb).asTensor\nres24: botkop.numsca.Tensor =\n[[2.00,  3.00,  5.00],\n [7.00,  11.00,  13.00],\n [17.00,  19.00,  23.00]]\n```\nUse as a look-up table:\n```scala\nscala\u003e val numSamples = 4\n       val numClasses = 3\n       val x = ns.arange(numSamples * numClasses).reshape(numSamples, numClasses)\n       val y = Tensor(0, 1, 2, 1)\n       val z: Tensor = x(ns.arange(numSamples), y)\nres26: botkop.numsca.Tensor = [0.00,  4.00,  8.00,  10.00]\n```\nUpdate along a single dimension:\n```scala\nscala\u003e val primes = Tensor(2, 3, 5, 7, 11, 13, 17, 19, 23)\nprimes: botkop.numsca.Tensor = [2.00,  3.00,  5.00,  7.00,  11.00,  13.00,  17.00,  19.00,  23.00]\n\nscala\u003e val idx = Tensor(3, 4, 1, 2, 2)\nidx: botkop.numsca.Tensor = [3.00,  4.00,  1.00,  2.00,  2.00]\n\nscala\u003e primes(idx) := 0\n\nscala\u003e primes\nres1: botkop.numsca.Tensor = [2.00,  0.00,  0.00,  0.00,  0.00,  13.00,  17.00,  19.00,  23.00]\n```\nMultiple dimensions\n```scala\n\nscala\u003e val a = ns.arange(6).reshape(3, 2) + 1\na: botkop.numsca.Tensor =\n[[1.00,  2.00],\n [3.00,  4.00],\n [5.00,  6.00]]\n\nscala\u003e val s1 = Tensor(0, 1, 2)\ns1: botkop.numsca.Tensor = [0.00,  1.00,  2.00]\n\nscala\u003e val s2 = Tensor(0, 1, 0)\ns2: botkop.numsca.Tensor = [0.00,  1.00,  0.00]\n\nscala\u003e val r1: Tensor = a(s1, s2)\nr1: botkop.numsca.Tensor = [1.00,  4.00,  5.00]\n```\nAn index will be broadcast if needed:\n```scala\nscala\u003e val y = ns.arange(35).reshape(5, 7)\ny: botkop.numsca.Tensor =\n[[0.00,  1.00,  2.00,  3.00,  4.00,  5.00,  6.00],\n [7.00,  8.00,  9.00,  10.00,  11.00,  12.00,  13.00],\n [14.00,  15.00,  16.00,  17.00,  18.00,  19.00,  20.00],\n [21.00,  22.00,  23.00,  24.00,  25.00,  26.00,  27.00],\n [28.00,  29.00,  30.00,  31.00,  32.00,  33.00,  34.00]]\n\nscala\u003e val r5: Tensor = y(Tensor(0, 2, 4), Tensor(1))\nr5: botkop.numsca.Tensor = [1.00,  15.00,  29.00]\n```\n\nUpdate along multiple dimensions:\n```scala\nscala\u003e val a = ns.arange(6).reshape(3, 2) + 1\na: botkop.numsca.Tensor =\n[[1.00,  2.00],\n [3.00,  4.00],\n [5.00,  6.00]]\n\nscala\u003e val s1 = Tensor(1, 1, 2)\ns1: botkop.numsca.Tensor = [1.00,  1.00,  2.00]\n\nscala\u003e val s2 = Tensor(0, 1, 0)\ns2: botkop.numsca.Tensor = [0.00,  1.00,  0.00]\n\nscala\u003e a(s1, s2) := 0\nres1: botkop.numsca.Tensor =\n[[1.00,  2.00],\n [0.00,  0.00],\n [0.00,  6.00]]\n```\n## Broadcasting\n\n```scala\nscala\u003e val x = ns.arange(4)\nx: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00]\n\nscala\u003e val xx = x.reshape(4, 1)\nxx: botkop.numsca.Tensor = [0.00,  1.00,  2.00,  3.00]\n\nscala\u003e val y = ns.ones(5)\ny: botkop.numsca.Tensor = [1.00,  1.00,  1.00,  1.00,  1.00]\n\nscala\u003e val z = ns.ones(3, 4)\n    val z = ns.ones(3, 4)\n[[1.00,  1.00,  1.00,  1.00],\n [1.00,  1.00,  1.00,  1.00],\n [1.00,  1.00,  1.00,  1.00]]\n\nscala\u003e (xx + y)\n[[1.00,  1.00,  1.00,  1.00,  1.00],\n [2.00,  2.00,  2.00,  2.00,  2.00],\n [3.00,  3.00,  3.00,  3.00,  3.00],\n [4.00,  4.00,  4.00,  4.00,  4.00]]\n\nscala\u003e x + z\n[[1.00,  2.00,  3.00,  4.00],\n [1.00,  2.00,  3.00,  4.00],\n [1.00,  2.00,  3.00,  4.00]]\n```\nOuter sum:\n```scala\nscala\u003e val a = Tensor(0.0, 10.0, 20.0, 30.0).reshape(4, 1)\na: botkop.numsca.Tensor = [0.00,  10.00,  20.00,  30.00]\n\nscala\u003e val b = Tensor(1.0, 2.0, 3.0)\nb: botkop.numsca.Tensor = [1.00,  2.00,  3.00]\n\nscala\u003e a + b\nres6: botkop.numsca.Tensor =\n[[1.00,  2.00,  3.00],\n [11.00,  12.00,  13.00],\n [21.00,  22.00,  23.00],\n [31.00,  32.00,  33.00]]\n\n```\n\nVector Quantization from [EricsBroadcastingDoc](http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc):\n```scala\nscala\u003e val observation = Tensor(111.0, 188.0)\n\nscala\u003e val codes = Tensor( 102.0, 203.0, 132.0, 193.0, 45.0, 155.0, 57.0, 173.0).reshape(4, 2)\ncodes: botkop.numsca.Tensor =\n[[102.00,  203.00],\n [132.00,  193.00],\n [45.00,  155.00],\n [57.00,  173.00]]\n\nscala\u003e val diff = codes - observation\ndiff: botkop.numsca.Tensor =\n[[-9.00,  15.00],\n [21.00,  5.00],\n [-66.00,  -33.00],\n [-54.00,  -15.00]]\n\nscala\u003e val dist = ns.sqrt(ns.sum(ns.square(diff), axis = -1))\ndist: botkop.numsca.Tensor = [17.49,  21.59,  73.79,  56.04]\n\nscala\u003e     val nearest = ns.argmin(dist).squeeze()\nnearest: Double = 0.0\n\n```\n","funding_links":[],"categories":["Table of Contents","Science and Data Analysis"],"sub_categories":["Science and Data Analysis"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotkop%2Fnumsca","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbotkop%2Fnumsca","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotkop%2Fnumsca/lists"}