Make it compile: linear algebra exercises #1
Rust has a crate called ndarray
. It’s like numpy
in Python. These exercises are designed to help you get familiar with ndarray
, so you can use it in your data science or bioinformatics workflows.
I mention the word tensor
a few times below. A tensor is simply an n-dimensional data structure. A 0-dimensional tensor is a scalar, a 1-dimensional tensor is a vector, and a 2-dimensional tensor is a matrix. In this first part, we will start with element-wise operations.
Shapes are important when performing arithmetic operations on tensors. Some things about tensor shapes to keep in mind while you work through the problems:
- If you are performing an arithmetic operation between a tensor and a scalar, the input tensor shape = output tensor shape.
- If the operation is between 2 tensors with same shape, then the input tensor shape = output tensor shape.
- If the input tensors are of different shapes, then one of the tensors should be compatible for broadcasting and the other tensor’s shape = output tensor shape.
- If your tensor can’t broadcast, you will see ShapeError.
You can open Rust Playground and work on these there. You will see 5 problems. The first one is solved for you. This code will not compile until you solve all the problems. Your task is to make this compile.
use ndarray::array;
fn main() {
problem_one();
problem_two();
problem_three();
problem_four();
problem_five();
println!("{}", "Congrats! You solved all problems.")
}
// a tensor * a scalar
fn problem_one() {
let a1 = array![1, 2, 3, 4];
let scalar = 2;
let expected = array![2, 4, 6, 8];
assert_eq!(a1 * scalar, expected, "Check problem 1");
}
// a tensor + a scalar
fn problem_two() {
let a1 = array![1, 2, 3, 4];
// ADD CODE BELOW THIS LINE
// Define a scalar value, so the assert statement passes
let scalar = __;
// ADD CODE ABOVE THIS LINE
let expected = array![10, 11, 12, 13];
assert_eq!(a1 + scalar, expected, "Check problem 2");
}
// a tensor * another tensor (same shape)
fn problem_three() {
let a1 = array![1, 2, 3, 4];
// ADD CODE BELOW THIS LINE
// Define array/tensor, so the assert statement passes
let a2 = __;
// ADD CODE ABOVE THIS LINE
let expected = array![0, 0, 0, 0];
assert_eq!(a1 * a2, expected, "Check problem 3");
}
// a tensor + another tensor (same shape)
fn problem_four() {
let a1 = array![1, 2, 3, 4];
// ADD CODE BELOW THIS LINE
// Define array/tensor, so the assert statement passes
let a2 = __;
// ADD CODE ABOVE THIS LINE
let expected = array![0, 0, 0, 0];
assert_eq!(a1 + a2, expected, "Check problem 4");
}
// a tensor * another tensor (different shapes)
fn problem_five() {
let a1 = array![[1, 1]];
// ADD CODE BELOW THIS LINE
// Define array/tensor, so the assert statement passes
let a2 = __;
// ADD CODE ABOVE THIS LINE
let expected = array![[1, 2], [3, 4]];
assert_eq!(a1 * a2, expected, "Check problem 5");
}