From 84205ff9cb22948dcc2dc0ed3312b91353e406bc Mon Sep 17 00:00:00 2001 From: Kiana Sheibani Date: Wed, 24 Apr 2024 18:59:47 -0400 Subject: [PATCH] Add beginnings of a tutorial --- README.md | 4 +- docs/DataTypes.md | 154 ++++++++++++++++++++++++++++++++++++++++ docs/Intro.md | 16 +++++ docs/Operations.md | 2 + docs/Representations.md | 2 + docs/Transforms.md | 2 + docs/VectorsMatrices.md | 2 + 7 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 docs/DataTypes.md create mode 100644 docs/Intro.md create mode 100644 docs/Operations.md create mode 100644 docs/Representations.md create mode 100644 docs/Transforms.md create mode 100644 docs/VectorsMatrices.md diff --git a/README.md b/README.md index 8640047..52d2522 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ combine the most useful features of each library. ## Documentation -Most of the exported utility functions have docstrings. There are also plans for -an in-depth tutorial on NumIdr's features, though that is not available yet. +Most of the exported utility functions have docstrings. There is also +a (currently unfinished) tutorial of NumIdr's features [here](docs/Intro.md). ## Usage diff --git a/docs/DataTypes.md b/docs/DataTypes.md new file mode 100644 index 0000000..ff3d8b3 --- /dev/null +++ b/docs/DataTypes.md @@ -0,0 +1,154 @@ +# Fundamental Data Types + +Most of the data that NumIdr operates on is stored in arrays, but there are a few other types and structures that are important to understand. + +## Arrays + +### What is an Array? + +In most programming languages and libraries, the word "array" is used to mean a one-dimensional list of values that is contiguous in memory. A typical array of integers may be written in list form like this: + +``` +[1, 4, 10, 2, -5, 18] +``` + +In a typical one-dimensional array, elements are indexed by a single integer, starting at zero and increasing from left to right. + +NumIdr, however, uses the word a bit more generally: a NumIdr array is a multi-dimensional structure that can be indexed by any number of integers. NumIdr arrays are written as nested lists: + +``` +[[4, -9, -2], + [5, -6, 1]] +``` + +Unlike in other languages, however, this is not a nested structure. The above is a single array, and it is always manipulated as one object. + +### Properties of Arrays + +The `Array` datatype has the following parameters: + +```idris +Array : (s : Vect rk Nat) -> (a : Type) -> Type +``` + +The first parameter is the _shape_, a list of numbers (the _dimensions_) where each dimension is the length of a particular _axis_ of the array. The second parameter is the _element type_, the type of the values inside the array. + +Let's return to the array example from earlier: + +``` +[[4, -9, -2], + [5, -6, 1]] +``` + +This is a rank-2 array, meaning that it has two axes. Rank-2 arrays are typically called matrices. To determine the dimensions of the array, we count the size of each nested list from the outside in, which in the case of matrices means the row axis comes before the column axis. This matrix has 2 rows and 3 columns, making its shape `[2, 3]`. Thus, a possible type for this array could be `Array [2, 3] Int`. + +When determining the index of a value inside the array, the order of the indices is the same as the order of the dimensions, and each index number counts from zero. For example, the index `[1, 0]` indicates the second row and first column, which contains `5`. + +> [!NOTE] +> The word "dimensions" is often ambiguously used to either refer to the rank of an array +> (as in "multi-dimensional array" in the previous section), or to the lengths of its +> axes. Conventionally, NumIdr reserves "dimension" for the second meaning, and uses +> "rank" for the first meaning. +> +> This guide has ignored this convention until now to be more understandable to newcomers, +> but will follow it from this point onward. + +## Types of Arrays + +Arrays are loosely divided into multiple subtypes mostly based on their rank. Each array subtype has an alias for convenience. + +### Scalars + +A scalar is a rank-0 array, meaning that it is indexed by 0 integers. Its alias is `Scalar`: + +```idris +Scalar : (a : Type) -> Type +Scalar = Array [] +``` + +A scalar has exactly one index, the empty list `[]`. This means that it is exactly the same as a single value and as such is largely pointless, but NumIdr still provides an alias for it just in case you need it. + +### Vectors + +A vector is a rank-1 array: + +```idris +Vector : (n : Nat) -> (a : Type) -> Type +Vector n = Array [n] +``` + +A vector's type signature and stored data is effectively identical to that of the standard library type `Vect`, whose elements are confusingly also called "vectors"; we often refer to these as "vects" to differentiate. + +Indices are typically written as lists of integers, but for vectors it is occasionally acceptable to write the single index number without putting it inside a list. This is mostly the case for indexing, where each indexing function has an alternate definition specifically for vectors. + +### Matrices + +As mentioned before, a matrix is a rank-2 array: + +```idris +Matrix : (m, n : Nat) -> (a : Type) -> Type +Matrix m n = Array [m, n] +``` + +There is also an alias `Matrix'` for square matrices. + +```idris +Matrix' : (n : Nat) -> (a : Type) -> Type +Matrix' n = Array [n, n] +``` + +As a linear algebra library, the majority of the operations in NumIdr revolve around matrices. + +#### Homogeneous Matrices + +NumIdr also provides aliases for homogeneous matrices: + +```idris +HMatrix : (m, n : Nat) -> (a : Type) -> Type +HMatrix m n = Array [S m, S n] + +HMatrix' : (n : Nat) -> (a : Type) -> Type +HMatrix' n = Array [S n, S n] + +-- To use with homogeneous matrices +HVector : (n : Nat) -> (a : Type) -> Type +HVector n = Array [S n] +``` + +These are useful for clarity when working with both homogeneous and non-homogeneous matrices. + +## Other Datatypes + +### Transforms + +A transform is a wrapper type for a matrix with certain properties that can be used to transform points in space. + +```idris +Transform : (ty : TransType) -> (n : Nat) -> (a : Type) -> Type +``` + +The `TransType` parameter dictates what kind of transform it is. These eight options are currently available: + +**Linear Types:** +- Trivial (always the identity transformation) +- Rotation +- Orthonormal (rotation + reflection) +- Linear + +**Affine Types:** +- Translation +- Rigid (rotation + translation) +- Isometry (rotation + reflection + translation) +- Affine + +The `TransType` value is obtained by prepending a capital T to these names. For example, an isometry may have the type `Isometry 3 Double`, which is an alias for `Transform TIsometry 3 Double`. + +#### The Point Type + +Transforms behave differently from regular matrices when applied to a vector. When a non-linear transform is used, the transform is first linearized, so that vectors only have linear transformations applied to them. This is not a bug. + +In order to properly apply these transforms, the `Point` type must be used, which is a wrapper around the `Vector` type that supports these transforms. This separation between points and vectors is intended to make working with affine transformations more convenient, as it mirrors the separation between points and vectors in affine algebra. + +### Permutations + +The type `Permutation n` represents a permutation of `n` elements. Permutations are mostly used internally for various algorithms, but they are also an input in various operations, such as those that permute the axes of an array. diff --git a/docs/Intro.md b/docs/Intro.md new file mode 100644 index 0000000..bcc6e0e --- /dev/null +++ b/docs/Intro.md @@ -0,0 +1,16 @@ +# NumIdr Tutorial + +Welcome to NumIdr's tutorial! + +If you're familiar with the Python library [NumPy](https://numpy.org/) or anything based on it, then a lot of the early content will be familiar, as NumIdr is based on the same array type. + +#### Tutorial + +1. [Fundamental Data Types](DataTypes.md) +2. Basic Operations +3. Working with Vectors and Matrices +4. Transforms + +#### Advanced Concepts + +5. Array Representations diff --git a/docs/Operations.md b/docs/Operations.md new file mode 100644 index 0000000..66a6fca --- /dev/null +++ b/docs/Operations.md @@ -0,0 +1,2 @@ +# Basic Operations + diff --git a/docs/Representations.md b/docs/Representations.md new file mode 100644 index 0000000..b78c656 --- /dev/null +++ b/docs/Representations.md @@ -0,0 +1,2 @@ +# Array Representations + diff --git a/docs/Transforms.md b/docs/Transforms.md new file mode 100644 index 0000000..8d482ae --- /dev/null +++ b/docs/Transforms.md @@ -0,0 +1,2 @@ +# Transforms + diff --git a/docs/VectorsMatrices.md b/docs/VectorsMatrices.md new file mode 100644 index 0000000..b0c97bb --- /dev/null +++ b/docs/VectorsMatrices.md @@ -0,0 +1,2 @@ +# Working with Vectors and Matrices +