diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd new file mode 100644 index 0000000000..812d3a5197 --- /dev/null +++ b/nx/exercises/exercises-1-20.livemd @@ -0,0 +1,508 @@ +# Exercises: 1-20 + +```elixir +Mix.install([{:nx, "~> 0.6"}]) +``` + +## Introduction + +Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook). + +## 1-10 + +**1. Install `Nx` in a Livebook. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Mix.install([{:nx, "~> 0.6"}]) + ``` + +
+
+ + + +**2. Create a 1-D tensor of 10 zeros. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.broadcast(0, {10}) + ``` + +
+
+ + + +**3. Find the number of elements in `tensor`. (★☆☆)** + +```elixir +tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.size(tensor) + ``` + +
+
+ + + +**4. Find the number of bytes of memory in `tensor`. (★☆☆)** + +```elixir +tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.byte_size(tensor) + ``` + +
+
+ + + +**5a. Use `Nx.sum/2` to find the sum of all elements of `tensor`. (★☆☆)** + +```elixir +tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.sum(tensor) + ``` + +
+
+ + + +**5b. Read the [documentation for `Nx.sum/2`](https://hexdocs.pm/nx/Nx.html#sum/2) then provide the correct option to sum across the _rows_. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.sum(tensor, axes: [1]) + ``` + +
+ Tip: You can also hover over a function inside Livebook code cells to display its documentation. +
+ +
+
+ + + +**6. Create a tensor of zeros of size 10 but where the fifth value is 1. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + zeros = Nx.broadcast(0, {10}) + index = Nx.tensor([4]) + Nx.indexed_put(zeros, index, 1) + ``` + +
+
+ + + +**7. Create a 3x3 tensor with values ranging from 0 to 8. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.iota({3, 3}) + ``` + +
+
+ + + +**8. Create a tensor with values ranging from 10 to 49. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution 1 +
+ + ```elixir + Nx.iota({39}) + |> Nx.add(10) + ``` + +
+
+ + + +
+ Example solution 2 +
+ + ```elixir + Nx.linspace(10, 49, n: 39, type: :s64) + ``` + +
+
+ + + +**9. Reverse `tensor` (first element becomes last). (★☆☆)** + +```elixir +tensor = Nx.tensor([2, 4, 6, 8]) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.reverse(tensor) + ``` + +
+
+ + + +**10a. Given an initial `tensor`, build a "mask" of non-zero elements. That is, build a second tensor with the same shape as the original, but that has a 1 wherever the original has a non-zero element and a 0 elsewhere. (★☆☆)** + +```elixir +tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + mask = Nx.not_equal(tensor, 0) + ``` + +
+
+ + + +**10b. Use the mask from 10a to replace each 0 from `tensor` with -1. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.select(mask, tensor, -1) + ``` + +
+
+ +## 11-20 + +**11. Create a 3x3 identity tensor. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.eye(3) + ``` + +
+
+ + + +**12. Create a 3x3x3 tensor with random values. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + key = Nx.Random.key(0) + {random, _} = Nx.Random.normal(key, shape: {3, 3, 3}) + random + ``` + +
+
+ + + +**13. Create a random 10x10 tensor then find its minimum and maximum values. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + key = Nx.Random.key(0) + {tensor, _} = Nx.Random.normal(key, shape: {10, 10}) + + %{ + min: Nx.reduce_min(tensor), + max: Nx.reduce_max(tensor) + } + ``` + +
+
+ + + +**14. Create a random 1D tensor of size 30 then find its mean. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + key = Nx.Random.key(0) + {tensor, _} = Nx.Random.normal(key, shape: {30}) + + Nx.mean(tensor) + ``` + +
+
+ + + +**15. Create a 4x4 tensor with 1 on the border and 0 inside. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.broadcast(1, {4, 4}) + |> Nx.put_slice([1, 1], Nx.broadcast(0, {2, 2})) + ``` + +
+
+ + + +**16. Add a border of 0 around `tensor` (end result will be a 5x5 tensor). (★☆☆)** + +```elixir +tensor = Nx.broadcast(1, {3, 3}) +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.pad(tensor, 0, [{1, 1, 0}, {1, 1, 0}]) + ``` + +
+
+ + + +**17. Determine the results of the following expressions. (★☆☆)** + +```elixir +nan = Nx.Constants.nan() +Nx.multiply(0, nan) +Nx.equal(nan, nan) +Nx.greater(nan, nan) +Nx.subtract(nan, nan) + +# Add your solution here. +``` + +
+ Example solution +
+ + ``` + #Nx.Tensor< + f32 + NaN + > + #Nx.Tensor< + u8 + 0 + > + #Nx.Tensor< + u8 + 0 + > + #Nx.Tensor< + f32 + NaN + > + ``` + +
+
+ + + +**18. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal. (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.tensor([1, 2, 3, 4]) + |> Nx.make_diagonal(offset: -1) + ``` + +
+
+ + + +**19. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element using [`Nx.tile`](https://hexdocs.pm/nx/Nx.html#tile/2). (★☆☆)** + +```elixir +# Add your solution here. +``` + +
+ Example solution +
+ + ```elixir + Nx.tensor([[0, 1], [1, 0]]) + |> Nx.tile([4, 4]) + ``` + +
+
+ + + +**20. Produce the same checkerboard pattern from exercise 19, but _without_ using `Nx.tile`. (★☆☆)** + +```elixir +# Add your solution here. +# Hint: try using `Nx.iota` in combination with `Nx.remainder`. +``` + +
+ Example solution 1 +
+ + ```elixir + t = Nx.iota({8, 1}) + + Nx.transpose(t) + |> Nx.add(t) + |> Nx.remainder(2) + ``` + +
+
+ + + +
+ Example solution 2 +
+ + ```elixir + Nx.iota({9, 9}) + |> Nx.remainder(2) + |> Nx.slice([0, 0], [8, 8]) + ``` + +
+
diff --git a/nx/mix.exs b/nx/mix.exs index 672378f71c..dfdea2ee2e 100644 --- a/nx/mix.exs +++ b/nx/mix.exs @@ -60,6 +60,7 @@ defmodule Nx.MixProject do source_url_pattern: "#{@source_url}/blob/v#{@version}/nx/%{path}#L%{line}", before_closing_body_tag: &before_closing_body_tag/1, extras: [ + "exercises/exercises-1-20.livemd", "guides/intro-to-nx.livemd", "guides/vectorization.livemd", "CHANGELOG.md" @@ -112,6 +113,10 @@ defmodule Nx.MixProject do Nx.Defn.Token, Nx.Defn.Tree ] + ], + groups_for_extras: [ + Exercises: ~r"exercises/", + Guides: ~r"guides/" ] ] end