From eab62e64f51d94ad83848647f320845aec665c30 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Fri, 10 Nov 2023 16:58:19 -0500 Subject: [PATCH 01/26] add first pass at exercises --- nx/exercises/exercises-1-20.livemd | 196 +++++++++++++++++++++++++++++ nx/mix.exs | 5 + 2 files changed, 201 insertions(+) create mode 100644 nx/exercises/exercises-1-20.livemd diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd new file mode 100644 index 0000000000..4111fa6f24 --- /dev/null +++ b/nx/exercises/exercises-1-20.livemd @@ -0,0 +1,196 @@ +# Exercises: 1-20 + +```elixir +Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) +``` + +## 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 +Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) +``` + +2. Print the Nx version and the configuration (★☆☆) + +```elixir +version = Application.spec(:nx, :vsn) +# I'm not sure if there's an equivalent for "configuration" +``` + +3. Create a 1-D tensor of 10 zeros (★☆☆) + +```elixir +# I'm not sure what the best way to do this is. +# I think Nx could use a function like: `Nx.fill(value, shape)` + +# 1. +# 0 |> List.duplicate(10) |> Nx.tensor() + +# 2. +# [0] |> Nx.tensor() |> Nx.tile([10]) + +# 3. +# i = Nx.iota({10}) +# Nx.subtract(i, i) + +0 |> List.duplicate(10) |> Nx.tensor() +``` + +4. How to find the memory size of any tensor (★☆☆) + +```elixir +Nx.byte_size(Nx.tensor([[1, 2, 3], [4, 5, 6]])) +``` + +5. How to get the documentation of the `add/2` function from the command line? (★☆☆) + +```elixir +# I don't know if this is possible. +# iex> h Nx.add +``` + +6. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆) + +```elixir +zeros = 0 |> List.duplicate(10) |> Nx.tensor() +index = Nx.tensor([4]) +Nx.indexed_put(zeros, index, 1) +``` + +7. Create a tensor with values ranging from 10 to 49 (★☆☆) + +```elixir +# 1. +# Nx.iota({40}) |> Nx.add(10) + +# 2. +# Nx.linspace(10, 49, n: 39, type: :s8) + +Nx.linspace(10, 49, n: 39, type: :s8) +``` + +8. Reverse a tensor (first element becomes last) (★☆☆) + +```elixir +Nx.iota({10}) +|> Nx.reverse() +``` + +9. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆) + +```elixir +Nx.iota({3, 3}) +``` + +10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) + +```elixir +Nx.tensor([1, 2, 0, 0, 4, 0]) +|> Nx.not_equal(0) +``` + +## 11-20 + +11. Create a 3x3 identity tensor (★☆☆) + +```elixir +Nx.eye(3) +``` + +12. Create a 3x3x3 tensor with random values (★☆☆) + +```elixir +key = Nx.Random.key(0) +{random, _} = Nx.Random.normal(key, shape: {3, 3}) +random +``` + +13. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆) + +```elixir +# This felt a little awkward. Is there a better way? + +key = Nx.Random.key(0) +{r, _} = Nx.Random.normal(key, shape: {3, 3}) +r |> IO.inspect() +r_1d = Nx.reshape(r, {:auto}) + +%{ + min: Nx.to_number(r_1d[Nx.argmin(r)]), + max: Nx.to_number(r_1d[Nx.argmax(r)]) +} +``` + +14. Create a random 1D tensor of size 30 and find the mean value (★☆☆) + +```elixir +key = Nx.Random.key(0) +{r, _} = Nx.Random.normal(key, shape: {30}) +r |> Nx.mean() |> Nx.to_number() +``` + +15. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) + +```elixir +zeros_3x3 = Nx.make_diagonal(Nx.tensor([0, 0, 0])) +Nx.pad(zeros_3x3, 1, [{1, 1, 0}, {1, 1, 0}]) +``` + +16. How to add a border (filled with 0's) around an existing array? (★☆☆) + +```elixir +ones_3x3 = 1 |> List.duplicate(9) |> Nx.tensor() |> Nx.reshape({3, 3}) +Nx.pad(ones_3x3, 0, [{1, 1, 0}, {1, 1, 0}]) +``` + +17. What are the results of the following expressions? (★☆☆) + +```elixir +nan = Nx.Constants.nan() +IO.inspect(Nx.multiply(0, nan)) +IO.inspect(Nx.equal(nan, nan)) +IO.inspect(Nx.greater(nan, nan)) +IO.inspect(Nx.subtract(nan, nan)) +IO.inspect(Enum.member?(MapSet.new([nan]), nan)) +IO.inspect(0.3 == 3 * 0.1) +``` + +18. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆) + +```elixir +Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) +``` + +19. Create a 8x8 tensor of 0s and 1s in a checkerboard pattern with 0 as the first element (★☆☆) + +```elixir +Nx.tensor([0, 0, 0, 0]) +|> Nx.make_diagonal() +|> Nx.pad(1, [{0, 0, 1}, {0, 0, 1}]) +``` + +20. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor? + +```elixir +# The numpy solution is to use `unravel_index`. I didn't see an equivalent. +# https://numpy.org/doc/stable/reference/generated/numpy.unravel_index.html +dims = [6, 7, 8] +target = 100 + +# This is how I'd do it with Enum. +dims +|> Enum.map_reduce({target, Enum.product(dims)}, fn dim, {remaining, step_size} -> + step_size = div(step_size, dim) + num_steps = div(remaining, step_size) + {num_steps, {remaining - num_steps * step_size, step_size}} +end) +|> then(fn {indices, {0, 1}} -> indices end) +``` 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 From 948e0a7e66c6d76c6badebd022bc298b9354e304 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:38:12 -0500 Subject: [PATCH 02/26] stop fighting the auto-formatted numbers (for now) --- nx/exercises/exercises-1-20.livemd | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 4111fa6f24..eae2cccef8 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -18,14 +18,14 @@ https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) ``` -2. Print the Nx version and the configuration (★☆☆) +1. Print the Nx version and the configuration (★☆☆) ```elixir version = Application.spec(:nx, :vsn) # I'm not sure if there's an equivalent for "configuration" ``` -3. Create a 1-D tensor of 10 zeros (★☆☆) +1. Create a 1-D tensor of 10 zeros (★☆☆) ```elixir # I'm not sure what the best way to do this is. @@ -44,20 +44,20 @@ version = Application.spec(:nx, :vsn) 0 |> List.duplicate(10) |> Nx.tensor() ``` -4. How to find the memory size of any tensor (★☆☆) +1. How to find the memory size of any tensor (★☆☆) ```elixir Nx.byte_size(Nx.tensor([[1, 2, 3], [4, 5, 6]])) ``` -5. How to get the documentation of the `add/2` function from the command line? (★☆☆) +1. How to get the documentation of the `add/2` function from the command line? (★☆☆) ```elixir # I don't know if this is possible. # iex> h Nx.add ``` -6. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆) +1. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆) ```elixir zeros = 0 |> List.duplicate(10) |> Nx.tensor() @@ -65,7 +65,7 @@ index = Nx.tensor([4]) Nx.indexed_put(zeros, index, 1) ``` -7. Create a tensor with values ranging from 10 to 49 (★☆☆) +1. Create a tensor with values ranging from 10 to 49 (★☆☆) ```elixir # 1. @@ -77,20 +77,20 @@ Nx.indexed_put(zeros, index, 1) Nx.linspace(10, 49, n: 39, type: :s8) ``` -8. Reverse a tensor (first element becomes last) (★☆☆) +1. Reverse a tensor (first element becomes last) (★☆☆) ```elixir Nx.iota({10}) |> Nx.reverse() ``` -9. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆) +1. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆) ```elixir Nx.iota({3, 3}) ``` -10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) +1. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) ```elixir Nx.tensor([1, 2, 0, 0, 4, 0]) @@ -99,13 +99,13 @@ Nx.tensor([1, 2, 0, 0, 4, 0]) ## 11-20 -11. Create a 3x3 identity tensor (★☆☆) +1. Create a 3x3 identity tensor (★☆☆) ```elixir Nx.eye(3) ``` -12. Create a 3x3x3 tensor with random values (★☆☆) +1. Create a 3x3x3 tensor with random values (★☆☆) ```elixir key = Nx.Random.key(0) @@ -113,7 +113,7 @@ key = Nx.Random.key(0) random ``` -13. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆) +1. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆) ```elixir # This felt a little awkward. Is there a better way? @@ -129,7 +129,7 @@ r_1d = Nx.reshape(r, {:auto}) } ``` -14. Create a random 1D tensor of size 30 and find the mean value (★☆☆) +1. Create a random 1D tensor of size 30 and find the mean value (★☆☆) ```elixir key = Nx.Random.key(0) @@ -137,21 +137,21 @@ key = Nx.Random.key(0) r |> Nx.mean() |> Nx.to_number() ``` -15. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) +1. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) ```elixir zeros_3x3 = Nx.make_diagonal(Nx.tensor([0, 0, 0])) Nx.pad(zeros_3x3, 1, [{1, 1, 0}, {1, 1, 0}]) ``` -16. How to add a border (filled with 0's) around an existing array? (★☆☆) +1. How to add a border (filled with 0's) around an existing array? (★☆☆) ```elixir ones_3x3 = 1 |> List.duplicate(9) |> Nx.tensor() |> Nx.reshape({3, 3}) Nx.pad(ones_3x3, 0, [{1, 1, 0}, {1, 1, 0}]) ``` -17. What are the results of the following expressions? (★☆☆) +1. What are the results of the following expressions? (★☆☆) ```elixir nan = Nx.Constants.nan() @@ -163,13 +163,13 @@ IO.inspect(Enum.member?(MapSet.new([nan]), nan)) IO.inspect(0.3 == 3 * 0.1) ``` -18. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆) +1. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆) ```elixir Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) ``` -19. Create a 8x8 tensor of 0s and 1s in a checkerboard pattern with 0 as the first element (★☆☆) +1. Create a 8x8 tensor of 0s and 1s in a checkerboard pattern with 0 as the first element (★☆☆) ```elixir Nx.tensor([0, 0, 0, 0]) @@ -177,7 +177,7 @@ Nx.tensor([0, 0, 0, 0]) |> Nx.pad(1, [{0, 0, 1}, {0, 0, 1}]) ``` -20. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor? +1. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor? ```elixir # The numpy solution is to use `unravel_index`. I didn't see an equivalent. From dba7470db6146e28011ab26e9f423bc723f43b0a Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:54:23 -0500 Subject: [PATCH 03/26] TIL broadcast --- nx/exercises/exercises-1-20.livemd | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index eae2cccef8..3838c15e9c 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -28,20 +28,7 @@ version = Application.spec(:nx, :vsn) 1. Create a 1-D tensor of 10 zeros (★☆☆) ```elixir -# I'm not sure what the best way to do this is. -# I think Nx could use a function like: `Nx.fill(value, shape)` - -# 1. -# 0 |> List.duplicate(10) |> Nx.tensor() - -# 2. -# [0] |> Nx.tensor() |> Nx.tile([10]) - -# 3. -# i = Nx.iota({10}) -# Nx.subtract(i, i) - -0 |> List.duplicate(10) |> Nx.tensor() +Nx.broadcast(0, {10}) ``` 1. How to find the memory size of any tensor (★☆☆) @@ -60,7 +47,7 @@ Nx.byte_size(Nx.tensor([[1, 2, 3], [4, 5, 6]])) 1. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆) ```elixir -zeros = 0 |> List.duplicate(10) |> Nx.tensor() +zeros = Nx.broadcast(0, {10}) index = Nx.tensor([4]) Nx.indexed_put(zeros, index, 1) ``` @@ -140,15 +127,15 @@ r |> Nx.mean() |> Nx.to_number() 1. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) ```elixir -zeros_3x3 = Nx.make_diagonal(Nx.tensor([0, 0, 0])) -Nx.pad(zeros_3x3, 1, [{1, 1, 0}, {1, 1, 0}]) +Nx.broadcast(0, {3, 3}) +|> Nx.pad(1, [{1, 1, 0}, {1, 1, 0}]) ``` 1. How to add a border (filled with 0's) around an existing array? (★☆☆) ```elixir -ones_3x3 = 1 |> List.duplicate(9) |> Nx.tensor() |> Nx.reshape({3, 3}) -Nx.pad(ones_3x3, 0, [{1, 1, 0}, {1, 1, 0}]) +Nx.broadcast(1, {3, 3}) +|> Nx.pad(0, [{1, 1, 0}, {1, 1, 0}]) ``` 1. What are the results of the following expressions? (★☆☆) From bb6771e34bfe55e012867994dcfe34982b6bef80 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:55:50 -0500 Subject: [PATCH 04/26] drop to_number; use reduce_{min,max} --- nx/exercises/exercises-1-20.livemd | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 3838c15e9c..f9536b452e 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -108,11 +108,10 @@ random key = Nx.Random.key(0) {r, _} = Nx.Random.normal(key, shape: {3, 3}) r |> IO.inspect() -r_1d = Nx.reshape(r, {:auto}) %{ - min: Nx.to_number(r_1d[Nx.argmin(r)]), - max: Nx.to_number(r_1d[Nx.argmax(r)]) + min: Nx.reduce_min(r), + max: Nx.reduce_max(r) } ``` @@ -121,7 +120,7 @@ r_1d = Nx.reshape(r, {:auto}) ```elixir key = Nx.Random.key(0) {r, _} = Nx.Random.normal(key, shape: {30}) -r |> Nx.mean() |> Nx.to_number() +Nx.mean(r) ``` 1. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) From 55412e644da53b4ef451a19d6ff563158a95aa0c Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:56:09 -0500 Subject: [PATCH 05/26] drop comments --- nx/exercises/exercises-1-20.livemd | 7 ------- 1 file changed, 7 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index f9536b452e..ef3d03dfae 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -22,7 +22,6 @@ Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) ```elixir version = Application.spec(:nx, :vsn) -# I'm not sure if there's an equivalent for "configuration" ``` 1. Create a 1-D tensor of 10 zeros (★☆☆) @@ -55,12 +54,6 @@ Nx.indexed_put(zeros, index, 1) 1. Create a tensor with values ranging from 10 to 49 (★☆☆) ```elixir -# 1. -# Nx.iota({40}) |> Nx.add(10) - -# 2. -# Nx.linspace(10, 49, n: 39, type: :s8) - Nx.linspace(10, 49, n: 39, type: :s8) ``` From e93dbd99643fdac8d2d5a31bded8e9aa1950d248 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:56:41 -0500 Subject: [PATCH 06/26] drop unhelpful expressions --- nx/exercises/exercises-1-20.livemd | 2 -- 1 file changed, 2 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index ef3d03dfae..dcee64cf29 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -138,8 +138,6 @@ IO.inspect(Nx.multiply(0, nan)) IO.inspect(Nx.equal(nan, nan)) IO.inspect(Nx.greater(nan, nan)) IO.inspect(Nx.subtract(nan, nan)) -IO.inspect(Enum.member?(MapSet.new([nan]), nan)) -IO.inspect(0.3 == 3 * 0.1) ``` 1. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆) From 657a3d9bd66b93f6fbec678c3e0d4502716a2e3e Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:56:55 -0500 Subject: [PATCH 07/26] drop s --- nx/exercises/exercises-1-20.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index dcee64cf29..c298ddad48 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -146,7 +146,7 @@ IO.inspect(Nx.subtract(nan, nan)) Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) ``` -1. Create a 8x8 tensor of 0s and 1s in a checkerboard pattern with 0 as the first element (★☆☆) +1. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element (★☆☆) ```elixir Nx.tensor([0, 0, 0, 0]) From 23d5f77bc5c5282d856f593d500d0bda0051d70f Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 11:57:14 -0500 Subject: [PATCH 08/26] fix checkerboard --- nx/exercises/exercises-1-20.livemd | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index c298ddad48..597f65541f 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -149,9 +149,8 @@ Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) 1. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element (★☆☆) ```elixir -Nx.tensor([0, 0, 0, 0]) -|> Nx.make_diagonal() -|> Nx.pad(1, [{0, 0, 1}, {0, 0, 1}]) +Nx.tensor([[0, 1], [1, 0]]) +|> Nx.tile([4, 4]) ``` 1. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor? From fd521a86cbbfc9ac72759a7c6e97e5bac5713ea2 Mon Sep 17 00:00:00 2001 From: Billy Lanchantin Date: Sat, 11 Nov 2023 14:28:11 -0500 Subject: [PATCH 09/26] fix shape Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com> --- nx/exercises/exercises-1-20.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 597f65541f..1c35530b62 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -89,7 +89,7 @@ Nx.eye(3) ```elixir key = Nx.Random.key(0) -{random, _} = Nx.Random.normal(key, shape: {3, 3}) +{random, _} = Nx.Random.normal(key, shape: {3, 3, 3}) random ``` From ba519095f937ef083ba1a30d9437e2b94ae1c7c0 Mon Sep 17 00:00:00 2001 From: Billy Lanchantin Date: Sat, 11 Nov 2023 14:28:46 -0500 Subject: [PATCH 10/26] fix shape (again) Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com> --- nx/exercises/exercises-1-20.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 1c35530b62..f685bad455 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -99,7 +99,7 @@ random # This felt a little awkward. Is there a better way? key = Nx.Random.key(0) -{r, _} = Nx.Random.normal(key, shape: {3, 3}) +{r, _} = Nx.Random.normal(key, shape: {10, 10}) r |> IO.inspect() %{ From f9c005cd5be16578574a3df51d0e2a348f379beb Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 14:59:50 -0500 Subject: [PATCH 11/26] use latest version; drop print config exercise --- nx/exercises/exercises-1-20.livemd | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index f685bad455..4c027a74db 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -1,7 +1,7 @@ # Exercises: 1-20 ```elixir -Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) +Mix.install([{:nx, "~> 0.6"}]) ``` ## Introduction @@ -15,13 +15,7 @@ https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook 1. Install Nx in a Livebook (★☆☆) ```elixir -Mix.install([{:nx, github: "elixir-nx/nx", sparse: "nx"}]) -``` - -1. Print the Nx version and the configuration (★☆☆) - -```elixir -version = Application.spec(:nx, :vsn) +Mix.install([{:nx, "~> 0.6"}]) ``` 1. Create a 1-D tensor of 10 zeros (★☆☆) From fcbcf14c0f3cb4a25f655b0de9cfce1c6635decb Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 15:00:46 -0500 Subject: [PATCH 12/26] add `size` exercise to replace removed exercise --- nx/exercises/exercises-1-20.livemd | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 4c027a74db..cc0496cef0 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -24,10 +24,18 @@ Mix.install([{:nx, "~> 0.6"}]) Nx.broadcast(0, {10}) ``` +1. How to find the number of elements in a tensor (★☆☆) + +```elixir +Nx.tensor([[1, 2, 3], [4, 5, 6]]) +|> Nx.size() +``` + 1. How to find the memory size of any tensor (★☆☆) ```elixir -Nx.byte_size(Nx.tensor([[1, 2, 3], [4, 5, 6]])) +Nx.tensor([[1, 2, 3], [4, 5, 6]]) +|> Nx.byte_size() ``` 1. How to get the documentation of the `add/2` function from the command line? (★☆☆) From 4a1f211824a1b16f6aecd82fd81f444c2f0fe9d6 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 11 Nov 2023 15:03:03 -0500 Subject: [PATCH 13/26] use bolding to circumvent auto-formatter --- nx/exercises/exercises-1-20.livemd | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index cc0496cef0..f730c2ea39 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -12,40 +12,40 @@ https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook ## 1-10 -1. Install Nx in a Livebook (★☆☆) +**1. Install Nx in a Livebook (★☆☆)** ```elixir Mix.install([{:nx, "~> 0.6"}]) ``` -1. Create a 1-D tensor of 10 zeros (★☆☆) +**2. Create a 1-D tensor of 10 zeros (★☆☆)** ```elixir Nx.broadcast(0, {10}) ``` -1. How to find the number of elements in a tensor (★☆☆) +**3. How to find the number of elements in a tensor (★☆☆)** ```elixir Nx.tensor([[1, 2, 3], [4, 5, 6]]) |> Nx.size() ``` -1. How to find the memory size of any tensor (★☆☆) +**4. How to find the memory size of any tensor (★☆☆)** ```elixir Nx.tensor([[1, 2, 3], [4, 5, 6]]) |> Nx.byte_size() ``` -1. How to get the documentation of the `add/2` function from the command line? (★☆☆) +**5. How to get the documentation of the `add/2` function from the command line? (★☆☆)** ```elixir # I don't know if this is possible. # iex> h Nx.add ``` -1. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆) +**6. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆)** ```elixir zeros = Nx.broadcast(0, {10}) @@ -53,26 +53,26 @@ index = Nx.tensor([4]) Nx.indexed_put(zeros, index, 1) ``` -1. Create a tensor with values ranging from 10 to 49 (★☆☆) +**7. Create a tensor with values ranging from 10 to 49 (★☆☆)** ```elixir Nx.linspace(10, 49, n: 39, type: :s8) ``` -1. Reverse a tensor (first element becomes last) (★☆☆) +**8. Reverse a tensor (first element becomes last) (★☆☆)** ```elixir Nx.iota({10}) |> Nx.reverse() ``` -1. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆) +**9. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆)** ```elixir Nx.iota({3, 3}) ``` -1. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) +**10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆)** ```elixir Nx.tensor([1, 2, 0, 0, 4, 0]) @@ -81,13 +81,13 @@ Nx.tensor([1, 2, 0, 0, 4, 0]) ## 11-20 -1. Create a 3x3 identity tensor (★☆☆) +**11. Create a 3x3 identity tensor (★☆☆)** ```elixir Nx.eye(3) ``` -1. Create a 3x3x3 tensor with random values (★☆☆) +**12. Create a 3x3x3 tensor with random values (★☆☆)** ```elixir key = Nx.Random.key(0) @@ -95,7 +95,7 @@ key = Nx.Random.key(0) random ``` -1. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆) +**13. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆)** ```elixir # This felt a little awkward. Is there a better way? @@ -110,7 +110,7 @@ r |> IO.inspect() } ``` -1. Create a random 1D tensor of size 30 and find the mean value (★☆☆) +**14. Create a random 1D tensor of size 30 and find the mean value (★☆☆)** ```elixir key = Nx.Random.key(0) @@ -118,21 +118,21 @@ key = Nx.Random.key(0) Nx.mean(r) ``` -1. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆) +**15. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆)** ```elixir Nx.broadcast(0, {3, 3}) |> Nx.pad(1, [{1, 1, 0}, {1, 1, 0}]) ``` -1. How to add a border (filled with 0's) around an existing array? (★☆☆) +**16. How to add a border (filled with 0's) around an existing array? (★☆☆)** ```elixir Nx.broadcast(1, {3, 3}) |> Nx.pad(0, [{1, 1, 0}, {1, 1, 0}]) ``` -1. What are the results of the following expressions? (★☆☆) +**17. What are the results of the following expressions? (★☆☆)** ```elixir nan = Nx.Constants.nan() @@ -142,20 +142,20 @@ IO.inspect(Nx.greater(nan, nan)) IO.inspect(Nx.subtract(nan, nan)) ``` -1. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆) +**18. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆)** ```elixir Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) ``` -1. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element (★☆☆) +**19. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element (★☆☆)** ```elixir Nx.tensor([[0, 1], [1, 0]]) |> Nx.tile([4, 4]) ``` -1. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor? +**20. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor?** ```elixir # The numpy solution is to use `unravel_index`. I didn't see an equivalent. From 4be316ed841dec5479a7830fa57037ca9f6fe894 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sun, 12 Nov 2023 11:13:12 -0500 Subject: [PATCH 14/26] add actual solution --- nx/exercises/exercises-1-20.livemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index f730c2ea39..a89eb9e419 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -41,8 +41,8 @@ Nx.tensor([[1, 2, 3], [4, 5, 6]]) **5. How to get the documentation of the `add/2` function from the command line? (★☆☆)** ```elixir -# I don't know if this is possible. -# iex> h Nx.add +import IEx.Helpers +h(Nx.add()) ``` **6. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆)** From 1475f4910701a8f2ed00dd5f07e67f9417909772 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sun, 12 Nov 2023 11:13:25 -0500 Subject: [PATCH 15/26] remove errant comment --- nx/exercises/exercises-1-20.livemd | 2 -- 1 file changed, 2 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index a89eb9e419..3b9610a858 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -98,8 +98,6 @@ random **13. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆)** ```elixir -# This felt a little awkward. Is there a better way? - key = Nx.Random.key(0) {r, _} = Nx.Random.normal(key, shape: {10, 10}) r |> IO.inspect() From cf7a9946665c34914131aad458278b30459fddef Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sun, 12 Nov 2023 11:13:54 -0500 Subject: [PATCH 16/26] tweak exercise 10 to request a mask; add part b --- nx/exercises/exercises-1-20.livemd | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 3b9610a858..0c2b0b24ff 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -72,11 +72,18 @@ Nx.iota({10}) Nx.iota({3, 3}) ``` -**10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆)** +**10a. Given an initial `tensor_10`, 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 -Nx.tensor([1, 2, 0, 0, 4, 0]) -|> Nx.not_equal(0) +tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) + +mask = Nx.not_equal(tensor_10, 0) +``` + +**10b. Use the mask from 10a to replace each 0 from `tensor_10` with -1. (★☆☆)** + +```elixir +Nx.select(mask, tensor_10, -1) ``` ## 11-20 From 8ac5b5da09ad0dc331a9c804aad9de3226a971dd Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sun, 12 Nov 2023 12:30:59 -0500 Subject: [PATCH 17/26] wrap solutions in details tags; mild wording tweaks --- nx/exercises/exercises-1-20.livemd | 463 ++++++++++++++++++++++++----- 1 file changed, 387 insertions(+), 76 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 0c2b0b24ff..0449aa0ccb 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -12,168 +12,479 @@ https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook ## 1-10 -**1. Install Nx in a Livebook (★☆☆)** +**1. Install `Nx` in a Livebook. (★☆☆)** ```elixir -Mix.install([{:nx, "~> 0.6"}]) +# Add your solution here. +:ok ``` -**2. Create a 1-D tensor of 10 zeros (★☆☆)** +
+ Example solution +
+ + ```elixir + Mix.install([{:nx, "~> 0.6"}]) + ``` + +
+
+ + + +**2. Create a 1-D tensor of 10 zeros. (★☆☆)** ```elixir -Nx.broadcast(0, {10}) +# Add your solution here. +:ok ``` -**3. How to find the number of elements in a tensor (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.broadcast(0, {10}) + ``` + +
+
+ + + +**3. Find the number of elements in `tensor_03`. (★☆☆)** ```elixir -Nx.tensor([[1, 2, 3], [4, 5, 6]]) -|> Nx.size() +tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +# Add your solution here. +:ok ``` -**4. How to find the memory size of any tensor (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.size(tensor_03) + ``` + +
+
+ + + +**4. Find the number of bytes of memory in `tensor_04`. (★☆☆)** ```elixir -Nx.tensor([[1, 2, 3], [4, 5, 6]]) -|> Nx.byte_size() +tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +# Add your solution here. +:ok ``` -**5. How to get the documentation of the `add/2` function from the command line? (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.byte_size(tensor_04) + ``` + +
+
+ + + +**5. Use `IEx.Helpers` to print the documentation of the `Nx.add/2` function. (★☆☆)** ```elixir -import IEx.Helpers -h(Nx.add()) +# Add your solution here. +:ok ``` -**6. Create a tensor of zeros of size 10 but the fifth value which is 1 (★☆☆)** +
+ Example solution +
+ + ```elixir + import IEx.Helpers + h Nx.add + ``` + +
+
+ + + +**6. Create a tensor of zeros of size 10 but where the fifth value is 1. (★☆☆)** ```elixir -zeros = Nx.broadcast(0, {10}) -index = Nx.tensor([4]) -Nx.indexed_put(zeros, index, 1) +# Add your solution here. +:ok ``` -**7. Create a tensor with values ranging from 10 to 49 (★☆☆)** +
+ Example solution +
+ + ```elixir + zeros = Nx.broadcast(0, {10}) + index = Nx.tensor([4]) + Nx.indexed_put(zeros, index, 1) + ``` + +
+
+ + + +**7. Create a tensor with values ranging from 10 to 49. (★☆☆)** ```elixir -Nx.linspace(10, 49, n: 39, type: :s8) +# Add your solution here. +:ok ``` -**8. Reverse a tensor (first element becomes last) (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.linspace(10, 49, n: 39, type: :s8) + ``` + +
+
+ + + +**8. Reverse `tensor_08` (first element becomes last). (★☆☆)** ```elixir -Nx.iota({10}) -|> Nx.reverse() +tensor_08 = Nx.tensor([2, 4, 6, 8]) +# Add your solution here. +:ok ``` -**9. Create a 3x3 tensor with values ranging from 0 to 8 (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.reverse(tensor_08) + ``` + +
+
+ + + +**9. Create a 3x3 tensor with values ranging from 0 to 8. (★☆☆)** ```elixir -Nx.iota({3, 3}) +# Add your solution here. +:ok ``` +
+ Example solution +
+ + ```elixir + Nx.iota({3, 3}) + ``` + +
+
+ + + **10a. Given an initial `tensor_10`, 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_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) - -mask = Nx.not_equal(tensor_10, 0) +# Add your solution here. +:ok ``` +
+ Example solution +
+ + ```elixir + mask = Nx.not_equal(tensor_10, 0) + ``` + +
+
+ + + **10b. Use the mask from 10a to replace each 0 from `tensor_10` with -1. (★☆☆)** ```elixir -Nx.select(mask, tensor_10, -1) +# Add your solution here. +:ok ``` +
+ Example solution +
+ + ```elixir + Nx.select(mask, tensor_10, -1) + ``` + +
+
+ ## 11-20 -**11. Create a 3x3 identity tensor (★☆☆)** +**11. Create a 3x3 identity tensor. (★☆☆)** ```elixir -Nx.eye(3) +# Add your solution here. +:ok ``` -**12. Create a 3x3x3 tensor with random values (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.eye(3) + ``` + +
+
+ + + +**12. Create a 3x3x3 tensor with random values. (★☆☆)** ```elixir -key = Nx.Random.key(0) -{random, _} = Nx.Random.normal(key, shape: {3, 3, 3}) -random +# Add your solution here. +:ok ``` -**13. Create a 10x10 tensor with random values and find the minimum and maximum values (★☆☆)** +
+ Example solution +
-```elixir -key = Nx.Random.key(0) -{r, _} = Nx.Random.normal(key, shape: {10, 10}) -r |> IO.inspect() + ```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. (★☆☆)** -%{ - min: Nx.reduce_min(r), - max: Nx.reduce_max(r) -} +```elixir +# Add your solution here. +:ok ``` -**14. Create a random 1D tensor of size 30 and find the mean value (★☆☆)** +
+ Example solution +
+ + ```elixir + key = Nx.Random.key(0) + {tensor_13, _} = Nx.Random.normal(key, shape: {10, 10}) + + %{ + min: Nx.reduce_min(tensor_13), + max: Nx.reduce_max(tensor_13) + } + ``` + +
+
+ + + +**14. Create a 1D tensor of size 30 then find its mean. (★☆☆)** ```elixir -key = Nx.Random.key(0) -{r, _} = Nx.Random.normal(key, shape: {30}) -Nx.mean(r) +# Add your solution here. +:ok ``` -**15. Create a 5x5 tensor with 1 on the border and 0 inside (★☆☆)** +
+ Example solution +
+ + ```elixir + key = Nx.Random.key(0) + {tensor_14, _} = Nx.Random.normal(key, shape: {30}) + + Nx.mean(tensor_14) + ``` + +
+
+ + + +**15. Create a 4x4 tensor with 1 on the border and 0 inside. (★☆☆)** ```elixir -Nx.broadcast(0, {3, 3}) -|> Nx.pad(1, [{1, 1, 0}, {1, 1, 0}]) +# Add your solution here. +:ok ``` -**16. How to add a border (filled with 0's) around an existing array? (★☆☆)** +
+ 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_16` (end result will be a 5x5 tensor). (★☆☆)** ```elixir -Nx.broadcast(1, {3, 3}) -|> Nx.pad(0, [{1, 1, 0}, {1, 1, 0}]) +tensor_16 = Nx.broadcast(1, {3, 3}) +# Add your solution here. +:ok ``` -**17. What are the results of the following expressions? (★☆☆)** +
+ Example solution +
+ + ```elixir + Nx.pad(tensor_16, 0, [{1, 1, 0}, {1, 1, 0}]) + ``` + +
+
+ + + +**17. Determine the results of the following expressions. (★☆☆)** ```elixir nan = Nx.Constants.nan() -IO.inspect(Nx.multiply(0, nan)) -IO.inspect(Nx.equal(nan, nan)) -IO.inspect(Nx.greater(nan, nan)) -IO.inspect(Nx.subtract(nan, nan)) +Nx.multiply(0, nan) +Nx.equal(nan, nan) +Nx.greater(nan, nan) +Nx.subtract(nan, nan) + +# Add your solution here. +:ok ``` -**18. Create a 5x5 tensor with values 1,2,3,4 just below the diagonal (★☆☆)** +
+ 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 -Nx.make_diagonal(Nx.tensor([1, 2, 3, 4]), offset: -1) +# Add your solution here. +:ok ``` -**19. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element (★☆☆)** +
+ 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. (★☆☆)** ```elixir -Nx.tensor([[0, 1], [1, 0]]) -|> Nx.tile([4, 4]) +# Add your solution here. +:ok ``` -**20. What is the index (x,y,z) of the 100th element of a 6x7x8 tensor?** +
+ Example solution +
-```elixir -# The numpy solution is to use `unravel_index`. I didn't see an equivalent. -# https://numpy.org/doc/stable/reference/generated/numpy.unravel_index.html -dims = [6, 7, 8] -target = 100 + ```elixir + Nx.tensor([[0, 1], [1, 0]]) + |> Nx.tile([4, 4]) + ``` -# This is how I'd do it with Enum. -dims -|> Enum.map_reduce({target, Enum.product(dims)}, fn dim, {remaining, step_size} -> - step_size = div(step_size, dim) - num_steps = div(remaining, step_size) - {num_steps, {remaining - num_steps * step_size, step_size}} -end) -|> then(fn {indices, {0, 1}} -> indices end) +
+
+ + + +**20. Find the (x,y,z) index ([row major](https://en.wikipedia.org/wiki/Row-_and_column-major_order)) of the 100th element of a 6x7x8 tensor. (★★☆)** + +```elixir +# Add your solution here. +:ok ``` + +
+ Example solution +
+ + ```elixir + defmodule Exercise20 do + import Nx.Defn + + deftransform solve(shape, target) do + dims = Tuple.to_list(shape) + + dims + |> Enum.map_reduce({target, Enum.product(dims)}, fn dim, {remaining, step_size} -> + step_size = div(step_size, dim) + num_steps = div(remaining, step_size) + {num_steps, {remaining - num_steps * step_size, step_size}} + end) + |> then(fn {indices, {0, 1}} -> indices end) + end + end + + Exercise20.solve({6, 7, 8}, 100) + ``` + +
+
From bee6f3e6dcfbf697adc7a342c0dccb37b2a8ed63 Mon Sep 17 00:00:00 2001 From: Billy Lanchantin Date: Tue, 14 Nov 2023 09:01:33 -0500 Subject: [PATCH 18/26] clarify wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonatan Kłosko --- nx/exercises/exercises-1-20.livemd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 0449aa0ccb..38e55f08a1 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -307,7 +307,7 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) -**14. Create a 1D tensor of size 30 then find its mean. (★☆☆)** +**14. Create a random 1D tensor of size 30 then find its mean. (★☆☆)** ```elixir # Add your solution here. From 2ff9ee8f3f03fc8477a2fe5b98c0e76fa89941ba Mon Sep 17 00:00:00 2001 From: Billy Lanchantin Date: Tue, 14 Nov 2023 09:04:33 -0500 Subject: [PATCH 19/26] use markdown link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonatan Kłosko --- nx/exercises/exercises-1-20.livemd | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 38e55f08a1..2d47904cf1 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -6,9 +6,7 @@ Mix.install([{:nx, "~> 0.6"}]) ## Introduction -Inspired by the Python notebook _100 Numpy Exercises_: - -https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook +Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/code/utsav15/100-numpy-exercises/notebook). ## 1-10 From 9ecf23d533a712e8915385f29f73c37a5a797eba Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Tue, 14 Nov 2023 09:13:27 -0500 Subject: [PATCH 20/26] remove trailing `:ok`s --- nx/exercises/exercises-1-20.livemd | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 2d47904cf1..442ccf93e3 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -14,7 +14,6 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod ```elixir # Add your solution here. -:ok ```
@@ -34,7 +33,6 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod ```elixir # Add your solution here. -:ok ```
@@ -55,7 +53,6 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod ```elixir tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. -:ok ```
@@ -76,7 +73,6 @@ tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) ```elixir tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. -:ok ```
@@ -96,7 +92,6 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) ```elixir # Add your solution here. -:ok ```
@@ -117,7 +112,6 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) ```elixir # Add your solution here. -:ok ```
@@ -139,7 +133,6 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) ```elixir # Add your solution here. -:ok ```
@@ -160,7 +153,6 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) ```elixir tensor_08 = Nx.tensor([2, 4, 6, 8]) # Add your solution here. -:ok ```
@@ -180,7 +172,6 @@ tensor_08 = Nx.tensor([2, 4, 6, 8]) ```elixir # Add your solution here. -:ok ```
@@ -201,7 +192,6 @@ tensor_08 = Nx.tensor([2, 4, 6, 8]) ```elixir tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. -:ok ```
@@ -221,7 +211,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -241,7 +230,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -261,7 +249,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -283,7 +270,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -309,7 +295,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -332,7 +317,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir # Add your solution here. -:ok ```
@@ -354,7 +338,6 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir tensor_16 = Nx.broadcast(1, {3, 3}) # Add your solution here. -:ok ```
@@ -380,7 +363,6 @@ Nx.greater(nan, nan) Nx.subtract(nan, nan) # Add your solution here. -:ok ```
@@ -415,7 +397,6 @@ Nx.subtract(nan, nan) ```elixir # Add your solution here. -:ok ```
@@ -436,7 +417,6 @@ Nx.subtract(nan, nan) ```elixir # Add your solution here. -:ok ```
@@ -457,7 +437,6 @@ Nx.subtract(nan, nan) ```elixir # Add your solution here. -:ok ```
From aa93d548e07cab5daea6e7a76a1e4e45ad4f84b8 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Tue, 14 Nov 2023 09:38:39 -0500 Subject: [PATCH 21/26] name everything just `tensor` --- nx/exercises/exercises-1-20.livemd | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 442ccf93e3..24dfb29bc6 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -48,10 +48,10 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod -**3. Find the number of elements in `tensor_03`. (★☆☆)** +**3. Find the number of elements in `tensor`. (★☆☆)** ```elixir -tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. ``` @@ -60,7 +60,7 @@ tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]])
```elixir - Nx.size(tensor_03) + Nx.size(tensor) ```
@@ -68,10 +68,10 @@ tensor_03 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) -**4. Find the number of bytes of memory in `tensor_04`. (★☆☆)** +**4. Find the number of bytes of memory in `tensor`. (★☆☆)** ```elixir -tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. ``` @@ -80,7 +80,7 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]])
```elixir - Nx.byte_size(tensor_04) + Nx.byte_size(tensor) ```
@@ -148,10 +148,10 @@ tensor_04 = Nx.tensor([[1, 2, 3], [4, 5, 6]]) -**8. Reverse `tensor_08` (first element becomes last). (★☆☆)** +**8. Reverse `tensor` (first element becomes last). (★☆☆)** ```elixir -tensor_08 = Nx.tensor([2, 4, 6, 8]) +tensor = Nx.tensor([2, 4, 6, 8]) # Add your solution here. ``` @@ -160,7 +160,7 @@ tensor_08 = Nx.tensor([2, 4, 6, 8])
```elixir - Nx.reverse(tensor_08) + Nx.reverse(tensor) ```
@@ -187,10 +187,10 @@ tensor_08 = Nx.tensor([2, 4, 6, 8]) -**10a. Given an initial `tensor_10`, 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. (★☆☆)** +**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_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) +tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` @@ -199,7 +199,7 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0])
```elixir - mask = Nx.not_equal(tensor_10, 0) + mask = Nx.not_equal(tensor, 0) ```
@@ -207,7 +207,7 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) -**10b. Use the mask from 10a to replace each 0 from `tensor_10` with -1. (★☆☆)** +**10b. Use the mask from 10a to replace each 0 from `tensor` with -1. (★☆☆)** ```elixir # Add your solution here. @@ -218,7 +218,7 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0])
```elixir - Nx.select(mask, tensor_10, -1) + Nx.select(mask, tensor, -1) ```
@@ -278,11 +278,11 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir key = Nx.Random.key(0) - {tensor_13, _} = Nx.Random.normal(key, shape: {10, 10}) + {tensor, _} = Nx.Random.normal(key, shape: {10, 10}) %{ - min: Nx.reduce_min(tensor_13), - max: Nx.reduce_max(tensor_13) + min: Nx.reduce_min(tensor), + max: Nx.reduce_max(tensor) } ``` @@ -303,9 +303,9 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) ```elixir key = Nx.Random.key(0) - {tensor_14, _} = Nx.Random.normal(key, shape: {30}) + {tensor, _} = Nx.Random.normal(key, shape: {30}) - Nx.mean(tensor_14) + Nx.mean(tensor) ``` @@ -333,10 +333,10 @@ tensor_10 = Nx.tensor([1, 2, 0, 0, 4, 0]) -**16. Add a border of 0 around `tensor_16` (end result will be a 5x5 tensor). (★☆☆)** +**16. Add a border of 0 around `tensor` (end result will be a 5x5 tensor). (★☆☆)** ```elixir -tensor_16 = Nx.broadcast(1, {3, 3}) +tensor = Nx.broadcast(1, {3, 3}) # Add your solution here. ``` @@ -345,7 +345,7 @@ tensor_16 = Nx.broadcast(1, {3, 3})
```elixir - Nx.pad(tensor_16, 0, [{1, 1, 0}, {1, 1, 0}]) + Nx.pad(tensor, 0, [{1, 1, 0}, {1, 1, 0}]) ```
From 57e8be4eff3f1614ff4ddce198fc3293b7cf99c5 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Tue, 14 Nov 2023 10:26:45 -0500 Subject: [PATCH 22/26] change docs exercise to be better suited to livebook --- nx/exercises/exercises-1-20.livemd | 35 +++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 24dfb29bc6..84ef9df48a 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -88,9 +88,10 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) -**5. Use `IEx.Helpers` to print the documentation of the `Nx.add/2` function. (★☆☆)** +**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. ``` @@ -99,8 +100,7 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]])
```elixir - import IEx.Helpers - h Nx.add + Nx.sum(tensor) ```
@@ -108,6 +108,35 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) +**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 +
+
+

In Livebook, you can also hover over a function to display its documentation.

+
+
+ +
+
+ + + **6. Create a tensor of zeros of size 10 but where the fifth value is 1. (★☆☆)** ```elixir From 57b39209f1b5606ad810b2c7c14dcc73ca631923 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Tue, 14 Nov 2023 11:11:46 -0500 Subject: [PATCH 23/26] switch to inline styles --- nx/exercises/exercises-1-20.livemd | 140 ++++++++++++++--------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 84ef9df48a..056ff077e2 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -16,9 +16,9 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Mix.install([{:nx, "~> 0.6"}]) @@ -35,9 +35,9 @@ Inspired by the Python notebook [100 Numpy Exercises](https://www.kaggle.com/cod # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.broadcast(0, {10}) @@ -55,9 +55,9 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.size(tensor) @@ -75,9 +75,9 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.byte_size(tensor) @@ -95,9 +95,9 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.sum(tensor) @@ -114,20 +114,20 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.sum(tensor, axes: [1]) ``` -
-
- +
+
+ Tip
-
+

In Livebook, you can also hover over a function to display its documentation.

@@ -143,9 +143,9 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir zeros = Nx.broadcast(0, {10}) @@ -164,9 +164,9 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.linspace(10, 49, n: 39, type: :s8) @@ -184,9 +184,9 @@ tensor = Nx.tensor([2, 4, 6, 8]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.reverse(tensor) @@ -203,9 +203,9 @@ tensor = Nx.tensor([2, 4, 6, 8]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.iota({3, 3}) @@ -223,9 +223,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir mask = Nx.not_equal(tensor, 0) @@ -242,9 +242,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.select(mask, tensor, -1) @@ -261,9 +261,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.eye(3) @@ -280,9 +280,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir key = Nx.Random.key(0) @@ -301,9 +301,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir key = Nx.Random.key(0) @@ -326,9 +326,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir key = Nx.Random.key(0) @@ -348,9 +348,9 @@ tensor = Nx.tensor([1, 2, 0, 0, 4, 0]) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.broadcast(1, {4, 4}) @@ -369,9 +369,9 @@ tensor = Nx.broadcast(1, {3, 3}) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.pad(tensor, 0, [{1, 1, 0}, {1, 1, 0}]) @@ -394,9 +394,9 @@ Nx.subtract(nan, nan) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
``` #Nx.Tensor< @@ -428,9 +428,9 @@ Nx.subtract(nan, nan) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.tensor([1, 2, 3, 4]) @@ -448,9 +448,9 @@ Nx.subtract(nan, nan) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir Nx.tensor([[0, 1], [1, 0]]) @@ -468,9 +468,9 @@ Nx.subtract(nan, nan) # Add your solution here. ``` -
- Example solution -
+
+ Example solution +
```elixir defmodule Exercise20 do From 58eb8b1e431653316828a863ddfcdc978e31d5d1 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sat, 18 Nov 2023 20:44:39 -0500 Subject: [PATCH 24/26] make 20 another checkerboard exercise --- nx/exercises/exercises-1-20.livemd | 44 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 056ff077e2..bf21c16865 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -442,7 +442,7 @@ Nx.subtract(nan, nan) -**19. Create a 8x8 tensor of 0 and 1 in a checkerboard pattern with 0 as the first element. (★☆☆)** +**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. @@ -462,34 +462,38 @@ Nx.subtract(nan, nan) -**20. Find the (x,y,z) index ([row major](https://en.wikipedia.org/wiki/Row-_and_column-major_order)) of the 100th element of a 6x7x8 tensor. (★★☆)** +**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 + Example solution 1 +
+ + ```elixir + t = Nx.iota({8, 1}) + + Nx.transpose(t) + |> Nx.add(t) + |> Nx.remainder(2) + ``` + +
+
+ + + +
+ Example solution 2
```elixir - defmodule Exercise20 do - import Nx.Defn - - deftransform solve(shape, target) do - dims = Tuple.to_list(shape) - - dims - |> Enum.map_reduce({target, Enum.product(dims)}, fn dim, {remaining, step_size} -> - step_size = div(step_size, dim) - num_steps = div(remaining, step_size) - {num_steps, {remaining - num_steps * step_size, step_size}} - end) - |> then(fn {indices, {0, 1}} -> indices end) - end - end - - Exercise20.solve({6, 7, 8}, 100) + Nx.iota({9, 9}) + |> Nx.remainder(2) + |> Nx.slice([0, 0], [8, 8]) ```
From a087119e616ec2480d03374a462ef3aadb7bb726 Mon Sep 17 00:00:00 2001 From: Billy Lanchantin Date: Sun, 26 Nov 2023 11:01:56 -0500 Subject: [PATCH 25/26] tone down styling on tip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Valim --- nx/exercises/exercises-1-20.livemd | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index bf21c16865..2e4f3eee6e 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -123,13 +123,7 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) ```
-
- - Tip -
-
-

In Livebook, you can also hover over a function to display its documentation.

-
+ Tip: You can also hover over a function inside Livebook code cells to display its documentation.
From e667514a8e1515dbd73cce6dcbde958dfe171fc2 Mon Sep 17 00:00:00 2001 From: William Lanchantin Date: Sun, 26 Nov 2023 11:14:20 -0500 Subject: [PATCH 26/26] 8->7; 9->8; 7->9; add iota solution --- nx/exercises/exercises-1-20.livemd | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/nx/exercises/exercises-1-20.livemd b/nx/exercises/exercises-1-20.livemd index 2e4f3eee6e..812d3a5197 100644 --- a/nx/exercises/exercises-1-20.livemd +++ b/nx/exercises/exercises-1-20.livemd @@ -152,7 +152,7 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -**7. Create a tensor with values ranging from 10 to 49. (★☆☆)** +**7. Create a 3x3 tensor with values ranging from 0 to 8. (★☆☆)** ```elixir # Add your solution here. @@ -163,7 +163,7 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
```elixir - Nx.linspace(10, 49, n: 39, type: :s8) + Nx.iota({3, 3}) ```
@@ -171,19 +171,32 @@ tensor = Nx.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -**8. Reverse `tensor` (first element becomes last). (★☆☆)** +**8. Create a tensor with values ranging from 10 to 49. (★☆☆)** ```elixir -tensor = Nx.tensor([2, 4, 6, 8]) # Add your solution here. ```
- Example solution + Example solution 1
```elixir - Nx.reverse(tensor) + Nx.iota({39}) + |> Nx.add(10) + ``` + +
+
+ + + +
+ Example solution 2 +
+ + ```elixir + Nx.linspace(10, 49, n: 39, type: :s64) ```
@@ -191,9 +204,10 @@ tensor = Nx.tensor([2, 4, 6, 8]) -**9. Create a 3x3 tensor with values ranging from 0 to 8. (★☆☆)** +**9. Reverse `tensor` (first element becomes last). (★☆☆)** ```elixir +tensor = Nx.tensor([2, 4, 6, 8]) # Add your solution here. ``` @@ -202,7 +216,7 @@ tensor = Nx.tensor([2, 4, 6, 8])
```elixir - Nx.iota({3, 3}) + Nx.reverse(tensor) ```