A Short Nx Quiz
Sharpen Your Array Programming Skills with Elixir’s Nx Library
Introduction
Numerical Elixir is a project that brings Elixir to the world of numerical computing and machine learning. Nx
is a multi-dimensional tensors library for Elixir. Learning how to program with Elixir’s Nx
library is really just a matter of repetition. In this post, we’ll go through a number of Nx
brain teasers to exercise your array-programming skills. Let’s dive in!
Installation
For this quiz you’ll need Nx
installed in a Livebook or an Elixir script:
Mix.install([ {:nx, "~> 0.1.0"}])
Unary Operations
Nx
has a number of element-wise unary functions. Let's see if you can put them to use!
Exponentials
e is perhaps one of the most important constants in mathematics. It appears everywhere. Use Nx
to calculate the exponential for every value in a tensor.
exp_tensor = fn x ->
Nx.exp(x)
end
Trig Functions
The trigonometric functions sin, tan, and cos are widely used in a number of fields. Use Nx
to calculate sine, cosine, and tangent of every value in a tensor.
sin_tensor = fn x -> Nx.sin(x) end
cos_tensor = fn x -> Nx.cos(x) end
tan_tensor = fn x -> Nx.tan(x) end
Composing Unary Functions
Nx
functions can be easily composed to implement more complex unary operations. Create a function that computes the cosine of the exponential of every value in a tensor.
cos_exp = fn x ->
x
|> Nx.exp()
|> Nx.cos()
end
Binary Operations
In addition to some standard unary operations, Nx
has some operations that allow you to compute results from element-wise binary operations.
Basic Addition
Implement a function that computes x + y
for corresponding values in tensors x and y.
add_2 = fn x, y -> Nx.add(x, y) end
Broadcasting
Broadcasting is an important concept in Nx
. Implement a function that multiplies the fixed scalar value π\piπ to any input tensor.
multiply_pi = fn x -> Nx.multiply(Nx.Constants.pi(), x) end
Composition
Once again, you’ll often need to compose binary operations for complex calculations. Implement a function that computes the result of dividing two tensors x
and y
and then multiplying the result by a scalar alpha
.
alpha_x_y = fn x, y, alpha ->
y
|> Nx.divide(x)
|> Nx.multiply(alpha)
Ramping Up
With a good grasp of unary and binary operation semantics, let’s ramp up the difficulty. In this section, you’ll test your skills composing various parts of the Nx APIs.
Fancy Tensor Creation
Use the Nx
API that creates a vector with n
elements, where each element is the current index if the current index is even, or the result of taking the cosine of the exponential of the current index if the current index is odd.
create_fancy_tensor = fn n ->
indices = Nx.iota({n})
indices
|> Nx.remainder(2)
|> Nx.equal(0)
|> Nx.select(indices, Nx.cos(Nx.exp(indices)))
end
Cumulative Max
Nx
does not currently implement a cumulative max in its API. Implement a cumulative max using the available functions in the API. For bonus points, see if you can open a PR to add this functionality to Nx
:)
cumulative_max = fn tensor ->
# No cheating... ;)
end
📣 If you enjoyed this quiz and want to do more with more challenging problems, leave a comment to let me know!