Add documentation
This commit is contained in:
parent
11d771b926
commit
59af31cdd7
|
@ -1,5 +1,6 @@
|
|||
module Data.NumIdr.Array
|
||||
|
||||
import public Data.NP
|
||||
import public Data.NumIdr.Array.Array
|
||||
import public Data.NumIdr.Array.Coords
|
||||
import public Data.NumIdr.Array.Order
|
||||
|
|
|
@ -4,6 +4,7 @@ import Data.List
|
|||
import Data.List1
|
||||
import Data.Vect
|
||||
import Data.Zippable
|
||||
import Data.NP
|
||||
import Data.NumIdr.Multiply
|
||||
import Data.NumIdr.PrimArray
|
||||
import Data.NumIdr.Array.Order
|
||||
|
@ -63,6 +64,7 @@ strides : Array {rk} s a -> Vect rk Nat
|
|||
strides (MkArray _ sts _ _) = sts
|
||||
|
||||
||| The total number of elements of the array
|
||||
|||
|
||||
||| This is equivalent to `product s`.
|
||||
export
|
||||
size : Array s a -> Nat
|
||||
|
@ -175,6 +177,26 @@ export
|
|||
fromStream : (s : Vect rk Nat) -> Stream a -> Array s a
|
||||
fromStream s = fromStream' s COrder
|
||||
|
||||
|
||||
||| Create an array given a function to generate its elements.
|
||||
|||
|
||||
||| @ s The shape of the constructed array
|
||||
||| @ ord The order to interpret the elements
|
||||
export
|
||||
fromFunctionNB' : (s : Vect rk Nat) -> (ord : Order) -> (Vect rk Nat -> a) -> Array s a
|
||||
fromFunctionNB' s ord f = let sts = calcStrides ord s
|
||||
in MkArray ord sts s (unsafeFromIns (product s) $
|
||||
map (\is => (getLocation' sts is, f is)) $ getAllCoords' s)
|
||||
|
||||
||| Create an array given a function to generate its elements.
|
||||
||| To specify the order of the array, use `fromFunctionNB'`.
|
||||
|||
|
||||
||| @ s The shape of the constructed array
|
||||
||| @ ord The order to interpret the elements
|
||||
export
|
||||
fromFunctionNB : (s : Vect rk Nat) -> (Vect rk Nat -> a) -> Array s a
|
||||
fromFunctionNB s = fromFunctionNB' s COrder
|
||||
|
||||
||| Create an array given a function to generate its elements.
|
||||
|||
|
||||
||| @ s The shape of the constructed array
|
||||
|
@ -219,32 +241,39 @@ array v = MkArray COrder (calcStrides COrder s) s (fromList $ collapse v)
|
|||
-- Indexing
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
infix 10 !!
|
||||
infix 10 !?
|
||||
infixl 10 !!
|
||||
infixl 10 !?
|
||||
infixl 11 !!..
|
||||
infix 11 !?..
|
||||
infixl 11 !?..
|
||||
|
||||
||| Index the array using the given `Coords` object.
|
||||
||| Index the array using the given coordinates.
|
||||
export
|
||||
index : Coords s -> Array s a -> a
|
||||
index is arr = index (getLocation (strides arr) is) (getPrim arr)
|
||||
|
||||
||| Index the array using the given coordinates.
|
||||
|||
|
||||
||| This is the operator form of `index`.
|
||||
export
|
||||
(!!) : Array s a -> Coords s -> a
|
||||
(!!) = flip index
|
||||
|
||||
-- TODO: Create set/update at index functions
|
||||
|
||||
||| Update the value at the given coordinates using the function.
|
||||
export
|
||||
indexUpdate : Coords s -> (a -> a) -> Array s a -> Array s a
|
||||
indexUpdate is f (MkArray ord sts s arr) =
|
||||
MkArray ord sts s (updateAt (getLocation sts is) f arr)
|
||||
|
||||
||| Set the value at the given coordinates to the given value.
|
||||
export
|
||||
indexSet : Coords s -> a -> Array s a -> Array s a
|
||||
indexSet is = indexUpdate is . const
|
||||
|
||||
|
||||
||| Index the array using the given coordinates, returning `Nothing` if the
|
||||
||| coordinates are out of bounds.
|
||||
export
|
||||
indexNB : Vect rk Nat -> Array {rk} s a -> Maybe a
|
||||
indexNB is arr with (viewShape arr)
|
||||
|
@ -252,21 +281,29 @@ indexNB is arr with (viewShape arr)
|
|||
then Just $ index (getLocation' (strides arr) is) (getPrim arr)
|
||||
else Nothing
|
||||
|
||||
||| Index the array using the given coordinates, returning `Nothing` if the
|
||||
||| coordinates are out of bounds.
|
||||
|||
|
||||
||| This is the operator form of `indexNB`.
|
||||
export
|
||||
(!?) : Array {rk} s a -> Vect rk Nat -> Maybe a
|
||||
(!?) = flip indexNB
|
||||
|
||||
||| Update the value at the given coordinates using the function. The array is
|
||||
||| returned unchanged if the coordinate is out of bounds.
|
||||
export
|
||||
indexUpdateNB : Vect rk Nat -> (a -> a) -> Array {rk} s a -> Array s a
|
||||
indexUpdateNB is f (MkArray ord sts s arr) =
|
||||
MkArray ord sts s (updateAt (getLocation' sts is) f arr)
|
||||
|
||||
||| Set the value at the given coordinates to the given value. The array is
|
||||
||| returned unchanged if the coordinate is out of bounds.
|
||||
export
|
||||
indexSetNB : Vect rk Nat -> a -> Array {rk} s a -> Array s a
|
||||
indexSetNB is = indexUpdateNB is . const
|
||||
|
||||
|
||||
||| Index the array using the given `CoordsRange` object.
|
||||
||| Index the array using the given range of coordinates, returning a new array.
|
||||
export
|
||||
indexRange : (rs : CoordsRange s) -> Array s a -> Array (newShape rs) a
|
||||
indexRange rs arr with (viewShape arr)
|
||||
|
@ -281,6 +318,9 @@ indexRange rs arr with (viewShape arr)
|
|||
where s' : Vect ? Nat
|
||||
s' = newShape rs
|
||||
|
||||
||| Index the array using the given range of coordinates, returning a new array.
|
||||
|||
|
||||
||| This is the operator form of `indexRange`.
|
||||
export
|
||||
(!!..) : Array s a -> (rs : CoordsRange s) -> Array (newShape rs) a
|
||||
arr !!.. rs = indexRange rs arr
|
||||
|
@ -320,10 +360,20 @@ reorder ord' arr with (viewShape arr)
|
|||
getAllCoords' s)
|
||||
|
||||
|
||||
||| Resize the array to a new shape, preserving the coordinates of the original
|
||||
||| elements. New coordinates are filled with a default value.
|
||||
|||
|
||||
||| @ s' The shape to resize the array to
|
||||
||| @ def The default value to fill the array with
|
||||
export
|
||||
resize : (s' : Vect rk Nat) -> a -> Array {rk} s a -> Array s' a
|
||||
resize s' x arr = fromFunction' s' (getOrder arr) (fromMaybe x . (arr !?) . toNB)
|
||||
resize : (s' : Vect rk Nat) -> (def : a) -> Array {rk} s a -> Array s' a
|
||||
resize s' def arr = fromFunction' s' (getOrder arr) (fromMaybe def . (arr !?) . toNB)
|
||||
|
||||
||| Resize the array to a new shape, preserving the coordinates of the original
|
||||
||| elements. This function requires a proof that the new shape is strictly
|
||||
||| smaller than the current shape of the array.
|
||||
|||
|
||||
||| @ s' The shape to resize the array to
|
||||
export
|
||||
-- TODO: Come up with a solution that doesn't use `believe_me` or trip over some
|
||||
-- weird bug in the type-checker
|
||||
|
@ -332,17 +382,23 @@ resizeLTE : (s' : Vect rk Nat) -> (0 ok : NP Prelude.id (zipWith LTE s' s)) =>
|
|||
resizeLTE s' arr = resize s' (believe_me ()) arr
|
||||
|
||||
|
||||
||| List all of the values in an array along with their coordinates.
|
||||
export
|
||||
enumerateNB : Array {rk} s a -> List (Vect rk Nat, a)
|
||||
enumerateNB (MkArray _ sts sh p) =
|
||||
map (\is => (is, index (getLocation' sts is) p)) (getAllCoords' sh)
|
||||
|
||||
|
||||
||| List all of the values in an array along with their coordinates.
|
||||
export
|
||||
enumerate : Array {rk} s a -> List (Coords s, a)
|
||||
enumerate : Array s a -> List (Coords s, a)
|
||||
enumerate arr with (viewShape arr)
|
||||
_ | Shape s = map (\is => (is, index is arr)) (getAllCoords s)
|
||||
|
||||
|
||||
||| Join two arrays along a particular axis, e.g. combining two matrices
|
||||
||| vertically or horizontally. The arrays must have the same shape on all other axes.
|
||||
|||
|
||||
||| @ axis The axis to join the arrays on
|
||||
export
|
||||
concat : (axis : Fin rk) -> Array {rk} s a -> Array (replaceAt axis d s) a ->
|
||||
Array (updateAt axis (+d) s) a
|
||||
|
@ -357,6 +413,9 @@ concat axis a b = let sA = shape a
|
|||
-- TODO: prove that the type-level shape and `s` are equivalent
|
||||
in believe_me $ MkArray COrder sts s (unsafeFromIns (product s) ins)
|
||||
|
||||
||| Stack multiple arrays along a new axis, e.g. stacking vectors to form a matrix.
|
||||
|||
|
||||
||| @ axis The axis to stack the arrays along
|
||||
export
|
||||
stack : {s : _} -> (axis : Fin (S rk)) -> Vect n (Array {rk} s a) -> Array (insertAt axis n s) a
|
||||
stack axis arrs = rewrite sym (lengthCorrect arrs) in
|
||||
|
@ -415,7 +474,7 @@ export
|
|||
|
||||
export
|
||||
{s : _} -> Monad (Array s) where
|
||||
join arr = fromFunction s (\is => index is $ index is arr)
|
||||
join arr = fromFunction s (\is => arr !! is !! is)
|
||||
|
||||
|
||||
-- Foldable and Traversable operate on the primitive array directly. This means
|
||||
|
@ -466,6 +525,7 @@ export
|
|||
negate = map negate
|
||||
(-) = zipWith (-)
|
||||
|
||||
export
|
||||
{s : _} -> Fractional a => Fractional (Array s a) where
|
||||
recip = map recip
|
||||
(/) = zipWith (/)
|
||||
|
@ -508,23 +568,30 @@ Show a => Show (Array s a) where
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
||| Linearly interpolate between two arrays.
|
||||
export
|
||||
lerp : Neg a => a -> Array s a -> Array s a -> Array s a
|
||||
lerp t a b = zipWith (+) (a *. (1 - t)) (b *. t)
|
||||
|
||||
|
||||
||| Calculate the square of an array's Eulidean norm.
|
||||
export
|
||||
normSq : Num a => Array s a -> a
|
||||
normSq arr = sum $ zipWith (*) arr arr
|
||||
|
||||
||| Calculate an array's Eucliean norm.
|
||||
export
|
||||
norm : Array s Double -> Double
|
||||
norm = sqrt . normSq
|
||||
|
||||
||| Normalize the array to a norm of 1.
|
||||
|||
|
||||
||| If the array contains all zeros, then it is returned unchanged.
|
||||
export
|
||||
normalize : Array s Double -> Array s Double
|
||||
normalize arr = if all (==0) arr then arr else map (/ norm arr) arr
|
||||
|
||||
||| Calculate the Lp-norm of an array.
|
||||
export
|
||||
pnorm : (p : Double) -> Array s Double -> Double
|
||||
pnorm p = (`pow` recip p) . sum . map (`pow` p)
|
||||
|
|
|
@ -2,7 +2,7 @@ module Data.NumIdr.Array.Coords
|
|||
|
||||
import Data.Either
|
||||
import Data.Vect
|
||||
import public Data.NP
|
||||
import Data.NP
|
||||
|
||||
%default total
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ Eq Order where
|
|||
FOrder == COrder = False
|
||||
|
||||
|
||||
|
||||
scanr : (el -> res -> res) -> res -> Vect len el -> Vect (S len) res
|
||||
scanr _ q0 [] = [q0]
|
||||
scanr f q0 (x::xs) = f x (head qs) :: qs
|
||||
|
|
|
@ -8,14 +8,33 @@ import Data.NumIdr.Matrix
|
|||
%default total
|
||||
|
||||
|
||||
public export
|
||||
HVector : Nat -> Type -> Type
|
||||
HVector n = Vector (S n)
|
||||
|
||||
||| A homogeneous matrix type.
|
||||
|||
|
||||
||| Homogeneous matrices are matrices that encode an affine transformation, as
|
||||
||| opposed to the more restriced linear transformations of normal matrices.
|
||||
||| Their multiplication is identical to regular matrix multiplication, but the
|
||||
||| extra dimension in each axis allows the homogeneous matrix to store a
|
||||
||| translation vector that is applied during multiplication.
|
||||
|||
|
||||
||| ```hmatrix mat tr *. v == mat *. v + tr```
|
||||
public export
|
||||
HMatrix : Nat -> Nat -> Type -> Type
|
||||
HMatrix m n = Matrix (S m) (S n)
|
||||
|
||||
||| A synonym for a square homogeneous matrix.
|
||||
public export
|
||||
HMatrix' : Nat -> Type -> Type
|
||||
HMatrix' n = HMatrix n n
|
||||
|
||||
||| An `n`-dimensional homogeneous vector type.
|
||||
|||
|
||||
||| Homogeneous vectors are vectors intended to be multiplied with homogeneous
|
||||
||| matrices (see `HMatrix`). They have an extra dimension compared to regular
|
||||
||| vectors.
|
||||
public export
|
||||
HVector : Nat -> Type -> Type
|
||||
HVector n = Vector (S n)
|
||||
|
||||
|
||||
export
|
||||
|
|
|
@ -8,10 +8,12 @@ import Data.NumIdr.Vector
|
|||
%default total
|
||||
|
||||
|
||||
||| A matrix is a rank-2 array.
|
||||
public export
|
||||
Matrix : Nat -> Nat -> Type -> Type
|
||||
Matrix m n = Array [m,n]
|
||||
|
||||
||| A synonym for a square matrix with dimensions of length `n`.
|
||||
public export
|
||||
Matrix' : Nat -> Type -> Type
|
||||
Matrix' n = Matrix n n
|
||||
|
@ -22,26 +24,30 @@ Matrix' n = Matrix n n
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
||| Construct a matrix with the given order and elements.
|
||||
export
|
||||
matrix' : {m, n : _} -> Order -> Vect m (Vect n a) -> Matrix m n a
|
||||
matrix' ord x = array' [m,n] ord x
|
||||
|
||||
||| Construct a matrix with the given elements.
|
||||
export
|
||||
matrix : {m, n : _} -> Vect m (Vect n a) -> Matrix m n a
|
||||
matrix = matrix' COrder
|
||||
|
||||
|
||||
||| Construct a matrix with a specific value along the diagonal.
|
||||
|||
|
||||
||| @ diag The value to repeat along the diagonal
|
||||
||| @ other The value to repeat elsewhere
|
||||
export
|
||||
repeatDiag : {m, n : _} -> (diag, other : a) -> Matrix m n a
|
||||
repeatDiag d o = fromFunction [m,n]
|
||||
(\[i,j] => if i `eq` j then d else o)
|
||||
where
|
||||
eq : {0 m,n : Nat} -> Fin m -> Fin n -> Bool
|
||||
eq FZ FZ = True
|
||||
eq (FS x) (FS y) = eq x y
|
||||
eq FZ (FS _) = False
|
||||
eq (FS _) FZ = False
|
||||
repeatDiag d o = fromFunctionNB [m,n]
|
||||
(\[i,j] => if i == j then d else o)
|
||||
|
||||
||| Construct a matrix given its diagonal elements.
|
||||
|||
|
||||
||| @ diag The elements of the matrix's diagonal
|
||||
||| @ other The value to repeat elsewhere
|
||||
export
|
||||
fromDiag : {m, n : _} -> (diag : Vect (minimum m n) a) -> (other : a) -> Matrix m n a
|
||||
fromDiag ds o = fromFunction [m,n] (\[i,j] => maybe o (`index` ds) $ i `eq` j)
|
||||
|
@ -53,15 +59,18 @@ fromDiag ds o = fromFunction [m,n] (\[i,j] => maybe o (`index` ds) $ i `eq` j)
|
|||
eq (FS _) FZ = Nothing
|
||||
|
||||
|
||||
||| The `n`-dimensional identity matrix.
|
||||
export
|
||||
identity : Num a => {n : _} -> Matrix' n a
|
||||
identity = repeatDiag 1 0
|
||||
|
||||
|
||||
||| Calculate the matrix that scales a vector by the given value.
|
||||
export
|
||||
scaling : Num a => {n : _} -> a -> Matrix' n a
|
||||
scaling x = repeatDiag x 0
|
||||
|
||||
||| Calculate the rotation matrix of an angle.
|
||||
export
|
||||
rotation2D : Double -> Matrix' 2 Double
|
||||
rotation2D a = matrix [[cos a, - sin a], [sin a, cos a]]
|
||||
|
@ -72,19 +81,24 @@ rotation2D a = matrix [[cos a, - sin a], [sin a, cos a]]
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
||| Index the matrix at the given coordinates.
|
||||
export
|
||||
index : Fin m -> Fin n -> Matrix m n a -> a
|
||||
index m n = index [m,n]
|
||||
|
||||
||| Index the matrix at the given coordinates, returning `Nothing` if the
|
||||
||| coordinates are out of bounds.
|
||||
export
|
||||
indexNB : Nat -> Nat -> Matrix m n a -> Maybe a
|
||||
indexNB m n = indexNB [m,n]
|
||||
|
||||
|
||||
||| Return a row of the matrix as a vector.
|
||||
export
|
||||
getRow : Fin m -> Matrix m n a -> Vector n a
|
||||
getRow r mat = rewrite sym (minusZeroRight n) in indexRange [One r, All] mat
|
||||
|
||||
||| Return a column of the matrix as a vector.
|
||||
export
|
||||
getColumn : Fin n -> Matrix m n a -> Vector m a
|
||||
getColumn c mat = rewrite sym (minusZeroRight m) in indexRange [All, One c] mat
|
||||
|
@ -94,19 +108,22 @@ getColumn c mat = rewrite sym (minusZeroRight m) in indexRange [All, One c] mat
|
|||
-- Operations
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
||| Concatenate two matrices vertically.
|
||||
export
|
||||
vconcat : Matrix m n a -> Matrix m' n a -> Matrix (m + m') n a
|
||||
vconcat = concat 0
|
||||
|
||||
||| Concatenate two matrices horizontally.
|
||||
export
|
||||
hconcat : Matrix m n a -> Matrix m n' a -> Matrix m (n + n') a
|
||||
hconcat = concat 1
|
||||
|
||||
|
||||
||| Calculate the kronecker product of two vectors as a matrix.
|
||||
export
|
||||
kronecker : Num a => Vector m a -> Vector n a -> Matrix m n a
|
||||
kronecker a b with (viewShape a, viewShape b)
|
||||
_ | (Shape [m], Shape [n]) = fromFunction [m,n] (\[i,j] => index i a * index j b)
|
||||
_ | (Shape [m], Shape [n]) = fromFunction [m,n] (\[i,j] => a !! i * b !! j)
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -6,32 +6,49 @@ module Data.NumIdr.Multiply
|
|||
infixr 9 *.
|
||||
infixr 10 ^
|
||||
|
||||
||| A generalized multiplication/transformation operator. This interface is
|
||||
||| A generalized multiplication/application operator. This interface is
|
||||
||| necessary since the standard multiplication operator is homogenous.
|
||||
|||
|
||||
||| All instances of this interface must collectively satisfy these axioms:
|
||||
||| * If `(x *. y) *. z` is defined, then `x *. (y *. z)` is defined and equal.
|
||||
||| * If `x *. (y *. z)` is defined, then `(x *. y) *. z` is defined and equal.
|
||||
public export
|
||||
interface Mult a b c | a,b where
|
||||
(*.) : a -> b -> c
|
||||
|
||||
||| An interface for monoids using the `*.` operator.
|
||||
|||
|
||||
||| An instance of this interface must satisfy:
|
||||
||| * `x *. neutral == x`
|
||||
||| * `neutral *. x == x`
|
||||
public export
|
||||
interface (Mult a a a) => MultNeutral a where
|
||||
interface Mult a a a => MultNeutral a where
|
||||
neutral : a
|
||||
|
||||
|
||||
||| Multiplication forms a semigroup
|
||||
public export
|
||||
[MultSemigroup] Mult a a a => Semigroup a where
|
||||
(<+>) = (*.)
|
||||
|
||||
||| Multiplication with a neutral element forms a monoid
|
||||
public export
|
||||
[MultMonoid] MultNeutral a => Monoid a using MultSemigroup where
|
||||
neutral = Multiply.neutral
|
||||
|
||||
|
||||
||| Raise a multiplicative value (e.g. a matrix or a transformation) to a natural
|
||||
||| number power.
|
||||
public export
|
||||
power : MultNeutral a => Nat -> a -> a
|
||||
power 0 _ = neutral
|
||||
power 1 x = x
|
||||
power (S n@(S _)) x = x *. power n x
|
||||
|
||||
||| Raise a multiplicative value (e.g. a matrix or a transformation) to a natural
|
||||
||| number power.
|
||||
|||
|
||||
||| This is the operator form of `power`.
|
||||
public export
|
||||
(^) : MultNeutral a => a -> Nat -> a
|
||||
(^) = flip power
|
||||
|
|
|
@ -35,8 +35,8 @@ export
|
|||
constant : Nat -> a -> PrimArray a
|
||||
constant size x = MkPrimArray size $ unsafePerformIO $ newArrayData size x
|
||||
|
||||
||| Construct an array from a list of "instructions" to write a
|
||||
||| value to a particular index.
|
||||
||| Construct an array from a list of "instructions" to write a value to a
|
||||
||| particular index.
|
||||
export
|
||||
unsafeFromIns : Nat -> List (Nat, a) -> PrimArray a
|
||||
unsafeFromIns size ins = unsafePerformIO $ do
|
||||
|
@ -44,8 +44,8 @@ unsafeFromIns size ins = unsafePerformIO $ do
|
|||
for_ ins $ \(i,x) => arrayDataSet i x arr
|
||||
pure $ MkPrimArray size arr
|
||||
|
||||
||| Create an array given its size and a function to generate
|
||||
||| its elements by its index.
|
||||
||| Create an array given its size and a function to generate its elements by
|
||||
||| its index.
|
||||
export
|
||||
create : Nat -> (Nat -> a) -> PrimArray a
|
||||
create size f = unsafePerformIO $ do
|
||||
|
@ -59,8 +59,8 @@ create size f = unsafePerformIO $ do
|
|||
= do arrayDataSet loc (f loc) arr
|
||||
addToArray (S loc) n arr
|
||||
|
||||
||| Index into a primitive array. This function is unsafe, as it
|
||||
||| performs no boundary check on the index given.
|
||||
||| Index into a primitive array. This function is unsafe, as it performs no
|
||||
||| boundary check on the index given.
|
||||
export
|
||||
index : Nat -> PrimArray a -> a
|
||||
index n arr = unsafePerformIO $ arrayDataGet n $ content arr
|
||||
|
@ -156,8 +156,8 @@ traverse : Applicative f => (a -> f b) -> PrimArray a -> f (PrimArray b)
|
|||
traverse f = map fromList . traverse f . toList
|
||||
|
||||
|
||||
||| Compares two primitive arrays for equal elements. This function assumes
|
||||
||| the arrays same the same length; it must not be used in any other case.
|
||||
||| Compares two primitive arrays for equal elements. This function assumes the
|
||||
||| arrays have the same length; it must not be used in any other case.
|
||||
export
|
||||
unsafeEq : Eq a => PrimArray a -> PrimArray a -> Bool
|
||||
unsafeEq a b = unsafePerformIO $
|
||||
|
|
|
@ -15,10 +15,12 @@ Scalar : Type -> Type
|
|||
Scalar = Array []
|
||||
|
||||
|
||||
||| Convert a value to a scalar.
|
||||
export
|
||||
scalar : a -> Scalar a
|
||||
scalar x = fromVect _ [x]
|
||||
|
||||
||| Unwrap the single value from a scalar.
|
||||
export
|
||||
unwrap : Scalar a -> a
|
||||
unwrap = index 0 . getPrim
|
||||
|
|
|
@ -6,11 +6,14 @@ import public Data.NumIdr.Array
|
|||
|
||||
%default total
|
||||
|
||||
|
||||
||| A vector is a rank-1 array.
|
||||
public export
|
||||
Vector : Nat -> Type -> Type
|
||||
Vector n = Array [n]
|
||||
|
||||
|
||||
||| The length (number of dimensions) of the vector
|
||||
public export
|
||||
dim : Vector n a -> Nat
|
||||
dim = head . shape
|
||||
|
@ -25,6 +28,7 @@ dimEq v = cong head $ shapeEq v
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
||| Construct a vector from a `Vect`.
|
||||
export
|
||||
vector : Vect n a -> Vector n a
|
||||
vector v = rewrite sym (lengthCorrect v)
|
||||
|
@ -32,20 +36,28 @@ vector v = rewrite sym (lengthCorrect v)
|
|||
rewrite lengthCorrect v in -- there is only 1 axis
|
||||
rewrite multOneLeftNeutral n in v
|
||||
|
||||
||| Convert a vector into a `Vect`.
|
||||
export
|
||||
toVect : Vector n a -> Vect n a
|
||||
toVect v = believe_me $ Vect.fromList $ toList v
|
||||
|
||||
|
||||
||| Return the `i`-th basis vector.
|
||||
export
|
||||
basis : Num a => {n : _} -> (i : Fin n) -> Vector n a
|
||||
basis i = fromFunction _ (\[j] => if i == j then 1 else 0)
|
||||
|
||||
|
||||
||| Calculate the 2D unit vector with the given angle off the x-axis.
|
||||
export
|
||||
unit2D : (ang : Double) -> Vector 2 Double
|
||||
unit2D ang = vector [cos ang, sin ang]
|
||||
|
||||
||| Calculate the 3D unit vector corresponding to the given spherical coordinates,
|
||||
||| where the polar axis is the z-axis.
|
||||
|||
|
||||
||| @ pol The polar angle of the vector
|
||||
||| @ az The azimuthal angle of the vector
|
||||
export
|
||||
unit3D : (pol, az : Double) -> Vector 3 Double
|
||||
unit3D pol az = vector [cos az * sin pol, sin az * sin pol, cos pol]
|
||||
|
@ -56,35 +68,49 @@ unit3D pol az = vector [cos az * sin pol, sin az * sin pol, cos pol]
|
|||
-- Indexing
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
infix 10 !!
|
||||
infix 10 !?
|
||||
infixl 10 !!
|
||||
infixl 10 !?
|
||||
|
||||
||| Index the vector at the given coordinate.
|
||||
export
|
||||
index : Fin n -> Vector n a -> a
|
||||
index n = Array.index [n]
|
||||
|
||||
||| Index the vector at the given coordinate.
|
||||
|||
|
||||
||| This is the operator form of `index`.
|
||||
export
|
||||
(!!) : Vector n a -> Fin n -> a
|
||||
(!!) = flip index
|
||||
|
||||
||| Index the vector at the given coordinate, returning `Nothing` if the
|
||||
||| coordinate is out of bounds.
|
||||
export
|
||||
indexNB : Nat -> Vector n a -> Maybe a
|
||||
indexNB n = Array.indexNB [n]
|
||||
|
||||
||| Index the vector at the given coordinate, returning `Nothing` if the
|
||||
||| coordinate is out of bounds.
|
||||
|||
|
||||
||| This is the operator form of `indexNB`.
|
||||
export
|
||||
(!?) : Vector n a -> Nat -> Maybe a
|
||||
(!?) = flip indexNB
|
||||
|
||||
|
||||
-- Named projections
|
||||
|
||||
||| Return the x-coordinate (the first value) of the vector.
|
||||
export
|
||||
(.x) : Vector (1 + n) a -> a
|
||||
(.x) = index FZ
|
||||
|
||||
||| Return the y-coordinate (the second value) of the vector.
|
||||
export
|
||||
(.y) : Vector (2 + n) a -> a
|
||||
(.y) = index (FS FZ)
|
||||
|
||||
||| Return the z-coordinate (the third value) of the vector.
|
||||
export
|
||||
(.z) : Vector (3 + n) a -> a
|
||||
(.z) = index (FS (FS FZ))
|
||||
|
@ -109,16 +135,19 @@ swizzle p v = rewrite sym (lengthCorrect p)
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
||| Concatenate one vector with another.
|
||||
export
|
||||
(++) : Vector m a -> Vector n a -> Vector (m + n) a
|
||||
(++) = concat 0
|
||||
|
||||
|
||||
||| Calculate the dot product of the two vectors.
|
||||
export
|
||||
dot : Num a => Vector n a -> Vector n a -> a
|
||||
dot = sum .: zipWith (*)
|
||||
|
||||
|
||||
||| Calculate the perpendicular product of the two vectors.
|
||||
export
|
||||
perp : Neg a => Vector 2 a -> Vector 2 a -> a
|
||||
perp a b = a.x * b.y - a.y * b.x
|
||||
|
|
Loading…
Reference in a new issue