# 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:

- 0-dimensional arrays: scalars
- 1-dimensional arrays: vectors
- 2-dimensional arrays: matrices

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:**

- In this assignment we will always use
**row-major**order. - Most subassignments come with unit tests, but I had to disable them
for the initial code to compile. Remove the line
`#[cfg(disable)]`

above a test to enable it.

### 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`

:

- One that returns the dot product of two
`Array<Ix1>`

s. - 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

- Submit your updated project, archived as a
`tar.gz`

or`zip`

file. - Include the first names of the team members in the archive name.
- Run
`cargo clean`

before archiving the project.

The `tar.gz`

or `zip`

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