Assignment: N-dimensional arrays

Download this crate for the fifth homework assignment. It contains tests and prototypes.

1 Array data type

In the previous assignments we have worked with, scalars, vectors and matrices and used different data types to represent them. The goal of this assignment is to represent these using a single generic data type, namely N-dimensional arrays:

Even though we would want to use one generic data type for N-dimensional arrays, arrays of different dimensionalities should have different specialized types. This allows us to use the type system to prevent undefined operations (such as the element-wise product of a vector and a matrix).

The crucial insight for a N-dimensional array type is that we can represent the number of dimensions using sized Rust array types. So, if we have a generic type Array<D>, the specialized types for scalars, vectors, matrices, and third order arrays are:

Array<[usize; 0]>
Array<[usize; 1]>
Array<[usize; 2]>
Array<[usize; 3]>

The additional benefit of using sized arrays as type parameters is that we can use arrays with the corresponding size to specify the shape of an array or as indexes. For example:

// Create an array of type Array<[usize; 2]>
let example = Array::from_vec([3, 2], vec![1., 2., 3., 4., 5., 6.]);

// Get a value.
let v = example.get([0, 0]);

// Compiler error: cannot use a 2-D array with a 3-D index.
let w = example.get([0, 0, 0]);

Notes:

1.1 Implement the Dim trait

Provide implementations of the Dim trait for Ix0, Ix1, Ix2, and Ix3. Ix[1-4] are type aliases for usize arrays of the corresponding lengths.

Do not overthink this one, the trait implementations are trivial.

1.2 Implement index

The get and set methods are now provided, but use the index method to obtain the index in the data array. Implement this index version. Note that this function should now work for N-dimensional arrays of any .

You can find a description of the generalized index calculation of row-major arrays on the Wikipedia page about orders

Unit tests: get_order0_test, get_order1_test, get_order2_test get_order3_test, set_order_test.

2.1 Operators

2.1 Elementwise multiplication

Implement elementwise multiplication of two N-dimensional arrays (with the same value for N) by implementing the Mul trait.

After implementing this trait you can use the * operator to multiply arrays. For example:

let r = u * v;

Note: if you want the most flexibility, implement the Mul trait for Array and &Array

Unit test: mul_test

2.2 (Generalized) dot product

A trait Dot is provided. Make two implementations of Dot:

  1. One that returns the dot product of two Array<Ix1>s.
  2. One that returns the matrix multiplication of two Array<Ix2>s.

Unit test: dot_rank_1_test, dot_rank_2_test

2.3 Enable tests

Enable all unit tests by removing the

#[cfg(disable)]

line above every unit test.

Submission

The tar.gz or zip file should be uploaded through this page. The deadline is June 12 at 14:00.