 
 // MARK: - Dimensions
 
+/**
+    A struct representing the dimensions of a 2-dimensional matrix.
+*/
 struct Dimensions: Equatable, Addable {
     
+    /**
+        The number of rows in the dimensions.
+    */
     let rows: Int
+    
+    /**
+        The number of columns in the dimensions.
+    */
     let columns: Int
     
+    /**
+        Creates a new dimensions object with the given number of rows and columns.
+    
+        :param: rows    The number of rows in the dimensions.
+        :param: columns The number of columns in the dimensions.
+    */
     init(_ rows: Int = 0, _ columns: Int = 0) {
         
         self.rows = rows
         self.columns = columns
     }
     
+    /**
+        Creates a new dimensions object where the number of rows and columns are equal.
+    
+        :param: size    The size of the dimensions. This value will be used for both the
+                            number of rows and columns.
+    */
     init(size: Int) {
         
         self.init(size, size)


// MARK: Matrix Addition

func + <T: MatrixCompatible> (left: Matrix<T>, right: Matrix<T>) -> Matrix<T> {
    
    if left.dimensions != right.dimensions {


// MARK: Matrix Subtraction

/**
    Returns the subtraction of the two given matrices.

    :param: left    The left matrix in the subtraction.
    :param: right   The right matrix in the subtraction.

    :returns: A matrix with the same dimensions as the two given matrices
                where every element is the difference of the corresponding
                elements in the left and right matrices.

    :exception: Throws an exception when the dimensions of the two given
                    matrices are not equal.
*/
func - <T: MatrixCompatible> (left: Matrix<T>, right: Matrix<T>) -> Matrix<T> {
    
    if left.dimensions != right.dimensions {
        NSException(name: "Unequal dimensions", reason: "The dimensions of the two given matrices are not equal. Left dimensions: \(left.dimensions), right dimensions: \(right.dimensions).", userInfo: nil).raise()
    }
    
    return mcombine(left, right){ $0 - $1 }
}


// MARK: Matrix Scalar Multiplication

/**
    Returns the product of the given scalar and the given matrix.

    :param: scalar  The scalar with which to multiply the given matrix.
    :param: matrix  The matrix to multiply with the given scalar.

    :returns: A matrix of the same dimensions as the given matrix where
                every element is calculated as the product of the corresponding
                element in the given matrix and the given scalar.
*/
func * <T: MatrixCompatible> (scalar: T, matrix: Matrix<T>) -> Matrix<T> {
    
    return Matrix(map(matrix.elements){ map($0){ scalar * $0 } })
}

/**
    Returns the product of the given scalar and the given matrix.

    :param: scalar  The scalar with which to multiply the given matrix.
    :param: matrix  The matrix to multiply with the given scalar.

    :returns: A matrix of the same dimensions as the given matrix where
                every element is calculated as the product of the corresponding
                element in the given matrix and the given scalar.
*/
func * <T: MatrixCompatible> (matrix: Matrix<T>, scalar: T) -> Matrix<T> {
    
    return scalar * matrix
